2

I come from a Java background and in C I am little bit confused about the C array syntax.

When I initialize an array in C I do this:

int arr[5];

As far as I understand it correctly this actually gives a pointer to arr that points to the first element of the array on the stack.

But then I don't understand why the array initialization does not look like this since we receive a pointer:

int* arr[5];

This gives me something I don't understand. Maybe an array of 5 pointers?

On the other hand this is totally valid again:

int arr[5];
int* p = arr;

So why is it done like this? Shouldn't the initalization syntax be with an int* instead of an int since we actually receive a pointer?

  • 1
    `int arr[5];` ... array of 5 `int`. `int *arr[5];` ... array of 5 `int*`. `int (*arr)[5];` ... pointer to array of 5 `int`. Yeah, that's tricky. (IMHO, this is the most hard part when learning C.) This may help: [C to gibberish](https://cdecl.org/?q=int*%20arr[5]). – Scheff's Cat May 20 '18 at 10:31
  • "why" ... C is quite old language, with idea to be capable to write assembler class solutions in more portable way. 2 it is lightweight, no array bounds checking (like few years younger Pascal) etc – Jacek Cz May 20 '18 at 10:31
  • 1
    The first is an array of 5 integers. An array is not a pointer, although it may decay to a pointer to the first element. The second is an array of 5 pointers. In the third, `int* p = arr;` is assigning a pointer (which the array decays to) to a pointer variable. I suggest you place the `*` with the variable name, not with its type, such as `int *p;`. If you define, for example, `int* p, q;` you have not defined two pointer variables, but one pointer and one integer. This would be clearer as `int *p, q;` – Weather Vane May 20 '18 at 10:35
  • 1
    You do not "actually receive a pointer", you receive an array. `int[5]` means an object whose layout is 5 contiguous `int`s. The line `int arr[5];` makes one of those objects called `arr`. It is analogous to `int y;` except the object is 5 times as big and you can refer to its sub-objects. – M.M May 20 '18 at 23:06

1 Answers1

1

In C syntax this line declares an array of 5 pointers to int.

int* arr[5];

Below an array of 5 ints is declared.

int arr[5];

The line above told the compiler to reserve in memory 5 times the size of int in adjacent addresses of memory starting at &arr[0]. While arr is not a pointer, itself, if used as a name, arr, decays to a pointer to the first slot (so arr is equivalent to &a[0]).

int* p = arr; 

p is an ordinary pointer to int, assigned to a valid memory address, the same as arr (or &arr[0] )

Arrays and pointers differ. The first difference is 'arr' is a constant and can't be reassigned to other addresses.

For example the following is invalid

arr++;

While the following is valid

p++;

Furthermore pointers require extra dereference underlying ASM operations, whereas arrays don't

char arr[7];
char *p = arr;

Arrays indexing

Compare this line and its ASM instructions:

char a = arr[7];

0041137E mov al,byte ptr [_array_place+7 (417007h)]

00411383 mov byte ptr [a],al


Pointer indexing:

With this line and its ASM instructions:

char b = p[7];

00412DD7 mov eax,dword ptr [ptr_arg]

00412DDA mov cl,byte ptr [eax+7]

00412DDD mov byte ptr [b],cl


Arrays can decay to pointers to the first element. This happens frequently, e.g. when you pass them as function arguments. In that case, treat them as pointers inside the called function. You can eventually label them as constant pointers or pointers to constant or constant pointers to constant.

I hope this clarifies.

Attersson
  • 4,755
  • 1
  • 15
  • 29