首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >printf(3+“优秀”+4)这一行是如何运行的?

printf(3+“优秀”+4)这一行是如何运行的?
EN

Stack Overflow用户
提问于 2019-11-21 19:05:46
回答 3查看 197关注 0票数 7

我不明白为什么这个程序中的输出是nt

有人能解释一下这个程序吗?

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int main(){

    printf(3+"excellent"+4); //output is  "nt"

    return 0;
}
EN

回答 3

Stack Overflow用户

发布于 2019-11-21 20:11:27

"excellent"是一个类型为char[10]的数组,其元素是单词的9个字母和终止'\0'。然后,C11 6.3.2.1p3

  1. 除非是sizeof运算符、_Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则具有类型“类型数组”类型的表达式将转换为类型为“指针到类型”的表达式,该表达式指向数组对象的初始元素,而不是lvalue。..。

也就是说,它被转换为指向字符串(e)的第一个字符的指针,然后具有char *类型。

现在我们有两个补充:

代码语言:javascript
复制
(3 + (char *)"excellent") + 4

C标准指出(简化的,C11 6.5.6p8),当将整数和指针相加时,结果将是相同类型的指针,并将被解释为如果指针p指向数组的元素n,则p + m将导致指向相同数组的元素n + m的指针,或指向结束后的元素n + m,或者,如果n + m超出数组的界限或超出数组的结束,则行为是未定义的。

也就是说,3 + "excellent"将给出指向第二个字母e of excellent的指针。当然,由于括号大小的表达式具有char *类型,并且它指向数组的元素3,如果将4添加到其中,就会得到指向元素7的指针,即第8个字母,n

代码语言:javascript
复制
 <-------------- char [10] -------------->

 +---+---+---+---+---+---+---+---+---+---+
 | e | x | c | e | l | l | e | n | t | \0|
 +---+---+---+---+---+---+---+---+---+---+
   ^           ^               ^
   |           |               |
   first character, "excellent" after lvalue conversion
               |               |
               + 3 + "excellent"
                               |
                               + 3 + "excellent" + 4

最后,当我们调用printf提供这样的指针作为参数时会发生什么?printf将把参数看作是指向以空结尾的字符串(即格式字符串)的第一个字符的指针。除了以%开头的特殊序列之外,所有字符都会逐字复制到输出,直到满足终止null为止。

另一种研究这些问题的方法是记住

代码语言:javascript
复制
*(a + b)

等于

代码语言:javascript
复制
a[b] (or even b[a])

既然&*x等同于x

代码语言:javascript
复制
&*(a + b) == (a + b) == (b + a) == &a[b] == &b[a]`

我们明白了

代码语言:javascript
复制
3 + "excellent" + 4

等于

代码语言:javascript
复制
&"excellent"[3] + 4

这等于

代码语言:javascript
复制
&"excellent"[3 + 4]

代码语言:javascript
复制
&"excellent"[7]
票数 9
EN

Stack Overflow用户

发布于 2019-11-21 19:52:38

代码语言:javascript
复制
printf(3+"excellent"+4);

可以用更长的时间写,但用一种更清晰的方式写:

代码语言:javascript
复制
const char *str = "excellent";
const char *to_print = str + 3 + 4; // equivalent to &str[7] which points to 'n'
printf(to_print); // or printf("%s", to_print); which prints "nt"
票数 7
EN

Stack Overflow用户

发布于 2019-11-21 19:09:32

这是因为它在第七个字符之后打印所有的东西。加号告诉它从哪里开始打印。如果你把它改为printf(2+"excellent"+4),你就会得到"ent“。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58982070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档