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]
指定E2
第E2
个元素。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.