我不明白为什么nt在此程序中输出。
谁能解释这个程序?
#include <stdio.h>
#include <stdlib.h>
int main(){
printf(3+"excellent"+4); //output is "nt"
return 0;
}
Run Code Online (Sandbox Code Playgroud)
"excellent"是类型的数组char[10],其元素是该单词的9个字母和终止符'\0'。然后C11 6.3.2.1p3,
- 除非它是运算
sizeof符,_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则类型为“ array of type”的表达式将转换为类型为“ pointer to type”的表达式”,它指向数组对象的初始元素,而不是左值。[...]
也就是说,它将转换为指向字符串第一个字符(e)的指针,然后具有类型char *。
现在我们有两个补充:
(3 + (char *)"excellent") + 4
Run Code Online (Sandbox Code Playgroud)
C标准说(简化为C11 6.5.6p8),将整数和指针加在一起时,结果将是相同类型的指针,并且将对其进行解释,因此,如果指针p指向n数组的元素,然后p + m将产生一个指针,该指针将指向n + m同一数组的元素,或者指向末尾的一个指针,或者如果指向数组n + m边界之外或指向末尾的一个指针,则该行为是不确定的。
即3 + "excellent"会给出一个指针将指向第二个字母e的excellent。当然,由于括号括起来的表达式具有类型,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
Run Code Online (Sandbox Code Playgroud)
现在最后,当我们调用printf给出这样的指针作为参数时会发生什么?printf会将参数视为指向空终止字符串(格式字符串)的第一个字符的指针。除了以开头的特殊序列外%,所有字符都逐字复制到输出中,直到满足终止null为止。
研究这些问题的另一种方法是记住
*(a + b)
Run Code Online (Sandbox Code Playgroud)
等于
a[b] (or even b[a])
Run Code Online (Sandbox Code Playgroud)
并且由于&*x是等同于x,
&*(a + b) == (a + b) == (b + a) == &a[b] == &b[a]`
Run Code Online (Sandbox Code Playgroud)
我们得到了
3 + "excellent" + 4
Run Code Online (Sandbox Code Playgroud)
等于
&"excellent"[3] + 4
Run Code Online (Sandbox Code Playgroud)
等于
&"excellent"[3 + 4]
Run Code Online (Sandbox Code Playgroud)
即
&"excellent"[7]
Run Code Online (Sandbox Code Playgroud)
这个
printf(3+"excellent"+4);
Run Code Online (Sandbox Code Playgroud)
可以用更长但更清晰的方式编写:
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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |