方括号数组和指针数组有什么区别?

作为非C / C ++专家,我总是将方括号和指针数组视为相等。

即:

char *my_array_star; char my_array_square[]; 

但我注意到,当在结构/类中使用时,它们的行为并不相同:

 typedef struct { char whatever; char *my_array_star; } my_struct_star; typedef struct { char whatever; char my_array_square[]; } my_struct_square; 

下面的行显示16, whatever需要1个字节, my_array_pointer需要8个字节。 由于填充,总结构尺寸为16。

 printf("my_struct_star: %li\n",sizeof(my_struct_star)); 

下面的行显示1, whatever需要1个字节, my_array_pointer都不会被考虑在内。

 printf("my_struct_square: %li\n",sizeof(my_struct_square)); 

通过玩耍,我注意到方括号被用作结构中的额外空间

 my_struct_square *i=malloc(2); i->whatever='A'; i->my_array_square[0]='B'; 

线吹显示A:

 printf("i[0]=%c\n",((char*)i)[0]); 

线吹显示B:

 printf("i[1]=%c\n",((char*)i)[1]); 

所以我不能再说方括号等于指针了。 但我想了解这种行为的原因。 我害怕错过那些语言的关键概念。

数组和指针的行为并不相同,因为它们根本不相同,只是看起来就是这样。

数组是一组连续的项,而指针是……嗯……指向单个项的指针。

指向的单个项可能是数组中的第一个,因此您也可以访问其他项,但指针本身既不知道也不关心它。

数组和指针通常看起来相同的原因是,在许多情况下,数组会衰减为指向该数组的第一个元素的指针。

其中一个地方就是函数调用。 将数组传递给函数时,它会衰减为指针。 这就是为什么像数组大小这样的东西没有明确地传递给函数。 我的意思是:

 #include  static void fn (char plugh[]) { printf ("size = %d\n", sizeof(plugh)); // will give char* size (4 for me). } int main (void) { char xyzzy[10]; printf ("size = %d\n", sizeof(xyzzy)); // will give 10. fn (xyzzy); return 0; } 

你要发现的另一件事是,虽然你可以plugh++plugh--内容(只要你不在数组之外取消引用),你就不能用数组xyzzy做到这一点。

在你的两个结构中,有一个主要的区别。 在指针版本中,结构内部有一个固定大小的指针,指向结构外部的项目。

这就是占用空间的原因 – 您的8字节指针与8字节边界对齐如下:

 +----------------+ | 1 char variable| +----------------+ | 7 char padding | +----------------+ | 8 char pointer | +----------------+ 

使用“无界”数组,您可以结构中使用它,并且可以根据需要调整它 – 您只需在创建变量时分配足够的内存。 默认情况下(即根据sizeof ),大小为零:

 +----------------+ | 1 char variable| +----------------+ | 0 char array | +----------------+ 

但是你可以分配更多的空间,例如:

 typedef struct { char whatever; char my_array_square[]; } my_struct_square; my_struct_square twisty = malloc (sizeof (my_struct_square) + 10); 

给你一个变量twisty ,它有一个whatever字符和一个名为my_array_square的十个字符数组。

这些无界数组只能出现在结构的末尾,并且只能有一个(否则编译器不知道这些可变长度部分的开始和结束位置),并且它们特别允许在结构末端允许任意大小的数组。

my_array_square成员是所谓的“灵活”数组成员。 没有指定大小的此类数组只能出现在结构的末尾,并且它们不会影响其大小。 目的是根据需要手动分配剩余的空间。 否则,在编译时确定数组的大小。

这种结构的使用模式如下:

 my_struct_square *s = malloc(sizeof(my_struct_square) + 5 * sizeof(char)); ... s->my_array_square[4]; // the last element of the array 

在所有其他情况下,必须在编译时知道数组的大小。 甚至数组的类型也与它的大小一起,即int a[20]的类型为int[20] ,而不仅仅是int[]

另外,理解数组和指针之间的区别至关重要。 @paxdiablo已经很好地解决了这个问题。