我有一些与此代码相关的问题.printf的参数是类型const char*和...(可变参数列表).
1)为什么程序的输出是d和不是127?
2)是否+1会转换为字符串并传递给类型的参数变量const char*?
#include<stdio.h>
int main()
{
printf("%d"+1 , 127); //how this will get executed?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
d
Run Code Online (Sandbox Code Playgroud)
Yun*_*sch 19
第一个参数是指向char.
文字"%d"将是指向'%'它的指针,隐含地跟着'd'和'\0'.它是一个指针char,因为这是字符串文字的C表示:'\0'末尾带有a的字符序列; 表示用作参数等作为指针char.
但是"%d"+1,根据指针算法,是一个指针'd',后跟'\0'.
两者都是零终止的,因为它适合printf的参数.
所以输出是一样的
printf("d", ignored);
Run Code Online (Sandbox Code Playgroud)
127变为"忽略",即它被忽略,因为"d"告诉printf不要期望任何东西,因为它没有任何特殊的字符序列,例如"%someletter".因此它不会期望,不会寻找任何东西,也不会在它认为给出的完全正常的字符串之外进行任何打印.
但请注意,其他参数(格式字符串中未包含的参数)会被评估然后被忽略.这是相关的,因为该评估的任何副作用(例如函数调用)确实发生.
有关详细信息,请参见此处:http:
//en.cppreference.com/w/c/io/fprintf
让我试着帮助并添加@Yunnosch的答案,你可以做到以下几点:
char *str = "%d";
printf (str, 127);
Run Code Online (Sandbox Code Playgroud)
和输出应该是:
127
Run Code Online (Sandbox Code Playgroud)
在上面的示例str中存储在这样的内存中(这只是一个示例,在现实生活中的地址类似于0xabcdef12345678):
address | memory
--------+--------------
0 | %
1 | d
3 | \0
Run Code Online (Sandbox Code Playgroud)
所以str指向地址0(或系统上的等价物),它保存%,printf()获取该地址并从那里开始读取,读取直到它击中NULL字符'\ 0'.现在,每次看到的时候%它会查找下一个字符d,c,x等它读取参数列表中的下一个参数.如果你提供d它将输出十进制,如果你提供c它将打印字符,x是十六进制,还有更多.因此,printf()将读取所有字符并替换%<place holder>为适当的参数,直到它遇到NULL字符\0,但它将从提供的地址开始.
你的情况:
printf("%d"+1, 127);
Run Code Online (Sandbox Code Playgroud)
与:
char *str = "%d";
printf (str + 1, 127); // printf receives address of character `d` as starting point
Run Code Online (Sandbox Code Playgroud)
或者它类似于
char *str = "%d";
char *str1 = str+1; // increment the address of string by one
printf (str1, 127)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,它接收地址d并从那里读取,直到它命中\0.
如果你这样做:
printf ("%d" + 2, 127);
Run Code Online (Sandbox Code Playgroud)
这将是:
char *str = "%d";
printf (str + 2, 127);
Run Code Online (Sandbox Code Playgroud)
它会输出任何东西,因为,printf()会获得地址\0.正如@Yunnosh说的127那样会被忽略.
因此+1,+2不要将它们转换为字符串,而是将它们添加到字符串的地址中.
我希望这有帮助,我想我回答了你的两个问题.