Are arrays and pointers implemented differently in C and C++? I have come across this question because, in both the cases we access elements from the starting address of an element. So, there should be close relation between them. Please explain the exact relation between them. Thanks.
Share
Let’s get the important stuff out of the way first: arrays are not pointers. Array types and pointer types are completely different things and are treated differently by the compiler.
Where the confusion arises is from how C treats array expressions. N1570:
Let’s look at the following declarations:
arris a 10-element array ofint; it refers to a contiguous block of memory large enough to store 10intvalues. The expressionarrin the second declaration is of array type, but since it is not the operand of&orsizeofand it isn’t a string literal, the type of the expression becomes “pointer toint“, and the value is the address of the first element, or&arr[0].parris a pointer to int; it refers to a block of memory large enough to hold the address of a singleintobject. It is initialized to point to the first element inarras explained above.Here’s a hypothetical memory map showing the relationship between the two (assuming 16-bit ints and 32-bit addresses):
Object Address 0x00 0x01 0x02 0x03 ------ ------- ---------------------- arr 0x10008000 0x00 0x00 0x00 0x01 0x10008004 0x00 0x02 0x00 0x03 0x10008008 0x00 0x04 0x00 0x05 0x1000800c 0x00 0x06 0x00 0x07 0x10008010 0x00 0x08 0x00 0x09 parr 0x10008014 0x10 0x00 0x80 0x00The types matter for things like
sizeofand&;sizeof arr == 10 * sizeof (int), which in this case is 20, whereassizeof parr == sizeof (int *), which in this case is 4. Similarly, the type of the expression&arrisint (*)[10], or a pointer to a 10-element array ofint, whereas the type of&parrisint **, or pointer to pointer toint.Note that the expressions
arrand&arrwill yield the same value (the address of the first element inarr), but the types of the expressions are different (int *andint (*)[10], respectively). This makes a difference when using pointer arithmetic. For example, given:the “before” line should print the same values for all three expressions (in our hypothetical map,
0x10008000). The “after” line should show three different values:0x10008000,0x10008002(base plussizeof (int)), and0x10008014(base plussizeof (int [10])).Now let’s go back to the second paragraph above: array expressions are converted to pointer types in most circumstances. Let’s look at the subscript expression
arr[i]. Since the expressionarris not appearing as an operand of eithersizeofor&, and since it is not a string literal being used to initialize another array, its type is converted from “10-element array ofint” to “pointer toint“, and the subscript operation is being applied to this pointer value. Indeed, when you look at the C language definition, you see the following language:In practical terms, this means you can apply the subscript operator to a pointer object as though it were an array. This is why code like
works the way it does.
mainis dealing with an array ofint, whereasfoois dealing with a pointer toint, yet both are able to use the subscript operator as though they were both dealing with an array type.It also means array subscripting is commutative: assuming
ais an array expression andiis an integer expression,a[i]andi[a]are both valid expressions, and both will yield the same value.