声明的输出如何是'E'

时间:2017-07-31 11:00:10

标签: c arrays implicit-conversion string-literals pointer-arithmetic

#include <stdio.h>

main() {
    printf("ABCDE" + sizeof("ABC");/*please explain the output*/
}

该程序的输出E使用gcc编译,请解释

3 个答案:

答案 0 :(得分:3)

C标准中的两个引号将使结果清晰。

第一个是关于字符串文字(6.4.5字符串文字)

  

6在转换阶段7中,附加一个值为零的字节或代码   每个由字符串文字产生的多字节字符序列   或者文字.78)然后使用多字节字符序列   初始化一个静态存储持续时间和长度的数组   足以包含序列。对于字符串文字,   数组元素具有char类型,并使用个体初始化   多字节字符序列的字节....

第二个是关于隐式转换(6.3.2.1 Lvalues,数组和函数指示符)

  

3 除非它是sizeof运算符的操作数或   一元&amp; operator,或者是用于初始化数组的字符串文字,   具有类型''数组类型''的表达式将转换为类型为''指向类型'的指针的表达式,指向初始值   数组对象的元素,而不是左值。如果是数组对象   具有寄存器存储类,行为未定义。

因此,根据第一个引用,字符串文字"ABC"被存储为类型char[4]的字符数组(由于附加的零)和静态存储持续时间。

根据表达式

中的第二个引用
sizeof("ABC")

数组未转换为指针。所以实际上这个表达式等同于表达式

sizeof( char[4] )

并将结果等于4

所以表达式

"ABCDE" + sizeof("ABC")

可以像

一样重写
"ABCDE" + 4

在根据第二个引用的表达式中,表示自身为字符数组的字符串文字"ABCDE"将转换为指向其第一个元素的指针。因此,使用了所谓的指针算法。

您可以使用以下代码片段

来设想函数调用中表达式的求值结果
char string_literal[6] = "ABCDE";
char *p = &string_literal[0];
printf( p + 4 );

表达式p + 4指向字符'E',相当于&p[4]&string_literal[4]

注意根据相同的C标准,没有参数的函数main应声明为

int main( void )

即使函数体中没有return语句。

答案 1 :(得分:0)

这是因为终止'\0'字节,3 + 1字节所以"ABCDE"[4]'E'

此外,main()的正确签名是

  1. int main(void)或,
  2. int main(int argc, char *argv[])

答案 2 :(得分:0)

您的计划的输出不是E,因为)

中缺少printf("ABCDE" + sizeof("ABC");,因此不会按照过帐进行编译

字符串常量的大小是包含空终止符的字节数,因此sizeof("ABC")的计算结果为4

"ABCDE" + 4是地址,如果字符串中的E,并且由于字符串dos在此E之后没有任何其他字符,则输出与{{1}的结果相同}}

请注意,没有参数的printf("E");的原型是main,并且为了好的风格,您应该返回int main(void)并输出换行符。

以下是您的代码的更正版本:

0

输出

#include <stdio.h>

int main(void) {
    printf("ABCDE\n" + sizeof("ABC"));
    return 0;
}