8

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 syntactic sugar for *(arr+ i) ?

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
David
  • 733
  • 2
  • 11
  • 30

5 Answers5

11

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.

alk
  • 69,737
  • 10
  • 105
  • 255
user2736738
  • 30,591
  • 5
  • 42
  • 56
5

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.

Gerhardh
  • 11,688
  • 4
  • 17
  • 39
0

Yes, you can access the elements of array with arr[i]/*(arr+i).

you can even use increment operation on array pointers. *ptr = &arr, ptr++

it means every time you add an integer or increment to array pointer the pointer add (size of datatype)*i to the previous pointer.

Nivesh Gadipudi
  • 486
  • 5
  • 15
0

Strictly saying, array is NOT syntactic sugar for the pointer. By definition, "syntactic sugar" is language construct, which it allows you to write shorter / clearer an equivalent of some other language construct. Situation with pointers and arrays is different. Pointer is variable that contains memory address of some value. In difference, array is variable which contains those values themselves. However, syntax of C is built in a way, which allows you treat pointer as address of the first element of array and apply indexing operator on it. But I'd not say this is syntactic sugar, this is base syntax of language.

ivan.ukr
  • 2,853
  • 1
  • 23
  • 41
-1

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.
Shachar Shemesh
  • 8,193
  • 6
  • 25
  • 57
  • This is all down to Dennis Ritchie being high when designing the C language features: 'I know, I'll allow array arguments to be passed automatically as a pointer, without requiring the '&' address operator' Saves one char typing, causes decades of confusion :( "Hey ,the argument is an array, the parameter is a pointer, so an array and a pointer must be the same thing". – Martin James Feb 18 '18 at 12:34
  • 1
    In how far is that related to the question? – Gerhardh Feb 18 '18 at 12:39
  • 2
    The question is not about whether "an array is a pointer or not". It is about the equivalence of the subscript operator and the de-reference operator. – machine_1 Feb 18 '18 at 12:47
  • @MartinJames I know you were joking about dmr being "high", but the actual history of arrays and pointers in C is considerably more nuanced. See [*The Development of the C Language*](https://www.bell-labs.com/usr/dmr/www/chist.html) if curious. (See especially the sentence "the empty square brackets [...] are a living fossil".) – Steve Summit Feb 18 '18 at 18:04
  • @Gerhardh the question's body is talking about subscripting, but the question itself is about arrays and pointers. I read the body (and I don't think it's reasonable to read it otherwise) as an example to the actual question. People confuse arrays and pointers all the time. – Shachar Shemesh Feb 18 '18 at 19:07
  • Also @machine_1. See my comment above. – Shachar Shemesh Feb 18 '18 at 19:08
  • @ShacharShemesh I don't agree. I think the body is the question and the title is just poorly worded. – Gerhardh Feb 19 '18 at 08:09
  • You "non-working" example works perfectly well if you remember to allocate some memory for int *arr; Which is exactly what the compiler has done for you when declaring an array. And (at least in my experience) the array-pointer equivalence avoids all sorts of problems (especially in mixed-language programming) with passing multi-dimensioned "arrays", where sizes have to be passed as hidden arguments &c. – jamesqf Feb 19 '18 at 21:47
  • @Shachar Shemesh: If people confuse arrays and pointers - or rather, get confused by the interchangable syntax - it's because they don't understand the language, or perhaps basic programming concepts. – jamesqf Feb 19 '18 at 21:49