格式字符串参数后"+1"对printf()的影响

Gok*_*oku 6 c

我有一些与此代码相关的问题.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

  • 我可以推荐你在任何体面书店翻阅的几本书,这些书最能帮到你.也就是说,在阅读了几段之后,翻阅页面和你没有放下的书,这对你来说是正确的.这里任何用户最喜欢的书可能是错误的,太贵或需要太长时间才能交付.书店,浏览,喜欢,购买.那是1小时的食谱. (2认同)
  • @Goku我认为你应该更加努力地理解这个答案,它解释了你所看到的,以及为什么忽略了"127"这个论点.一本好书会有所帮助,但他的答案对你的问题非常具体. (2认同)
  • @chux好点,任何副作用当然会在忽略之前发生,编辑成答案.谢谢. (2认同)

0x4*_*16e 5

让我试着帮助并添加@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不要将它们转换为字符串,而是将它们添加到字符串的地址中.

我希望这有帮助,我想我回答了你的两个问题.