Hello I am learning c in school and having a little confusion on this problem.
That is,
b
is two d array, and I am trying to implement around printing values and the adress,
but why is *(b 1)
giving the same thing as b 1
?
I thought *(b 1)
would give the value of the first element of the second row.
and if I change printf("%p\n", *(b 1))
to printf("%d\n", *(b 1))
, it just gives a garbage value.
Why is it working like this?
I appriciate any feedback! thank you
int main()
{
int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
printf("b:\n");
print_2d_array(3, 4, b);
printf("\n");
printf("%p\n", b);
printf("%p\n", *(b 1));
printf("%p\n", b 1);
return 0;
}
Output is like this,
b:
0 1 2 3
4 5 6 7
8 9 10 11
0x7ffeecee6730
0x7ffeecee6740
0x7ffeecee6740
CodePudding user response:
The question you have asked essentially boils down to a question about the nature of an array and the address of an array, which is a fairly well covered topic (see this for example). However, you likely confused yourself with the pointer arithmetic, so this answer tries to clarify some of that.
In C, when array object is used in an expression, its value and type becomes the same as the pointer to its first element.
In your case, you have:
int b[3][4] = { /* ... */ };
/* ... */
printf("%p\n", *(b 1));
printf("%p\n", b 1);
If we consider the last print statement,b
in the expression b 1
becomes the same as &b[0] 1
, and this would be the same as &b[1]
.
When we consider the print statement before the last one, we note that *(b 1)
is defined to be the value b[1]
. However, the result of that expression is an array of 4 int
. That array now takes on the value and type of its first element, which would be &b[1][0]
.
Since you need to be able to find the address of the first element of an array from the array itself, the address of an array, &b[1]
, has the same pointer value as the address of its first element &b[1][0]
.
However, &b[1]
and &b[1][0]
have different types. The former is a pointer to an array, while the later is a pointer to an int
.
For additional information, I encourage you to read the linked question at the top of this answer for more about arrays and the address of arrays.
CodePudding user response:
*why is (b 1) giving the same thing as b 1?
The output address is numerically same but their type is different.
The type of *(b 1)
is int [4]
whereas the type of b 1
is int (*)[4]
.
*(b 1)
, when used in an expression, will convert to address of first element of second row1):
*(b 1) -> b[1] -> ((b[1]) (0)) -> &(*((b[1]) (0))) -> &b[1][0]
and b 1
will give address of second row.
Address of an array and address of first element of that array are numerically same but their type are different.
*I thought (b 1) would give the value of the first element of the second row.
*(b 1)
will give the second element of 2D array b
which is nothing but a 1D
array of 4
integers.
To access the first element of second row using *(b 1)
, you can do:
(*(b 1))[0]
To access the second element of second row using *(b 1)
, you can do:
(*(b 1))[1]
third element ....
(*(b 1))[2]
and so on .....
Note that *(b 1)
is equivalent to b[1]
1). So,
(*(b 1))[0] is equivalent to b[1][0]
(*(b 1))[1] is equivalent to b[1][1] .. and so on
Hope this clarifies your doubt.
1 ) From C Standards#6.5.2.1
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1) (E2)))..