Note that the C standard defines that the main()
program returns an int
, not void
.
Given the code:
#include <stdio.h>
int main()
{
char str[2][7] = {"1234567", "abcdefg"};
char** p = str;
printf("%d\n", *(p+1));
printf("%c\n", *(p+1));
return(0);
}
When compiled withgcc -o x -Wall x.c
, you get the warnings:
x.c: In function ‘main’:
x.c:5: warning: initialization from incompatible pointer type
x.c:6: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
x.c:7: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’
(If you omit the -Wall
, you don't get the format warnings.)
This tells you that you are passing a pointer to printf()
. Printing a pointer is not going to be all that useful. However, the previous warning also tells you that you are mis-initializing the variable p
. However, the net result is that p
points to the start of the space in str
. When you print
One interesting little quirk: normally, a string such as "1234567" includes a terminating NUL '\0'
; in your arays, because you specified that the length of the array is 7, not 8, the terminating null is missing. Be careful how you print the strings!
Here's another variant of the code:
#include <stdio.h>
int main()
{
char str[2][7] = {"1234567", "abcdefg"};
char** p = str;
printf("%d\n", *(p+1));
printf("%c\n", *(p+1));
printf("%p %p %p -- %p %p %p\n", str, &str[0], &str[0][0], p, p+1, *(p+1));
printf("%.4s\n", (p+1));
return(0);
}
That gives me the following output (from an Mac):
1631008309
5
0xbffffa5e 0xbffffa5e 0xbffffa5e -- 0xbffffa5e 0xbffffa62 0x61373635
567a
Note that the addresses str, &str[0] and &str[0][0] all have the same value, and that p+1
is four bytes further along. When treated as a string, it prints the last three bytes of the first initializer and the first byte of the second.
Also, for fun, compiled with gcc -m64 -o x64 x.c
, the output is:
1701077858
b
0x7fff5fbff9e0 0x7fff5fbff9e0 0x7fff5fbff9e0 -- 0x7fff5fbff9e0 0x7fff5fbff9e8 0x676665646362
bcde