Speaking in terms of exact variable lengths and addresses:
Case 1:
char str1[] = "test";
allocates a 5 bytes memory space, say from 0x0050
to 0x0054
, and str1
is the address of the first character of the string; that is, 0x0050
in this case.
When it is used in printf
with a %s
format specifier, the compiler knowing the str1
is an array of characters, directly sends the address of str1
to the printf
function and it prints the string.
When it is used in printf
with a %p
format specifier, the compiler assumes that the coder is interested in the address of the string; again sends the address of str1
to the printf
function and this time, it prints the address of the string.
Case 2:
char *str2 = "test";
allocates a 5 bytes memory space, say from 0x0050
to 0x0054
. This time however, str2
is a pointer stored in another address, say 0x0030
; and it's value is 0x0050
, pointing the first character of the string.
When it is used in printf
with a %s
format specifier, the compiler knowing the str2
is a pointer to an array of characters, sends the value stored in str2
to the printf
function; not the address of str2
.
When it is used in printf
with a %p
format specifier, the compiler assumes that the coder is interested in the address of the string; again sends the value stored in str2
to the printf
function.
Case 3:
char *arrStr[4];
arrStr[0] = str1;
Here, the behavior of the compiler resembles the Case 2 above.
When it is used in printf
with a %s
format specifier, the compiler knowing the arrStr[0]
is a pointer to an array of characters, sends the value stored in arrStr[0]
to the printf
function (and in fact, this is the address of str1
); not the address of arrStr[0]
.
When it is used in printf
with a %p
format specifier, the compiler assumes that the coder is interested in the address of the string; again sends the value stored in arrStr[0]
to the printf
function.
So, if you're interested in the address of the arrStr[0]
(not
the value that it is pointing to), you should use &arrStr[0]
with a
%p
format specifier.