我试图理解printf
在这些情况下是如何运作的:(这是测试中的一个额外问题)
案例1:
int d=1;
printf("%d",(int)"printf("%d);
输出:0
案例2 :(最后没有%d
)
int d=1;
printf("%d",(int)"printf(");
输出:15554368
这是如何工作的?为什么%d
会让它与众不同?
答案 0 :(得分: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
。
答案 1 :(得分:3)
这个奖金问题是一个棘手的问题:
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>
,则会有未定义的行为。
答案 2 :(得分:2)
第二个%d
不是printf()
说明符,它是%
模除法运算符和int
变量d
价值1
,有什么区别?它们根本不相同。
第二个问题是,您正在投射指向int
的指针,该指针没有明确定义。