From my understanding so far,
char * argv[] = {"abc", "def"};
initialises an array of 2 char
pointers. First one points to "abc"
, the second to "def"
. And the name argv
is also a pointer that points to the first pointer in the array argv
.
Why does some say argv
is an array of char
strings then? (like in the C Programming Language by K&R). Don't they mean an array of pointers to char
s, which the book also explains.
If my hypothesis is correct, the %s
in printf("%s", argv[1])
is not expecting a char string
at all, rather, a pointer to the char string
?
Thanks for your patience!
Stuff i've read:
As used in the C standard, “A string is a contiguous sequence of characters terminated by and including the first null character” (C 2018 7.1.1 1). It is not a char *
. A char *
may point to the first character of a string and is sometimes referred to in the C standard as a pointer to a string, but this is sloppy terminology as a char *
is necessarily a pointer to a character—there is no technical definition for what it means to point to a “sequence,” although we may take it to mean to point to the first element of a sequence.
From my understanding so far,
char * argv[] = {"abc", "def"};
initialises an array of 2char
pointers.
That is correct.
And the name
argv
is also a pointer that points to the first pointer in the arrayargv
.
That is not correct given the definition of argv
in the question. The definition char * argv[] = {"abc", "def"};
defines argv
to be an array of char *
. It is not a pointer.
When an array is used as the operand of sizeof
or unary &
, it is operated on as an array. (Also, when an array is initialized with a string literal, the string literal is used as an array.) Other than these circumstances, when an array is used in an expression, it is converted to a pointer to its first element. This conversion is automatic and is so common that students may mistake the array, or the name of the array, for the pointer it is converted to. That is a mistake. The array is not a pointer.
Why does some say
argv
is an array ofchar
strings then? (like in the C Programming Language by K&R).
Kernighan and Ritchie do not say this in either edition of The C Programming Language in any of the places listed for argv
in the index. In the first edition, 1978, they say on page 110 “the second (argv
) is a pointer to an array of character strings that contain the arguments, one per string.” In the second edition, 1988, they say on page 114 “the second (argv
, for argument vector) is a pointer to an array of character strings that contain the arguments, one per string.” The index also lists page 163 for argv
, but there is just an incidental mention there, referring to argv[0]
for the program name.
Note that they refer to argv
as a pointer rather than an array. This is because the argv
parameter to main
is a pointer. Although it may be declared with int main(int argc, char *argv[])
, a parameter that is declared as an array is automatically adjusted to be a pointer. Thus char *argv[]
in the declaration of main
defines argv
to be something different from the statement you showed, char * argv[] = {"abc", "def"};
. In the parameter declaration, it is automatically adjusted to be a pointer. In the separate definition, it is an array.
Although Kernighan and Ritchie do refer to argv
as a pointer, not an array as you wrote, they says it is a “pointer to an array.” This is also sloppy terminology. Its type is pointer-to-pointer-to-char
, not pointer-to-array-of-char
. It is a pointer to an array only in the sense that it is a pointer to the first element of an array of char
.
If my hypothesis is correct, the
%s
inprintf("%s", argv[1])
is not expecting achar string
at all, rather, a pointer to thechar string
?
Per C 2018 7.21.6.1 8, for an s
specifier to printf
without a modifier or a precision, “the argument shall be a pointer to the initial element of an array of character type. Characters from the array are written up to (but not including) the terminating null character.” Thus, one should pass a char *
(or a signed char *
or unsigned char *
) that points to the initial character of a string.