在做`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,比如从0x0050
到0x0054
,str1
是字符串第一个字符的地址;也就是说,在这种情况下 0x0050
。
当它在 printf
中与 %s
格式说明符一起使用时,编译器 知道 str1
是一个字符数组 ,直接将 str1
的 地址 发送到 printf
函数并打印字符串。
当它在 printf
中与 %p
格式说明符一起使用时,编译器 假定编码器对字符串的地址感兴趣 ;再次将 str1
的 address 发送到 printf
函数,这一次,它打印字符串的地址。
案例二:
char *str2 = "test";
分配一个5字节的内存space,比如从0x0050
到0x0054
。然而,这次 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.
我有这个代码:
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,比如从0x0050
到0x0054
,str1
是字符串第一个字符的地址;也就是说,在这种情况下 0x0050
。
当它在 printf
中与 %s
格式说明符一起使用时,编译器 知道 str1
是一个字符数组 ,直接将 str1
的 地址 发送到 printf
函数并打印字符串。
当它在 printf
中与 %p
格式说明符一起使用时,编译器 假定编码器对字符串的地址感兴趣 ;再次将 str1
的 address 发送到 printf
函数,这一次,它打印字符串的地址。
案例二:
char *str2 = "test";
分配一个5字节的内存space,比如从0x0050
到0x0054
。然而,这次 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.