这行的printf(3+“ excellent” +4)如何运行?

Jaden 7 c string printf

我不明白为什么nt在此程序中输出。
谁能解释这个程序?

#include <stdio.h>
#include <stdlib.h>

int main(){

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

    return 0;
}

Antti Haapal.. 9

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

  1. 除非它是运算sizeof符,_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则类型为“ array of type”的表达式将转换为类型为“ pointer to type”的表达式”,它指向数组对象的初始元素,而不是左值。[...]

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

现在我们有两个补充:

(3 + (char *)"excellent") + 4

C标准说(简化为C11 6.5.6p8),将整数和指针加在一起时,结果将是相同类型的指针,并且将对其进行解释,因此,如果指针p指向n数组的元素,然后p + m将产生一个指针,该指针将指向n + m同一数组的元素,或者指向末尾的一个指针,或者如果指向数组n + m边界之外或指向末尾的一个指针,则该行为是不确定的。

3 + "excellent"会给出一个指针将指向第二个字母eexcellent。当然,由于括号括起来的表达式具有类型,char *并且它指向数组的元素3,因此如果将其加4,我们将得到一个指向元素7的指针,即第8个字母the n

 <-------------- 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为止。


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

*(a + b)

等于

a[b] (or even b[a])

并且由于&*x是等同于x

&*(a + b) == (a + b) == (b + a) == &a[b] == &b[a]`

我们得到了

3 + "excellent" + 4

等于

&"excellent"[3] + 4

等于

&"excellent"[3 + 4]

&"excellent"[7]


Alex Lop... 7

这个

printf(3+"excellent"+4);

可以用更长但更清晰的方式编写:

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"