Search code examples
cstringpointersmultidimensional-arrayformat-specifiers

For "char list[3][10];" why does all of these work as scanf() %s arguments---&list[i],list[i],&list[i][0]?


Isn't char* the only valid argument type for the %s format specifier used in the format specifier string of scanf()?If so,in my program why each one of these work exactly the same for both scanf()'s and printf()'s %s format specifier:

scanf("%s",&list[i]);
scanf("%s",list[i]);   
scanf("%s",&list[i][0]);

I'll appreciate if you clear the following confusions that arise from this premise:

1) Why is &name[i] working given it is of type char (*)[].Isn't &name[i][0] is the only valid argument as it is of type char* ?

2) Does name[i] decompose/translate into char* when we pass it as an argument for %s?Is it same as passing &name[i][0],which is the address of the first character of each name we enter?Is it why it works?

#include<stdio.h>
#include<string.h>

int main(void)
{

char list[3][10];
int i;
printf("Enter the three names \n");

for(i=0;i<=2;i++)
scanf("%s",&list[i]);  //Why this works?
//scanf("%s",list[i]);   //Does it decompose into char* type?
//scanf("%s",&list[i][0]);

for(i=0;i<=2;i++)
printf("%s\n",list+i);  //All of these printf() work as well
//printf("%s\n",list[i]);
//printf("%s\n",&list[i][0]);

}

Solution

  • list[i] is a char[10], and undergoes array-to-pointer conversion when passed as an argument, so in that place, it is completely equivalent to &list[i][0].

    &list[i] is a char(*)[10] and as such an invalid argument for the %s conversion specifier in printf or scanf, invoking undefined behaviour.

    However, since the first byte in list[i] has the same address as the array list[i], usually it works(1), since printf and scanf don't know about the types of their arguments and interpret them according to the format string.

    (1) It will fail if the representation of a char* is different from that of a char(*)[10]. That would be uncommon, but is possible.