在做`char first_word[MAX_LENGTH + 1] = "test";`时,first_word是指针还是字符串?

When doing `char first_word[MAX_LENGTH + 1] = "test";`, is first_word a pointer or a string?

我有这个代码:

char first_word[MAX_LENGTH + 1] = "test";
printf("Word to input: %s\n", first_word);
printf("Word to input: %p\n", first_word);

两者都打印成功(打印字符串 "test",然后是地址)。

在我的代码中,我最终会这样做:

char *arr_of_strings[MAX_LENGTH + 1];
arr_of_strings[0] = first_word;

并且它正确地将 arr_of_strings[0] 设置为任何 first_word 是什么(在这种情况下是一个指针,因为 *arr_of_strings 是一个指针数组,对吧?)。但现在当我这样做时

printf("arr at 0 is: %s\n", arr_of_strings[0]);

它又打印了一个字符串,我也可以这样打印一个地址吗:

printf("arr at 0 is: %p\n", arr_of_strings[0]);

那么c什么时候把first_word当作字符串,什么时候把它当作指针呢?

正确答案是字符数组的标识符。

  • 不是字符串,因为字符串甚至不是C中的类型。 C 被定义为一个字符序列,包括一个 0 / '[=11=]' 字符在末尾(表示结束)。所以,first_word可以持有一个字符串,但你不能说它一个字符串。它可以容纳任何 char 序列,而不仅仅是字符串。

  • 不是指针,尽管在大多数情况下它计算为指针。除了与 sizeof_Alignof& 一起使用时,数组的标识符被评估为指向其第一个元素的指针。因此,first_word 在许多情况下将具有 char * 类型(指针类型),例如,您可以将它分配给一个指针,如 char *foo = first_word。尽管如此,对指针求值并不意味着它指针。运算符 sizeof_Alignof& 在数组上使用与在指针上使用时的计算结果截然不同。


关于您关于 printf 的问题:printf 中的 %s 需要传递一个指向 char (char *) 的指针,并期望该指针指向一个字符串。希望你看完上面的解释,明白什么意思。

就确切的可变长度和地址而言:

案例一:

char str1[] = "test";

分配5个字节的内存space,比如从0x00500x0054str1是字符串第一个字符的地址;也就是说,在这种情况下 0x0050

当它在 printf 中与 %s 格式说明符一起使用时,编译器 知道 str1 是一个字符数组 ,直接将 str1 地址 发送到 printf 函数并打印字符串。

当它在 printf 中与 %p 格式说明符一起使用时,编译器 假定编码器对字符串的地址感兴趣 ;再次将 str1address 发送到 printf 函数,这一次,它打印字符串的地址。

案例二:

char *str2 = "test";

分配一个5字节的内存space,比如从0x00500x0054。然而,这次 str2 是一个指针 存储在另一个地址 ,比如 0x0030;它的值为 0x0050,指向字符串的第一个字符。

当它在 printf 中与 %s 格式说明符一起使用时,编译器 知道 str2 是指向字符数组的指针 ,将str2中存储的发送给printf函数;不是 str2.

的地址

当它在 printf 中与 %p 格式说明符一起使用时,编译器 假定编码器对字符串的地址感兴趣 ;再次将存储在 str2 中的 value 发送到 printf 函数。

案例三:

char *arrStr[4];
arrStr[0] = str1;

在这里,编译器的行为类似于上面的情况 2。

当它在 printf 中与 %s 格式说明符一起使用时,编译器 知道 arrStr[0] 是指向字符数组的指针 ,将arrStr[0]中存储的发送给printf函数(实际上,这是str1的地址);不是 arrStr[0].

的地址

当它在 printf 中与 %p 格式说明符一起使用时,编译器 假定编码器对字符串的地址感兴趣 ;再次将存储在 arrStr[0] 中的 value 发送到 printf 函数。

So, if you're interested in the address of the arrStr[0] (not the value that it is pointing to), you should use &arrStr[0] with a %p format specifier.