Question about printf arguments. C / C ++

We have the following code snippet:

char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'}; printf("%s\n", tab); 

And I donโ€™t understand why we donโ€™t get an error / warning when calling printf . I get a warning, but not an error, and the program works fine. He is typing " 12 ".
printf expects an argument of type char * , that is, a pointer to char . Therefore, if I declared char arr[3] , then arr is the address of the memory block that contains char , so if I called printf with it, it would decay to a pointer to char, i.e. char * .
Similarly, tab is the address of a memory block that contains an array of 3 char 'types, which, in turn, contains the address of a char memory block, so tab decays to char ** , and this should be a problem since printf expects a char * .

Can someone explain this problem?

Addendum:

The warning I get:
ac:6: warning: char format, different type arg (arg 2)

+4
source share
4 answers

Example Source

 #include <stdio.h> int main( void ) { char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'}; printf("%s\n", tab); return 0; } 

Compile warning

  $ gcc test.c
 test.c: In function 'main':
 test.c: 5: warning: format '% s' expects type 'char *', but argument 2 has type 'char (*) [3]' 

Pointers - pointers

The argument %s for printf tells the function that it will receive a pointer (to a string). A string in C is just a series of bytes terminated by ASCII-Z. The variable tab[2][3] is a pointer. Some compilers give a warning about pointer mismatch. However, the code should still print 12 , because the printf code moves through memory, starting with the pointer that it set (prints characters as it arrives) until it finds a null byte. 1, 2 and \ 0 are adjacent in memory starting from the address represented by the variable tab .

Experiment

As an experiment, what happens when you compile and run the following code:

 #include <stdio.h> int main( void ) { char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'}; printf("%s\n", tab[1]); return 0; } 

Do not be afraid to experiment. See if you can find the answer based on what you now know. How would you now refer to tab (in the light of the experiment) to get rid of the warning and still display 12 ?

+6
source

The tab parameter matches elipsis in the printf () call. C and C ++ compilers are not required to check such parameters.

+4
source

Your assumption that tab will fade to char ** is wrong: tab is of type char [2][3] , that is, it will fall to char (*) [3] . It is important to understand that although arrays and pointers often behave the same, they are not the same thing. printf() expects a char * , so it takes the char (*) [3] bit and interprets them accordingly. Although it runs on your platform, the C standard does not guarantee this: both pointers refer to the same memory location, but their representation does not have to be identical.

Check out my answer to this related question for details.

+3
source

You seem to have explained it yourself, I donโ€™t see what to say.

tab - an array of two char * . Each tab element is a string that printf can accept, but tab itself is not acceptable, as it is a pointer to a pointer to a char.

+1
source

All Articles