输出原因

Par*_*ita 4 c

#include<stdio.h>
int main(void)
{
 int a=5;
 printf("%d"+1,a);
}
Run Code Online (Sandbox Code Playgroud)

输出:d.我没有得到输出的结果:d?

Mat*_*lia 24

你通过了第一个论点printf "%d"+1; "%d"实际上被视为const char *指向存储的存储位置%d.与任何指针一样,如果将其递增1,结果将指向以下元素,在本例中,将是d.

a没有使用,但这不应该是一个问题,因为一般情况下(我不知道它是否是标准强制 编辑:是的,请参阅底部)可变参数函数的堆栈清理责任取决于调用者(至少,cdecl这样做,但这可能是也可能不是UB,我不知道*).

你可以通过这种方式看到它:

#include<stdio.h>
int main(void)
{
    int a=5;
    const char * str="%d";
    printf(str + 1, a);
}
Run Code Online (Sandbox Code Playgroud)

 

str ---------+
             |
             V
          +----+----+----+
          |  % |  d | \0 |
          +----+----+----+

str + 1 ----------+
                  |
                  V
          +----+----+----+
          |  % |  d | \0 |
          +----+----+----+
Run Code Online (Sandbox Code Playgroud)

因此,("%d"+1)(它"d")被解释为格式字符串,并且printf,没有找到任何%,将简单地按原样打印它.如果你想要打印a加1 的值,你应该已经完成​​了

printf("%d", a+1);
Run Code Online (Sandbox Code Playgroud)


编辑: *好吧,它不是UB,至少对于C99标准(§7.19.6.1.2),可以使用未使用的参数fprintf:

如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略.

printf定义为在§7.19.6.3.2中具有相同的行为

printf函数等效于fprintf,其参数stdout插入到printf的参数之前.


Ign*_*ams 12

字符串文字是指针.将指针推进"%d"1会导致"d".这个论点被抛弃了.