How does this code work?
#include <stdio.h>
#include <string.h>
int main()
{
#define NAME_LEN 10
char name[NAME_LEN+1]; // line 8
strcpy(name,"Hi"); // line 9
char (* name_ptr)[NAME_LEN +1] = & name; // line 10
printf("%s=%s\n%s=%s\n", // line 12
"name",name, // line 13
"name_ptr",name_ptr // line 14
);
}
Everything is routine until line 10. To me, Line 10 mixes together declaring a char * and char [length], so I would expect to have an array of 10 char * (clearly, the compiler disagrees, because this works). When I compile this with -Wall, I get the following:
$ cc -g -Wall a.C
a.C: In function ‘int main()’:
a.C:16:2: warning: format ‘%s’ expects argument of type ‘char*’, but argument 5 has type ‘char (*)[11]’ [-Wformat=]
);
What am I missing?
>Solution :
char (* name_ptr)[NAME_LEN +1]
name_ptr is a pointer to char array of NAME_LEN +1 elements. So the type of this pointer is not the same as char * even if they reference the same object.
The easiest to spot and understand difference is the pointer arithmetic.
Example:
int main()
{
#define NAME_LEN 10
char name[NAME_LEN+1]; // line 8
strcpy(name,"Hi"); // line 9
char (* name_ptr)[NAME_LEN +1] = & name; // line 10
printf("name = %p (name + 1) = %p, difference in chars = %td\n",
(void *)name, (void *)(name + 1), (char *)(name + 1) - (char *)name); // line 12
printf("name_ptr = %p (name_ptr + 1) = %p, difference in chars = %td\n",
(void *)name_ptr, (void *)(name_ptr + 1), (char *)(name_ptr + 1) - (char *)name_ptr); // line 12
}
And the result:
name = 0x7fff645264b5 (name + 1) = 0x7fff645264b6, difference in chars = 1
name_ptr = 0x7fff645264b5 (name_ptr + 1) = 0x7fff645264c0, difference in chars = 11
As you see the pointer to array adds the whole size of the array to the initial address.
So if you want to use this pointer in the printf you need to dereference it:
printf("name_ptr = %s\n",name_ptr[0]);
printf("name_ptr = %s\n",*name_ptr);