Are arrays in C a syntactic sugar for pointers?

删除回忆录丶 提交于 2019-12-18 18:28:52

问题


Let's take a look at the following code:

int arr[n];
// s.t. i<n
arr[i] = 12;
// s.t. i<n 
*(arr + i) = 12;

Is arr[i] is a syntatic sugar for *(arr+ i) ?


回答1:


Yes you can say that- array subscript access is identical to pointer access with * dereference.

From 6.5.2.1p2 C11 standard N1570

A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

This by no means should give you the impression that arrays are pointers. Interestingly when you apply [] the array decays into pointer to first element and that is being used to access the subsequent elements.

Array object is a different thing - there are cases when arrays don't decay into pointers. They are not syntactic sugar - you can consider one example -

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

Run this and I will understand something much more relevant to your question. An array can't be realized using something other than the array itself. Array access is identical to pointer dereference but that doesn't mean pointers take the position of array or vice versa.

Key takeaway or red pill of C programming:

Arrays are arrays and pointers are pointers. They are different thing.


By the way if sizeof tricked you a bit - don't worry there is a standard section saying that. From 6.3.2.1p3

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type 'array of type' is converted to an expression with type 'pointer to type' that points to the initial element of the array object and is not an lvalue...

Array doesn't get converted to pointer when used as an operand to sizeof. That's the thing. That's why you get what you get in earlier code snippet.




回答2:


Yes, arr[i] is the same as *(arr+i) which is the same as *(i+arr) which again is the same as i[arr]

From Fabio Turati's comment: See "Why is a[5] == 5[a]" for more details.




回答3:


Absolutely not! To see that, just replace the array with a pointer in your example:

int *arr;
// s.t. i<n
arr[i] = 12;
// s.t. i<n 
*(arr + i) = 12;

This compiles fine, but it is undefined behavior. It is not guaranteed to work. In fact, there is nothing this program might do that would be considered a bug in the compiler.

Arrays are array; types containing data. Pointers point to where data is. Pointers don't contain actual data, while arrays do.

There are some circumstances where an array name behaves the same way as a pointer. This does not make the two identical.

For example, check this out:

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.


来源:https://stackoverflow.com/questions/48851598/are-arrays-in-c-a-syntactic-sugar-for-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!