如何将二维数组分配给指向数组的指针
how to assign 2 d array to pointer to an array in
我有一个指向数组(二维数组)的指针。我喜欢将二维数组分配给指针
int (*p)[2]={{1,2}};//SegFault
int (*p)[2]=(int **){{1,2},{3,4}}; //should it be same as above? but also causing segFault/
int (*p)[2]=(int[][]){{5,4},{5,6}};//should it be same as above two? but also causing segFault
以及如何访问这些值。访问第一个数组和第一个值应该是正确的*(*(p)
。 // Willl it also work p[0][0]
我认为是这样,但请澄清这些访问方法纯粹是 C 的设计方式还是如果我使用 *(*(p))
或 p[0][0]
[ 是否有任何内存问题=15=]
这个声明
int (*p)[2]={{1,2}};
语法不正确。指针是标量对象,它们可以由可选地括在大括号中的单个表达式进行初始化。
在此声明中
int (*p)[2]=(int **){{1,2},{3,4}}
您正在尝试使用复合文字,但再次初始化不正确,因为类型 int **
的对象是标量对象,我可以通过单个表达式进行初始化。
在这个带有复合文字的声明中
int (*p)[2]=(int[][]){{5,4},{5,6}};
对二维数组使用了错误的类型说明符 int[][]
,因为数组元素的大小未知。你可以这样写
int (*p)[2]=(int[][2]){{5,4},{5,6}};
那就是你需要有一个数组,你将分配给一个指针。如果你没有这样的数组,你可以使用复合文字。例如
int (*p)[2] = (int[2][2]){{1,2},{3,4}};
或
int (*p)[2] = (int[][2]){{1,2},{3,4}};
这是一个演示程序。
#include <stdio.h>
int main(void)
{
enum { N = 2 };
int ( *p )[N] = ( int[N][N] ){ { 1, 2 }, { 3, 4 } };
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
int a[N][N] = { { 1, 2 }, { 3, 4 } };
p = a;
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
int b[N] = { 1, 2 };
p = &b;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", ( *p )[i] );
}
putchar( '\n' );
return 0;
}
程序输出为
1 2
3 4
1 2
3 4
1 2
{{1,2}};
是数组初始值设定项,而不是数组。所以代码是无效的 C - 你不能像那样初始化一个指针。这是错误的类型 int
和错误的初始值设定项数量。
(int **){{1,2},{3,4}};
是 int**
类型的复合文字。但是同样,像这样初始化一个指针是无效的 C.
(int[][]){{5,4},{5,6}};
是一个不完整类型的数组。它不能被初始化。所以这也是无效的C.
您所有的问题都源于忽略编译器警告。对于类似 gcc 的编译器,我强烈建议将您的设置更改为 -std=c11 -pedantic-errors
。然后,当您编写无效的 C 时,您将收到编译器错误,而不仅仅是警告。
回答问题,正确的做法是:
int (*p)[2] = (int[2][2]){ {1,2}, {3,4} };
这将创建一个局部作用域二维数组,其作用域与指针 p
相同。这相当于:
int arr[2][2] = { {1,2}, {3,4} };
int (*p)[2] = arr;
我有一个指向数组(二维数组)的指针。我喜欢将二维数组分配给指针
int (*p)[2]={{1,2}};//SegFault
int (*p)[2]=(int **){{1,2},{3,4}}; //should it be same as above? but also causing segFault/
int (*p)[2]=(int[][]){{5,4},{5,6}};//should it be same as above two? but also causing segFault
以及如何访问这些值。访问第一个数组和第一个值应该是正确的*(*(p)
。 // Willl it also work p[0][0]
我认为是这样,但请澄清这些访问方法纯粹是 C 的设计方式还是如果我使用 *(*(p))
或 p[0][0]
[ 是否有任何内存问题=15=]
这个声明
int (*p)[2]={{1,2}};
语法不正确。指针是标量对象,它们可以由可选地括在大括号中的单个表达式进行初始化。
在此声明中
int (*p)[2]=(int **){{1,2},{3,4}}
您正在尝试使用复合文字,但再次初始化不正确,因为类型 int **
的对象是标量对象,我可以通过单个表达式进行初始化。
在这个带有复合文字的声明中
int (*p)[2]=(int[][]){{5,4},{5,6}};
对二维数组使用了错误的类型说明符 int[][]
,因为数组元素的大小未知。你可以这样写
int (*p)[2]=(int[][2]){{5,4},{5,6}};
那就是你需要有一个数组,你将分配给一个指针。如果你没有这样的数组,你可以使用复合文字。例如
int (*p)[2] = (int[2][2]){{1,2},{3,4}};
或
int (*p)[2] = (int[][2]){{1,2},{3,4}};
这是一个演示程序。
#include <stdio.h>
int main(void)
{
enum { N = 2 };
int ( *p )[N] = ( int[N][N] ){ { 1, 2 }, { 3, 4 } };
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
int a[N][N] = { { 1, 2 }, { 3, 4 } };
p = a;
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
int b[N] = { 1, 2 };
p = &b;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", ( *p )[i] );
}
putchar( '\n' );
return 0;
}
程序输出为
1 2
3 4
1 2
3 4
1 2
{{1,2}};
是数组初始值设定项,而不是数组。所以代码是无效的 C - 你不能像那样初始化一个指针。这是错误的类型int
和错误的初始值设定项数量。(int **){{1,2},{3,4}};
是int**
类型的复合文字。但是同样,像这样初始化一个指针是无效的 C.(int[][]){{5,4},{5,6}};
是一个不完整类型的数组。它不能被初始化。所以这也是无效的C.
您所有的问题都源于忽略编译器警告。对于类似 gcc 的编译器,我强烈建议将您的设置更改为 -std=c11 -pedantic-errors
。然后,当您编写无效的 C 时,您将收到编译器错误,而不仅仅是警告。
回答问题,正确的做法是:
int (*p)[2] = (int[2][2]){ {1,2}, {3,4} };
这将创建一个局部作用域二维数组,其作用域与指针 p
相同。这相当于:
int arr[2][2] = { {1,2}, {3,4} };
int (*p)[2] = arr;