Let's say we have an array char a[] = "abcd"
. When I print the following:
printf("%p\n", a);
printf("%p\n", &a);
printf("%p\n", &a[0]);
printf("%p\n", a[0]);
I am getting the following results:
0061FF1B
0061FF1B
0061FF1B
00000061
which means that a[0]
is not pointing at the same memory address as either %a[0]
or a
. This is really confusing to me. I'd like someone to point out the difference between these pointers, and whether or not a[0]
is / decays to a pointer.
CodePudding user response:
When you compile the code with g , you will find the following warning
main.cpp: In function ‘int main()’:
main.cpp:7:21: warning: format ‘%p’ expects argument of type ‘void*’, but argument 2 has type ‘int’ [-Wformat=]
printf("%p\n", a[0]);
~~~~^
Here, a
and &a[0] point to the address of first item of the string
while a[0] is a char. You print a[0] whose ascii is 0x00000061
with %p
.
CodePudding user response:
a[0]
is not pointing anywhere because it isn't a pointer but a char
object. You lie to printf
and tell it that it is a pointer, when it isn't. That's an undefined behavior bug in your program.
Now as it happens 0x61 is the ASCII code for 'a'
.
Regarding the other lines in your code: whenever used in expressions or function calls, arrays "decay" into a pointer to their first element. There are very few exceptions when this decay doesn't happen - using the &
address-of operator is one of them.
Therefore: printf("%p\n", a);
decays to a pointer to the first element, which is 100% equivalent to printf("%p\n", &a[0]);
.
In case of printf("%p\n", &a);
the decay does not happen but you get the address of the array itself. In C, an array is nothing but a bunch of elements with no other overhead, so the address of the array will always be the same as the address of the first element.
CodePudding user response:
char a[] = "abcd"
- Array
a
, when used in an expression, will convert to pointer to first element of array i.e.&a[0]
(there are few exceptions to this rule). &a
is address of arraya
which is numerically same as the address of first element of array&a[0]
but the difference is in their type. The type of&a[0]
ischar *
whereas the type of&a
ischar (*) [5]
.&a[0]
is address of first element of arraya
.a[0]
is first element of character arraya
.
which means that a[0] is not pointing at the same memory address as either %a[0] or a. .......... whether or not a[0] is / decays to a pointer.
a[0]
is not a pointer, it is first element of array a
which is character 'a'
. Note that decay happens when array name is used.
When printing a[0]
, you should use the format specifier %c
. Wrong format specifier in printf()
lead to undefined behaviour. Also, format specifier %p
expect that the argument shall be a pointer to void
. You should type cast pointer argument to void *
- printf("%p\n", (void*)a);
.
CodePudding user response:
printf("%p\n", &a[0]);
printf("%p\n", a[0]);
In the first case you correctly print the address of the first element of a
.
In the second case you ask printf to print a pointer but you pass it a char
.
The char is automatically converted to an int (due to the signature of printf, that contains ...
).
The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments
The fact that printf prints 61
(exactly the ASCII code) is because on your computer the pointer to object and the int
have the same number of bits or because it has 0
s next to integer, where printf reads the pointer value.
But it is undefined behavior to pass printf a type and instrument it print other type.
CodePudding user response:
In C array variable is like address
char a[] = "abcd";
// it is all same
// a == &a == &a[0]
// &(a 1) == &a[1]
// so roughly say 'a' is pointer to address of first element of array
// and a[0] or a[1] is a value.
// this is more appropriate way to express a[0]
printf("%c\n", a[0]);