Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用&;使用数组返回意外结果_C - Fatal编程技术网

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]相当于

我一直在学习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]
相当于
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好吧,他是学究气,但是电脑会更学究气,所以他这么做是对的。:-)