C中的数组是指针的语法糖吗?

我们来看看下面的代码:

int arr[n]; // st i<n arr[i] = 12; // st i<n *(arr + i) = 12; 

arr[i]*(arr+ i)的合成糖吗?

是的,您可以说 – 数组下标访问与使用* dereference的指针访问相同。

从6.5.2.1p2 C11标准N1570

后缀表达式后跟方括号[]的表达式是数组对象元素的下标名称。 下标运算符[]的定义是E1[E2](*((E1)+(E2))) 由于适用于binary +运算符的转换规则,如果E1是数组对象(等效地,指向数组对象的初始元素的指针)并且E2是整数,则E1[E2]指定E2E2个元素。 E1 (从零开始计数)。

绝不应该给你一个数组是指针的印象。 有趣的是,当你应用[] ,数组衰减成指向第一个元素的指针,并且用于访问后续元素。

数组对象是另一回事 – 有些情况下数组不会衰减为指针。 它们不是语法糖 – 你可以考虑一个例子 –

 int p[] = {1, 2 ,3}; int *t = p; size_t sz1 = sizeof p; size_t sz2 = sizeof t; printf("%zu %zu\n", sz1, sz2); 

运行此操作,我将了解与您的问题更相关的内容。 使用除数组本身之外的其他东西无法实现数组。 数组访问与指针取消引用相同,但这并不意味着指针占据数组的位置,反之亦然。

C编程的关键外卖或红色药丸:

数组是数组,指针是指针。 他们是不同的东西。


顺便说一句,如果sizeof欺骗了你一点 – 不要担心有一个标准部分说。 从6.3.2.1p3开始

除非它是sizeof运算符_Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为'array of type'的表达式转换为类型为'pointer to type'的表达式'pointer to type'数组对象的初始元素而不是左值…

当用作sizeof的操作数时,Array不会转换为指针。 那是事情。 这就是为什么你得到你在早期代码片段中得到的东西。

是的, arr[i]*(arr+i)相同,它与*(i+arr)相同,它与i[arr]相同

来自Fabio Turati的评论:有关详细信息,请参阅“为什么[5] == 5 [a]” 。

绝对不! 要看到这一点,只需在示例中用指针替换数组:

 int *arr; // st i 

这编译很好,但它是未定义的行为。 它不能保证工作。 实际上,这个程序可能没有什么可以被认为是编译器中的错误。

数组是数组; 包含数据的类型。 指针指向数据的位置。 指针不包含实际数据,而数组则包含实际数据。

某些情况下,数组名称的行为与指针的行为方式相同。 这并不能使两者完全相同。

例如,检查一下:

 int arr[12]; int ptr; ptr = arr; // Legal printf("array size %ld\n", sizeof(arr)); // Usually prints 12*4=48 printf("pointer size %ld\n", sizeof(ptr)); // Depending on your arch, will likely print either 4 or 8.