admin 管理员组文章数量: 887031
[C语言]关于printf输出的奇怪事:printf(“%d %d %d %d %d\n“, ++i,
题目
打开这篇文章,屏幕前的你一定也是C语言大军中的一员,不知道你能否猜出下面几个程序的运行结果
1.
#include<stdio.h>
int main(){char s[]="123",*p;p=s;printf("%c%c%c\n",*p++,*p++,*p++);return 0;
}
#include<stdio.h>
int main(){char s[]="123",*p;p=s;printf("%c",*p++);printf("%c",*p++);printf("%c",*p++);return 0;
}
#include<stdio.h>
int main(){int a=0;printf("%d%d%d\n",a++,a++,a++);return 0;
}
#include<stdio.h>
int main(){int a=0;printf("%d",a++);printf("%d",a++);printf("%d",a++);return 0;
}
#include<stdio.h>
int main()
{int j = 8;printf("%d ", ++j);printf("%d ", --j);printf("%d ", j++);printf("%d ", --j);printf("%d\n", j);return 0;
}
#include<stdio.h>
int main()
{int i = 8;printf("%d %d %d %d %d\n", ++i, --i, i++,i--, i);return 0;
}
上面程序运行结果如下
- 321
- 123
- 210
- 012
- 9 8 8 8 8
- 8 8 7 8 8
不知道屏幕前的你做对几道题呢?
如果全对了的话,那你
你可能对本片所讲的知识已经很熟悉了,可以选择不在看下去;
如果觉得文章有趣,想一探究竟,欢迎继续读下去
看到这里的同学可能作对了2、4和5,但是1、3和6有一些不太理解,为什么会这样呢?
解释
下面就为大家解惑,(2、4和5为正常情况,这里不在赘述)
首先,请大家观察一下1、3和6的共同点
最主要的是输出多个内容 %c%c%c 和%d%d%d
在输出这多个数据的时候,printf 的内部情况是怎么样的呢?
是从左到有依次进行输出吗? 从结果,我们可以发现,显然不是这种情况.
接下来,我们通过观察下面代码的反汇编,来逐步解释,是怎样执行的?
代码:
#include<stdio.h>
int main()
{int i = 8;printf("%d %d %d %d %d\n", ++i, --i, i++, i--, i);return 0;
}
汇编:
int i = 8;
mov dword ptr [i],8 printf("%d %d %d %d %d\n", ++i, --i, i++,i--, i);//i
mov eax,dword ptr [i]//将i变量的值存放到eax寄存器中
//i--
mov dword ptr [ebp-0DCh],eax //将eax寄存器中的值存放在一个临时变量中
mov ecx,dword ptr [i] //将i变量的值存放到ecx寄存器中
sub ecx,1 //ecx寄存器中的值-1
mov dword ptr [i],ecx //将ecx寄存器中的值写回i变量
//i++
mov edx,dword ptr [i]//将i变量的值存放到edx寄存器中
mov dword ptr [ebp-0E0h],edx //将edx寄存器中的值存放在临时变量
mov eax,dword ptr [i] //将i变量的值存放到eax寄存器中
add eax,1 //eax寄存器的值+1
mov dword ptr [i],eax //将eax寄存器中的值写回i变量
//--i
mov ecx,dword ptr [i] //将i变量的值存放到ecx寄存器中
sub ecx,1 //ecx寄存器的值+1
mov dword ptr [i],ecx // //将ecx寄存器中的值写回i变量
//++i
mov edx,dword ptr [i] //将i变量的值存放到edx寄存器中
add edx,1 //edx寄存器的值+1
mov dword ptr [i],edx //将edx寄存器中的值写回i变量
//
mov eax,dword ptr [i] //将i变量的值存放到eax寄存器中
push eax //将eax寄存器的值入栈
mov ecx,dword ptr [ebp-0DCh] //将这个临时变量放到ecx寄存器
push ecx //将ecx寄存器的值入栈
mov edx,dword ptr [ebp-0E0h] //将这个临时变量放到edx寄存器
push edx //将edx寄存器的值入栈
mov eax,dword ptr [i] //将i变量的值存放到eax寄存器中
push eax //将eax寄存器的值入栈
mov ecx,dword ptr [i] //将i变量的值存放到ecx寄存器中
push ecx //将ecx寄存器的值入栈
在上面汇编的解释中,栈 这个字,在最后出现多次。
可能有的小伙伴会很疑惑,什么是栈呢?
栈可以理解为一个容器,很想存放羽毛球的桶,我们先放入球桶当中的球一定是最后才能拿出来的,就像下面的过程,1我们最先放进去,最后取出来
通过之前的解释,大家也初步了解了 什么是栈?下面,我们就来演示一下代码的求取过程。
演示过程
首先,我们要明确,printf是一个stdio.h库中的一个函数,函数的参数是要存放在栈当中的。
即对于这一句 printf("%d %d %d %d %d\n", ++i, --i, i++, i--, i);
而言,可以使用下面进行表示
2.
我们从参数栈中取出表达式进行计算,计算结果也要放到一个栈(我们称其为结果栈)当中。
对于后置 ++ 或者 - - 而言,我们直接把结果放到结果栈中
对于前置 ++ 或者 - - 而言,我们把一个指向 i 变量的指针放入结果栈当中
对于一个变量而言,我们把一个指向 i 变量的指针放入结果栈当中
最终 i 的值为8;
我们使用 *(&i) 表示指向i变量的指针
从结果栈中取出结果,进行打印,上面的*(&i)表示最终 i 变量的值。
最终打印结果为 8 8 7 8 8
听到这里,不知道
总结
#include<stdio.h>
int main()
{int i = 8;printf("%d %d %d \n", ++i, i,i--);return 0;
}
- 从 右往左 进行计算
- 对于后置++或者-- 来说,计算结果即为打印结果
- 对于变量 、前置++或者- - ,打印所有表达式计算完毕后 ,i 的结果
执行 i - - ,打印结果8 ;i 变为7
执行i, 打印结果 最终 i 的值
执行i++, 打印结果 最终i的值 ,i变为8
最终i的值为8
打印结果为 8 8 8
记得点赞+收藏噢
如果你觉得不错,欢迎点赞+收藏,感谢!
本文标签: C语言关于printf输出的奇怪事printf(“d d d d dn“ I
版权声明:本文标题:[C语言]关于printf输出的奇怪事:printf(“%d %d %d %d %dn“, ++i, 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1731010272h1423972.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论