C 使用&;使用数组返回意外结果
我一直在学习C,遇到了以下代码。我知道它是做什么的,但我不知道它为什么会这样C 使用&;使用数组返回意外结果,c,C,我一直在学习C,遇到了以下代码。我知道它是做什么的,但我不知道它为什么会这样 char str[5] = "hele"; printf("string is %s: \n", &str[1]); output: ele 为什么&str[1]输出ele?根据我目前所读的,&返回地址,因此不应&str[1]返回地址“e”。由于输出为“ele”,我知道情况并非如此,但我不明白原因。感谢所有帮助 这是因为C字符串只是内存中的若干字符后跟一个空字符str在内存中有一些地址,&str[1]相当于
char str[5] = "hele";
printf("string is %s: \n", &str[1]);
output:
ele
为什么&str[1]输出ele?根据我目前所读的,&返回地址,因此不应&str[1]返回地址“e”。由于输出为“ele”,我知道情况并非如此,但我不明白原因。感谢所有帮助 这是因为C字符串只是内存中的若干字符后跟一个空字符
str
在内存中有一些地址,&str[1]
相当于str+1
(数组在该表达式中变成指针)。您得到的是一个指向原始字符串中间的指针,它也是一个有效字符串,只是缺少开头
它在内存中的外观如下所示:
[h ] [e ] [l ] [e ] [\0]
^ str points here
当
printf
打印字符串时,它接收指向第一个字符的指针,就像大多数处理字符串的函数一样,并打印字符,直到到达终止null(\0
)。如果您改为传入str+1
,它将愉快地打印从索引1开始的字符串部分。这是printf
的原型:
int printf(const char *format, ...);
它与转换说明符一起使用,如%d、%a、%s、%c
如果使用了%s
,则const char*
参数应该是指向字符类型数组的指针(指向字符串的指针)
回到您的案例:
&str[1]
确实指向'e'
,并且它是指向字符串的指针,因此printf
的参数类型显然正确
接下来,请看Cobster的高质量评论
printf函数中的%s将其用作字符串的开头,然后
将继续,直到遇到空终止符
首先,c中的字符串基本上是一个字符数组。所以你的字符串实际上包含
h (position 0) e (position 1) l (position 2) e (position 3) \0 (position 4)
括号内的所有内容仅供解释
&
运算符返回变量的地址或数组元素的地址
所以当你这么做的时候
printf("string is %s: \n", &str[1]);
&str[1]
返回str[1]
的地址。如果将%c
放入printf,则str[1]
元素的值即e
,将被打印出来。但是当您放置%s
时,printf
将它作为字符串的开始,从必须打印的位置开始,然后打印字符串,直到遇到空终止符(\0
)
为了更好地解释:
有一个字符串,其内容为hele
h
是第0个元素,e
是第一个元素,l
是第二个元素,e
是第三个元素,\0
作为第四个元素。字符串基本上是一个字符数组,其中每个元素都是一个char
。他们每个人都有一个地址。这样做&str[1]
返回字符数组的第一个元素的地址。然后,%s
将其作为要打印的字符串的开始,并打印字符串,直到遇到空终止符(\0
)。因此,它将字符串的开头作为第一个e
,或第一个元素。然后打印l
和e
,然后遇到空终止符,并在此处停止
&str[1]不会返回地址。printf函数中的%s将其用作字符串的开头,并将一直持续到遇到空终止符为止。因此ele.this&str[1]
是字符串数组中第二个元素的地址,数组索引从0开始,因此第一个元素是&str[0]
。不,C字符串不是指针。引用C标准:“字符串是以第一个空字符结尾并包含该空字符的连续字符序列。”。。。“指向字符串的指针是指向其初始(最低地址)字符的指针。”@KeithThompson:Sigh。。。更好?@MattiVirkkunen你为什么要为此叹息?指针和它所指向的对象之间的区别并不是微不足道的;基思不仅仅是学究气。@immibis好吧,他是学究气,但是电脑会更学究气,所以他这么做是对的。:-)