当我遇到这段代码时,我正试图在C中学习字符串。
#include <stdio.h>
int main(){
char s[] = "Hello world";
printf("%s" , s);
printf("%s" , &s);
return 0;
}
两者都将Hello World作为输出。根据我的理解,这个输出对于第一种情况是好的。如何为第二个工作?请澄清。
答案 0 :(得分:6)
获取数组的地址与获取第一个元素的地址相同。当使用数组的名称时,它也会衰减到它的第一个元素的地址 - 因此表达式s
和&s
会产生相同的结果。
答案 1 :(得分:4)
s
返回数组中第一项的地址,&s
返回数组本身的地址 - 这些都是相同的。
通常,如果您希望更明确,表达式&s[0]
也可用于返回第一个项目的地址。
答案 2 :(得分:2)
s
和&s
返回相同的地址。该地址是存储“Hello world”中“H”的位置。
由于,
数组的名称衰减到数组中第一个元素的地址&amp;
第一个元素的地址与数组的地址相同。
答案 3 :(得分:1)
只是为了获得可能的价值,如果你想获得技术,你的第二个版本:
printf("%s" , &s);
有未定义的行为,只能偶然发挥作用。通过显式获取地址,您将获得数组的地址(这很好),但结果的类型为“指向12个字符的数组的指针”,而不是类型“指向char的指针”,如{{{ 1}}%转换。由于类型不匹配,结果是未定义的行为。
然而,实际上,纯粹是技术性 - 代码在我知道的C的每个实现上都能正常工作。
如果你想证明存在差异,你可以很容易地做到这一点。例如:
printf
在第一种情况下,char string[] = "hello world";
printf("without &: %p, %p\n", (void *)string, (void *)(string+1));
printf("with &: %p, %p\n", (void *)&string, (void *)(&string+1));
衰减到指向char的指针,所以在第一行,第二个指针恰好比第一个指针大一个。在第二行,我们在指向字符数组的指针中添加一个,所以当我们添加一个字符时,它实际上会添加数组的大小。在我的机器上运行它,我得到这样的结果:
string
答案 4 :(得分:0)
char s []类似于char * s,它是一个指向数组第一个元素的charecter指针(它包含存储的第一个元素的地址)。 我们还可以通过存储第一个字符的地址来存储字符串。在执行期间,计算机开始逐个从该地址获取字符并创建一个字符串,直到它到达空字符('\ 0')。 在上面的例子's'和'%s'代表相同的值(起始字符的地址)希望你能得到它。 如果你使用char [10](固定长度数组)你会理解一切。
答案 5 :(得分:-1)
s相当于&amp; s [0]所以我们传递s [0]的地址而不是指向s [0]的指针的地址,所以它将在第二种情况下打印Hellow世界。
是数组的名称而不是指针。