问题
Please help me out as to why in below code outputs are different:
int z[][3] = { 1, 2, 3, 4, 5, 6 };
printf("\n**(z+1): %d", **(z + 1));
Output: (z+1): 4
char y[][3] = { "A", "F", "G", "J", "M", "P" };
printf("\n**(y+1): %c", **(y+1));
Output: (y+1): F
Why in the above two outputs, first is checking the 4th index while in second output prints 2nd index ?
回答1:
Why in the above two outputs, first is checking the 4th index while in second output prints 2nd index ?
That's not actually close to describing what is happening.
To understand what is happening, write the examples into their actual meaning
int z[][3] = { 1, 2, 3, 4, 5, 6 };
printf("\n**(z+1): %d", **(z + 1));
is actually
int z[][3] = { {1, 2, 3}, {4, 5, 6} };
printf("\n**(z+1): %d", **(z + 1));
where z[0] is an array of three elements initialised with {1, 2, 3} and z[1] is an array of three elements initialised with {4,5,6}.
In this z + 1 is equal to &z[0] + 1 which is equal to &z[1] (the address of an array of three int). So *(z+1) is (a reference to) z[1] (an array of three elements) and **(z+1) is z[1][0]. Since z[1] is an array initialised as elements {4,5,6}, z[1][0] is the first element of that array. This has a value of 4.
In comparison,
char y[][3] = { "A", "F", "G", "J", "M", "P" };
printf("\n**(y+1): %c", **(y+1));
each of the string literals is initialised as an array of two elements e.g. "A" is initialised as {'A', '\0'}.
Now y is an array of arrays of three char. If an array of three elements is given an initialiser with two char, as is the case here, the values that are not explicitly initialialised are zero-initialised. So
char y[][3] = { "A", "F", "G", "J", "M", "P" };
is equivalent to
char y[][3] = { {'A', '\0', '\0'}, {'F', '\0', '\0'}, {'G', '\0', '\0'}, {'J', '\0', '\0'}, {'M', '\0', '\0'}, {'P', '\0', '\0'}};
So y is array of six elements, each of which is an array of three char.
Using the same logic as in the discussion of z above, y + 1 is equal to &y[1] where y[1] is an array of three char that is initialized as {'F', '\0', '\0'}.
So *(y + 1) is (a reference to) y[1], and **(y + 1) is y[1][0]. This has a value of 'F'.
回答2:
If you do this
int z[][3] = { 1, 2, 3, 4, 5, 6 };
printf("\n**(z+1): %d", **(z + 1));
you actually get
int z[2][3] = { {1, 2, 3}, {4, 5, 6} };
printf("\n**(z+1): %d", **(z + 1));
With this definition, *(z+1) points to {4,5,6} and therefore **(z+1) accesses the integer value 4.
You access the first element of the second element of our array.
In your second version this happens:
char y[][3] = { "A", "F", "G", "J", "M", "P" };
printf("\n**(y+1): %c", **(y+1));
This will result in
char y[6][3] = { {'A',0,0}, {'F',0,0}, {'G',0,0}, {'J',0,0}, {'M',0,0}, {P',0,0}};
printf("\n**(y+1): %c", **(y+1));
Now *(y+1) points to {'F',0,0} and therefore **(y+1) accesses the character value 'F'.
You access the first element of the second element of our array.
This is in fact the same result as with first version.
回答3:
You actually don't need two dimensional char array , if you use only one character in each array.
Like here:
char y[] = { 'A', 'F', 'G', 'J', 'M', 'P' };
printf("\n**(y+1): %c", *(y + 1));
来源:https://stackoverflow.com/questions/62495737/difference-of-value-of-ptr1-in-char-and-int