views:

676

answers:

6

Is an array's name a pointer in C? If not, what is the difference between an array's name and a pointer variable?

+11  A: 

An array is an array and a pointer is a pointer, but in most cases array names are converted to pointers.

Here is an array:

int a[7];

a contains space for seven integers, and you can put a value in one of them with an assignment, like this:

a[3] = 9;

Here is a pointer:

int *p;

p doesn't contain any spaces for integers, but it can point to a space for an integer. We can for example set it to point to one of the places in the array a, such as the first one:

p = &a[0];

What can be confusing is that you can also write this:

p = a;

This does not copy the contents of the array a into the pointer p (whatever that would mean). Instead, the array name a is converted to a pointer to its first element. So that assignment does the same as the previous one.

Now you can use p in a similar way to an array:

p[3] = 17;

The reason that this works is that the array dereferencing operator in C, "[ ]", is defined in terms of pointers. x[y] means: start with the pointer x, step y elements forward after what the pointer points to, and then take whatever is there. Using pointer arithmetic syntax, x[y] can also be written as *(x+y).

For this to work with a normal array, such as our a, the name a in a[3] must first be converted to a pointer (to the first element in a). Then we step 3 elements forward, and take whatever is there. In other words: take the element at position 3 in the array. (Which is the fourth element in the array, since the first one is numbered 0.)

So, in summary, array names in a C program are (in most cases) converted to pointers. One exception is when we use the sizeof operator on an array. If a was converted to a pointer in this contest, sizeof(a) would give the size of a pointer and not of the actual array, which would be rather useless, so in that case a means the array itself.

Thomas Padron-McCarthy
A similar automatic conversion is applied to function pointers - both `functionpointer()` and `(*functionpointer)()` mean the same thing, strangely enough.
Carl Norum
He did not asked if arrays and pointers are the same, but if an array's name is a pointer
Ricky AH
An array name is not a pointer. It's an identifier for a variable of type array, which has an implicit conversion to pointer of element type.
Pavel Minaev
Also, apart from `sizeof()`, the other context in which there's no array->pointer decay is operator ` that is, its type will be `int(*)[7]`, which is not implicitly convertible to `int*`. This way, functions can actually take pointers to arrays of specific size, and enforce the restriction via the type system.
Pavel Minaev
Thomas Padron-McCarthy
to be fair, asking for the difference of an array's name in expressions to the name of a pointer is not asking whether arrays are different from pointers. Example: In C++, a reference's name in expressions is the same as the referenced object's name in expressions. Still, a reference is not the same as the object it references. But instead, while evaluating, the reference type is replaced by the referenced type, and is an lvalue. In C, somewhat similar happens with arrays, just that this conversion doesn't *always* happen: Not in sizeof and address-of: These are operators not applied to values
Johannes Schaub - litb
Note that this automatic conversion doesn't happen in C++. In C++, it happens only when needed (for example when assigning to a pointer), whereas in C, the array to pointer conversion always happens if not within sizeof or address-of or initializing an array with a string literal.
Johannes Schaub - litb
A: 

An array declared like this

int a[10];

allocates 10 ints on the stack. You can't modify a but you can do pointer arithmetic with a.

A pointer like this allocates just the pointer p on the stack:

int *p;

It doesn't allocate any ints. You can modify it:

p = a;

and use array subscripts as you can with a:

p[2] = 5;
a[2] = 5;    // same
*(p+2) = 5;  // same effect
*(a+2) = 5;  // same effect
Grumdrig
Arrays are not always allocated on the stack. Yhat's an implementation detail that will vary from compiler to compiler. In most cases static or global arrays will be allocated from a different memory region than the stack. Arrays of const types may be allocated from yet another region of memory
Mark Bessey
+1  A: 

An array is a collection of secuential and contiguous elements in memory. In C an array's name is the index to the first element, and applying an offset you can access the rest of elements. An "index to the first element" is indeed a pointer to a memory direction.

The difference with pointer variables is that you cannot change the location the array's name is pointing to, so is similar to a const pointer (it's similar, not the same. See Mark's comment). But also that you don't need to dereference the array name to get the value if you use pointer aritmetic:

char array = "hello wordl"; char* ptr = array;

char c = array[2]; //array[2] holds the character 'l' char *c1 = ptr[2]; //ptr[2] holds a memory direction that holds the character 'l'

So the answer is kinda 'yes'.

Ricky AH
An array name is not the same as a const pointer. Given:int a[10];int *p=a;sizeof(p) and sizeof(a) are not the same.
Mark Bessey
Ok, Edited for clarification
Ricky AH
Pavel Minaev
A: 

The array name by itself yields a memory location, so you can treat the array name like a pointer:

int a[7];

a[0] = 1976;
a[1] = 1984;

printf("memory location of a: %p", a);

printf("value at memory location %p is %d", a, *a);

And other nifty stuff you can do to pointer (e.g. adding/substracting an offset), you can also do to an array:

printf("value at memory location %p is %d", a + 1, *(a + 1));

Language-wise, if C didn't expose the array as just some sort of "pointer"(pedantically it's just a memory location. It cannot point to arbitrary location in memory, nor can be controlled by the programmer). We always need to code this:

printf("value at memory location %p is %d", &a[1], a[1]);
Michael Buen
A: 

When an array is used as a value, its name represents the address of the first element.
When an array is not used as a value its name represents the whole array.

int arr[7];

/* arr used as value */
foo(arr);
int x = *(arr + 1); /* same as arr[1] */

/* arr not used as value */
size_t bytes = sizeof arr;
int *q = &arr;
pmg
A: 

If an expression of array type (such as the array name) appears in a larger expression and it isn't the operand of either the & or sizeof operators, then the type of the array expression is converted from "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element in the array.

In short, the array name is not a pointer, but in most contexts it is treated as though it were a pointer.

John Bode