昨天有个以前的同事在QQ上问了我一个问题,问题是这样的:
char p[10][5];
printf("%d\n", (int)((int)(p + 1) - (int)p));
他问我为什么printf输出结果是1而不是5, 我看了看他给我的这个语句,我告诉他结果应该是5啊,怎么可能是1呢,但他说自己已经用gcc测试过了.我有点怀疑,我就自己在gcc上测试了一下,输出确实是5,但他还是坚持他的结果是1,我就让他把测试代码发给我了,结果他的代码是这样的:
char p[10][5];
printf("%d\n", (int)((p + 1) - p));
我一下子也愣了,为什么两句的输出不一样呢?所以我就自己把两句都测试了一下,果然后一句的输出是1,到底为什么两句会有这样的差别呢?
后来我对下面这几句代码进行了反汇编:
char p[10][5];
printf("%d\n", (int)((int)(p + 1) - (int)p));
printf("%d\n", (int)((p + 1) - p));
结果是:
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $80, %esp
movl $.LC0, %eax
movl $5, 4(%esp)
movl %eax, (%esp)
call printf
movl $.LC0, %eax
movl $1, 4(%esp)
movl %eax, (%esp)
call printf
movl $0, %eax
leave
ret
其它的暂且不看,就看红色标注的两句,很明显参数是以常数的形式压栈的,可见在编译期就已经决定了它的值.两句不一样的原因是:
printf("%d\n", (int)((int)(p + 1) - (int)p));当中强制类型转换的优级比较高,先转换再相减,相当于(int)&p[1][0] - (int)&p[0][0] = 5
printf("%d\n", (int)((p + 1) - p));则在编译器进行分析时就去计算出了 (p + 1) - p = p + 1 - p = 1
我不知道他出于什么原因会遇到这样的问题,至少我在工作当中很少见类似的情况,最少我自己没有写过这样的代码,最多也就在考试或面试题当中能遇到吧.
阅读(1280) | 评论(0) | 转发(0) |