为什么我的printf输出结果与预期不符?

3
我将尝试理解在以下情况下printf的工作原理:(这是一道测试题的奖励问题)
情况1:
int d=1;
printf("%d",(int)"printf("%d);

输出值: 0

情况2:(结尾没有%d

int d=1;
printf("%d",(int)"printf(");

输出结果为: 15554368
这是怎么实现的呢?为什么使用%d会产生不同的结果呢?

3
这是什么荒谬之语?你想要做什么? - Eugene Sh.
你在哪里看到这个的? - Iharob Al Asimi
1
首先打印指针除以'd'的余数。其次打印指针值。如所述,这是无意义的。 - Eugene Sh.
@Coldspeed 看起来相当一致。 - Eugene Sh.
1
@ThingyWotsit 看起来像是来自混淆C代码竞赛的一些摘录...这可能是一个有趣的游戏,为什么不试试呢? - Jean-Baptiste Yunès
显示剩余7条评论
3个回答

4
这个奖励问题是一个恶作剧问题: printf("%d", (int)"printf("%d); 被解析为
printf(
       "%d",
       ((int)"printf(") % d
      );

字符串"printf("的地址被转换为int,并计算模数操作。由于d = 1,模数始终为0。因此,printf输出0

第二个调用只是打印了转换为int的字符串地址,这在不同的环境中可能会有所不同,甚至可能在每次运行时都会有所不同(在我的Mac上确实如此)...

事实上,转换甚至可能失败并触发实现特定的行为。因此,答案在两种情况下真正应该是实现定义的行为。

另一个问题应该是:

int d=1;
printf("%d",(int)printf("%d", d));

这将产生11。你能解释一下为什么吗?

请注意,即使是最后一个问题也很棘手:如果没有正确的原型调用printf,例如未包含<stdio.h>,则会导致未定义的行为。


3

让我们从第二个例子开始:

int d=1;
printf("%d",(int)"printf(");

在这里,"printf(" 是一个字符串常量,只包含C函数名,试图让您感到困惑。字符串常量的类型为char *,它是指向第一个字符的指针。 (int)将指针转换为整数。虽然这是实现定义,但您将获得与实际存储"printf("字符串的地址相关的某些值。
所以在这里打印一个数字,这个数字恰好是指针转换为int的结果。
接下来:
int d=1;
printf("%d",(int)"printf(" % d);

只有一个更改,我添加了空格以使其更明显:你从指针转换中获得的int被取模于d,因此结果是整数除以d的余数。由于d为1,因此永远不会有余数,任何数字都可以被1整除而不产生余数。因此结果是0

2
第二个%d不是printf()的格式控制符,而是%取模运算符和值为1int变量d。它们有什么区别?它们完全不相同。
第二个问题是,您正在将指针强制转换为int,这是不明确的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接