Search code examples
arrayscpointersimplicit-conversionpointer-arithmetic

which one is the correct type of an array variable? (for using with pointers in C)


If i want to initialize a pointer to an int to an array, i need to use this notation:

int data[] = {34,35,36};
int *ptr = &data[0];

because the type of the variable data is int[], that's the reason why the next declaration gives warnings:

int *ptr = &data;

In the case above I'm assigning an "array type" to an int pointer, it's a mistake and is ok. So, why is it possible to use the next code to iterate in the array:

for(int i=0;i<3;i++)
    *(data+i);

What the line above should do is to add the size of the full array in every iteration and the correct code should be as shown below:

for(int i=0;i<3;i++)
    *(&data[0] + i);

but if we test them, both are equals and correct to iterate in the array.

So, the type of the variable data (alone, without []) should be thought as int[] or int? how can i know when a variable will have one type or another to do correct pointer aritmethic.


Solution

  • In most cases whenever an array name is used in an expression, it decays into a pointer to it's first element. Therefore int *ptr = &data[0]; is 100% equivalent to int *ptr = data;.

    As for accessing individual items of an array, or of an array pointed at through a pointer to the first element, arr[i] is 100% equivalent to *(arr + i), the latter is just needlessly hard to read. See Do pointers support "array style indexing"?

    However, one exception to the mentioned array decay rule is when an array name is used as operand to the & operator. In that case it does not decay - instead we get a pointer to "the array as whole". In your case int *ptr = &data; is an invalid pointer conversion because &data is of type int(*)[3], a pointer to array.

    Please note however that in the expression &data[i], operator precedence says that [] "binds tighter" to the data operand than &. So it is equivalent to &(data[i]). The previously mentioned exception to array decay does not apply, since the & is never applied to the array name, but to an item in the array. Array decay into a pointer to the first element has already happened when we reach &, since it happened at the point where [] was encountered.