Here is a code which print the address of the first element of an 2D array followed by an addition of 1. Though all 4 base addresses are same but their addition with 1 is obviously not giving the same result due the their different "types". I can figure out the type for some(in case they are correct) but not for all.
int main()
{
int array[4][3];
printf("array %u\n",array); //of type int(*)[3]
printf("array+1 %u\n",array+1);
printf("&array %u\n",&array); //....???
printf("&array+1 %u\n",&array+1);
printf("array[0] %u\n",array[0]); //of type int*
printf("array[0]+1 %u\n",array[0]+1);
printf("&array[0] %u\n",&array[0]); //....???
printf("&array[0]+1 %u\n",&array[0]+1);
}
Can you explain the "type" of each base address in detail in order to understand the pointer arithmetic involved after adding 1. A sample output for gcc machine is given below for quick reference.
array 3214383040
array+1 3214383052
&array 3214383040
&array+1 3214383088
array[0] 3214383040
array[0]+1 3214383044
&array[0] 3214383040
&array[0]+1 3214383052
Having int array[4][3];
the following applies
array
is an array with 4 elements. Each element is an array with 3 int
s. In most circumstances using the name by itself makes the array decay to a pointer to its first element; then array
becomes a pointer to arrays of 3 int
s
array + 1
is a pointer to an array of 3 ints. Here array
decays to pointer and the 1
refers to array of 3 int
&array
is the address of the whole array. It points to objects of type array of 4 arrays of 3 ints
&array + 1
is the 2nd (which really does not exist) element of a pseudo-array of arrays of 4 arrays of 3 ints
array[0]
is an array of 3 ints. It usually decays to a pointer to the first element
array[0] + 1
points to the 2nd int
in array[0]
&array[0]
address of an object of type array of 3 ints
&array[0]+1
2nd element of an array of arrays of 3 ints
PS. I'll try to make a drawing (ASCII) after lunch.
Hmmm ... drawing is tough :)
Before trying, I thought I could make a better drawing. This is the best I could come up with ...
int array[4][3] ........[aaabbbcccddd]........ where aaa, bbb, ccc, ddd are arrays of 3 ints' the [] represent the object itself; the {} represent pointers. array (object) ........[AAABBBCCCDDD]........ int[4][3] array (decayed) ==> ........{aaa}bbbcccddd........ int(*)[3] array + 1 ==> ........aaa{bbb}cccddd........ int(*)[3] &array ==> ........{aaabbbcccddd}........ int(*)[4][3] &array + 1 ==> ........aaabbbcccddd{xxxxxxxxxxxx}........ int(*)[4][3] array[0] (object) ........[AAA]bbbcccddd........ int[3] array[0] (decayed) ==> ........{a}aabbbcccddd........ int* array[0] + 1 ==> ........a{a}abbbcccddd........ int* &array[0] ==> ........{aaa}bbbcccddd........ int(*)[3] &array[0] + 1 ==> ........aaa{bbb}cccddd........ int(*)[3]
If you compile this as C++, you can use the typeid
operator from the typeinfo
STL library to get this information. For example, running this
#include <stdio.h>
#include <typeinfo>
void main()
{
int array[4][3];
printf("array %s\n",typeid(array).name()); //of type int(*)[3]
printf("array+1 %s\n",typeid(array+1).name());
printf("&array %s\n",typeid(&array).name()); //....???
printf("&array+1 %s\n",typeid(&array+1).name());
printf("array[0] %s\n",typeid(array[0]).name()); //of type int*
printf("array[0]+1 %s\n",typeid(array[0]+1).name());
printf("&array[0] %s\n",typeid(&array[0]).name()); //....???
printf("&array[0]+1 %s\n",typeid(&array[0]+1).name());
}
Gave me the following results
array int [4][3]
array+1 int (*)[3]
&array int (*)[4][3]
&array+1 int (*)[4][3]
array[0] int [3]
array[0]+1 int *
&array[0] int (*)[3]
&array[0]+1 int (*)[3]
This explains why adding 1 can increase the pointer by 4 bytes (a single int), 12 bytes (int[3]) or by 48 bytes (int[4][3]).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With