看到我看到了一些像
这样的代码int (*b)[10];
表示
declare b as pointer to array 10 of int
所以我想问你这样做的目的是什么?
为什么我们不写而不是
int array[10];
并用作数组的传递地址。
两者是相同还是差异?
编辑: 不要混淆
int *b[10]; // this one declare b as array 10 of pointer to int
和
int (*b)[10]; // this one declare b as pointer to array 10 of int
再编辑一次
请参阅int (*b)[10];
1>将为int的10个元素分配内存,并将该内存的地址分配给b?
或
2>没有为数组分配内存。这里它说b能够保存10个元素的地址和int数组吗?
哪个选项是对的? 如果任何一个是正确的,为什么一个人应该使用这个复杂的语法,而不是使用不同的方法?
答案 0 :(得分:1)
实际上有一点不同。在int b[10]
中,b
是一个指针常量(这意味着它可用于修改其基础数据,但不能更改为指向其他内容)。另一方面,中的int (*b)[10]
中的指针可以更改为指向其他内容(当然也可以更改其基础数据)。所以区别在于b
是int (*b)[10]
;您特此警告下一位看到您的代码的开发人员,此b
可以指向代码中的其他位置。这就是为什么 - 显然 - 不要这样做,除非你真的打算改变b
所指向的东西(否则你只会混淆谁将会追随你)。
关于您的问题,我使用sizeof(b)
进行了检查。
int (*b)[10]
==> sizeof(b)
为4(表示没有分配内存 - 选项2)。
int b[10]
==> sizeof(b)
为40(表示内存按预期分配 - 选项1)。
看看这个:
int (*b)[10];
int x[10];
b = &x;
这个编译。将数组的大小更改为其他任何内容。它不会编译!这意味着您非常正确 :-D。选项2写得很完美:这个指针只能 指向大小为10的数组而没有别的。
[根据问题所有者的要求添加]
这种语法的优点是什么?它只是一个已经存在的功能,也许它对某些人有用。这就是我理解它的方式(如果错误,请纠正我):例如,您可以说:string (*names_of_players_in_soccer_team)[11];
,优点是 - 显然 - 将数组限制为完全 11个名称处理应用程序逻辑 - 团队实际上必须有11个名字。这为那些阅读你的代码的人提供了更多的可读性,并强调了它的正确性......
答案 1 :(得分:0)
int (*b)[10]
是一个指向int数组的指针,int b[10]
是一个int数组。 (下次可能选择不同的名字?)也许你想malloc
数组存储,b = malloc(sizeof(*b))
。为此,您需要一个指向数组类型的指针。
答案 2 :(得分:0)
C允许使用不带下标的数组名称作为rvalue,表示数组基址的地址。它还允许使用偏移量隐式地取消引用指针,因为通常访问数组。因此,当且仅当b永远不需要指向同一数组的不同数组或不同元素时,声明在逻辑上和语法上是等效的。从技术上讲,它们的不同之处在于int b[10]
需要sizeof(int)*10
个字节来保存数组,而int (*b)[10]
需要额外的sizeof(int*)
个字节来保存指向所述数组的指针。如果在函数之外声明数组,则访问int b[10]
的元素可能会使用更小的操作码和更少的寄存器。
我建议您在计划使用它时声明它。如果您不知道为什么它可能是指针,请将其声明为数组。如果它需要在堆上动态分配,重新设置,或者声明为函数参数,它应该是一个指针。