初始化“指向整数数组的指针”

20
 int (*a)[5];

如何初始化一个指向上面展示的包含5个整数的数组的指针。

下面的表达式是否正确?

int (*a)[3]={11,2,3,5,6}; 

在 C 语言中,“指向数组的指针”几乎没有任何好用的地方。它只会使代码变得更加晦涩,没有任何好处。直接声明和初始化数组,然后使用元素类型的指针即可。 - Lee Daniel Crocker
7
@LeeDanielCrocker说:“那不是真的——指向数组的指针是动态分配多维数组(如int (*a)[5] = malloc(nrows * sizeof *a);)最有效的方式。” - caf
是的,那很简单,但只适用于在编译时知道内部维度的情况,而不是更一般的情况。 - Lee Daniel Crocker
3
@LeeDanielCrocker说:对于VLA也同样适用:size_t cols; ...; int (*a)[cols] = malloc( nrows * sizeof *a );。当将二维数组表达式传递给函数时,它也会衰减为这种类型。虽然原帖中的用法不正确,但这并不使它们无用。请注意不要改变原文意思,并尽可能地让翻译更加通俗易懂。 - John Bode
4个回答

22

假设你有一个长度为5的int数组,例如:

int x[5];

那么你可以执行a = &x;

 int x[5] = {1};
 int (*a)[5] = &x;

要访问数组元素,您需要使用括号:(*a)[i](等同于(*(&x))[i] == (*&x)[i] == x[i]),因为[]运算符的优先级高于*运算符。 (一个常见的错误是使用*a[i]来访问数组元素)。

理解您在问题中所询问的是编译时错误:

int (*a)[3] = {11, 2, 3, 5, 6}; 

这并不正确,而且类型不匹配,因为{11,2,3,5,6}可以分配给int a[5];,而你正在分配给int (*a)[3].

此外,对于一维数组,您可以尝试以下操作:

int *why = (int p[2]) {1,2};

同样地,对于二维情况可以尝试使用以下代码(感谢@caf):

int (*a)[5] = (int p[][5]){ { 1, 2, 3, 4, 5 } , { 6, 7, 8, 9, 10 } };

1
@Flow 第二个不正确,请尝试使用新编译器并使用int (*a)[5]= (int(*)[5])&({11,2,3,5,6}); - Grijesh Chauhan
1
int (*a)[5] = (int [][5]){ { 1, 2, 3, 4, 5 } , { 6, 7, 8, 9, 10 } }; - caf
@caf明白了,谢谢。它类似于:int *why = (int[2]) {1,2} - Grijesh Chauhan
@caf 你的表达式是 "c99" 吗? - Grijesh Chauhan
@caf 谢谢!我在我的实验中一直在寻找它,你给了我答案,谢谢 Caf :) - Grijesh Chauhan
显示剩余7条评论

5
{11,2,3,5,6}是一个初始化列表,它不是一个数组,所以你不能指向它。数组指针需要指向一个具有有效内存位置的数组。无论数组是一个命名变量还是一块已分配的内存块都没有关系。
这一切归结于你需要的数组类型。在C语言中,根据用途有多种声明数组的方式:
// plain array, fixed size, can be allocated in any scope
int array[5] = {11,2,3,5,6};
int (*a)[5] = &array;

// compound literal, fixed size, can be allocated in any scope
int (*b)[5] = &(int[5]){11,2,3,5,6};

// dynamically allocated array, variable size possible
int (*c)[n] = malloc( sizeof(int[n]) );

// variable-length array, variable size
int n = 5;
int vla[n];
memcpy( vla, something, sizeof(int[n]) ); // always initialized in run-time
int (*d)[n] = &vla;

@M.M 确实。我不确定为什么写了那个。已修复。我想我当时是在试图警告在声明它的范围之外传递指向复合字面量的指针。 - Lundin

1
int a1[5] = {1, 2, 3, 4, 5};
int (*a)[5] = &a1;

0
int vals[] = {1, 2};
int (*arr)[sizeof(vals)/sizeof(vals[0])] = &vals;

然后您可以像这样访问数组的内容:

(*arr)[0] = ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接