#include<stdio.h>
void main()
{
char a[]="get organized learn c!";
printf("%s",&a[2]);
}
我得到的输出:%s格式用于查找字符串的地址
t organized learn c!
它应该给错误,因为我%s的
#include<stdio.h>
void main()
{
char a[]="get organized learn c!";
printf("%s",&a[2]);
}
我得到的输出:%s格式用于查找字符串的地址
t organized learn c!
它应该给错误,因为我%s的
不,你的代码行为使用&正确。
a
是char
类型的数组。它兼容char *
a[2]
是单char
&a[2]
是char *
指向阵列中的第三个字符。它相当于a + 2
。它不应该给出错误 - 代码中的printf工作正常。
你不能只看&
运算符的地址,并决定它产生的结果是无效的,因为表达式的其余部分也很重要。在你的情况下,&
运算符适用于a[2]
,所以它取得字符串中第三个字符的地址。这是有效的,只要您的以null结尾的字符串至少有两个字符,您的字符串就是这样做的。
get organized learn c!\0
^^ ^
| | +- null terminator
| +---------------------- &a[2] points here
+------------------------ a, interpreted as a pointer, points here
正如你所看到的,a
和&a[2]
点有效null结束的C字符串。在你的情况下,字符串重叠,但C不禁止它。
*代码正常工作*:除了'void main()';-) – chqrlie
@chqrlie对,有一些健康的UB生活中总是有地方:-) – dasblinkenlight
错误不是你期望:
不带参数的原型为main
应该int main(void)
为了获得良好的作风,main
应该返回0明确。
对于转换说明符%s
,printf
需要一个指向空终止字符串的指针。 &a[2]
是a
中第三个字节的地址,它是一个有效的char
指针,变为a
,即以空字符结尾的字符串"t organized learnc!"
,这里没有错误。
你可以写a + 2
或2 + a
,甚至使用相同的确切含义&2[a]
。
#include <stdio.h>
int main(void) {
char a[] = "get organized learn c!";
printf("%s\n", &a[2]);
return 0;
}
应该返回0是否返回EXIT_SUCCESS? –
@EdHeal:行为应该基本相同:来自'main'的返回值的处理就如同调用exit()作为它的'status'参数:*最后,控制返回到主机环境。如果'status'的值是零或'EXIT_SUCCESS',则返回状态成功终止的实现定义形式。如果'status'的值是'EXIT_FAILURE',则返回状态不成功终止的实现定义形式。否则,返回的状态是实现定义的。* – chqrlie
为什么你认为你应该得到一个错误? –
''%s“'格式*预计*指针。指向以零结尾的'char'元素的指针。这是你给出的论点。你为什么认为你应该得到一个错误? –