【C】由printf("%d\t%d\t%d\n",a,a+=(a++),a);引起的思考
#include<stdio.h>
int main()
{
int a=,a1=;
int b=,b1=;
printf("(1)后自加:\n");
printf("a+=(a++):\n");//
printf("%d\t%d\t%d\n",a,a+=(a++),a);
printf("%d\n",a);
printf("a1+(a1++):\n");//
printf("%d\t%d\t%d\n",a1,a1+(a1++),a1);
printf("%d\n",a1); printf("\n(2)前自加:\n");
printf("b+=(++b):\n");//
printf("%d\t%d\t%d\n",b,b+=(++b),b);
printf("%d\n",b);
printf("b1+(++b1):\n");//
printf("%d\t%d\t%d\n",b1,b1+(++b1),b1);
printf("%d\n",b1);
return ;
}
aaarticlea/png;base64,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" alt="" />
总的来说挺纠结的,实际上面的结果计算涉及到如下几点:
(1) 当printf()参数表中有自加表达式时执行顺序:
后自加:以 8: printf("%d\t%d\t%d\n",a,a+=(a++),a);在VC6.0中的反汇编结果(见文末)为例:
1)倒数第一个参数入栈 (这里值得注意的是入栈时数据占的字节数依据是参数表中该变量的数据类型,且float类型按照double类型的字节数)
2)倒数第二个参数入栈:取(a++)的值得① --> 计算①+a得② --> 把②赋值给a
3)倒数第三个参数入栈
4)控制字符串入栈
5)输出 (这里值得注意的是输出时从栈中取数据时按照格式说明符对应的字节数,且%f对应double类型的字节数)
6)变量a自加1,并更新
前自加:以16: printf("%d\t%d\t%d\n",b,b+=(++b),b);在VC6.0中的反汇编结果(见文末)为例:
1)倒数第一个参数入栈
2)倒数第二个参数入栈:变量b自加1,并更新-->取b的值得① --> 计算b+①得② --> 把②赋值给b
3)倒数第三个参数入栈
4)控制字符串入栈
5)输出
(2)加法运算符'+'的计算顺序
这个也不用怀疑,计算顺序一定是先计算左操作数对应的表达式。
另外,要区分“计算”和“取值”的区别,如果左操作数只是一个变量,而右操作数是表达式。则先计算右操作数表达式的值,然后从左操作数的变量中取值再与该表达式相加。
因此: a+(++a)是 (变量a自加后数值+变量a自加后数值)而不是 (变量当前数值+变量a自加后数值)
以下是部分语句在VC6.0中反汇编结果:
: printf("%d\t%d\t%d\n",a,a+=(a++),a);
0040D75E mov eax,dword ptr [ebp-]
0040D761 push eax
0040D762 mov ecx,dword ptr [ebp-]
0040D765 add ecx,dword ptr [ebp-]
0040D768 mov dword ptr [ebp-],ecx
0040D76B mov edx,dword ptr [ebp-]
0040D76E mov dword ptr [ebp-14h],edx
0040D771 mov eax,dword ptr [ebp-14h]
0040D774 push eax
0040D775 mov ecx,dword ptr [ebp-]
0040D778 push ecx
0040D779 push offset string "%d\t%d\t%d\n" (00422fdc)
0040D77E mov edx,dword ptr [ebp-]
0040D781 add edx,
0040D784 mov dword ptr [ebp-],edx
0040D787 call printf ()
0040D78C add esp,10h
: printf("%d\n",a);
0040D78F mov eax,dword ptr [ebp-]
0040D792 push eax
0040D793 push offset string "%c\n" (0042201c)
0040D798 call printf ()
0040D79D add esp,
: printf("a1+(a1++):\n");//
0040D7A0 push offset string "a1+(a1++):\n" (00422fd0)
0040D7A5 call printf ()
0040D7AA add esp,
: printf("%d\t%d\t%d\n",a1,a1+(a1++),a1);
0040D7AD mov ecx,dword ptr [ebp-]
0040D7B0 push ecx
0040D7B1 mov edx,dword ptr [ebp-]
0040D7B4 add edx,dword ptr [ebp-]
0040D7B7 mov dword ptr [ebp-18h],edx
0040D7BA mov eax,dword ptr [ebp-18h]
0040D7BD push eax
0040D7BE mov ecx,dword ptr [ebp-]
0040D7C1 push ecx
0040D7C2 push offset string "%d\t%d\t%d\n" (00422fdc)
0040D7C7 mov edx,dword ptr [ebp-]
0040D7CA add edx,
0040D7CD mov dword ptr [ebp-],edx
0040D7D0 call printf ()
0040D7D5 add esp,10h
: printf("%d\n",a1);
0040D7D8 mov eax,dword ptr [ebp-]
0040D7DB push eax
0040D7DC push offset string "%c\n" (0042201c)
0040D7E1 call printf ()
0040D7E6 add esp,
:
: printf("\n(2)前自加:\n");
0040D7E9 push offset string "%d\t%d\n" (00422fc0)
0040D7EE call printf ()
0040D7F3 add esp,
: printf("b+=(++b):\n");//
0040D7F6 push offset string "b+=(++b):\n" (00422fa8)
0040D7FB call printf ()
0040D800 add esp,
: printf("%d\t%d\t%d\n",b,b+=(++b),b);
0040D803 mov ecx,dword ptr [ebp-0Ch]
0040D806 push ecx
0040D807 mov edx,dword ptr [ebp-0Ch]
0040D80A add edx,
0040D80D mov dword ptr [ebp-0Ch],edx
0040D810 mov eax,dword ptr [ebp-0Ch]
0040D813 add eax,dword ptr [ebp-0Ch]
0040D816 mov dword ptr [ebp-0Ch],eax
0040D819 mov ecx,dword ptr [ebp-0Ch]
0040D81C push ecx
0040D81D mov edx,dword ptr [ebp-0Ch]
0040D820 push edx
0040D821 push offset string "%d\t%d\t%d\n" (00422fdc)
0040D826 call printf ()
0040D82B add esp,10h
: printf("%d\n",b);
0040D82E mov eax,dword ptr [ebp-0Ch]
0040D831 push eax
0040D832 push offset string "%c\n" (0042201c)
0040D837 call printf ()
0040D83C add esp,
: printf("b1+(++b1):\n");//
0040D83F push offset string "b1+(++b1):\n" (00422fb4)
0040D844 call printf ()
0040D849 add esp,
: printf("%d\t%d\t%d\n",b1,b1+(++b1),b1);
0040D84C mov ecx,dword ptr [ebp-10h]
0040D84F push ecx
0040D850 mov edx,dword ptr [ebp-10h]
0040D853 add edx,
0040D856 mov dword ptr [ebp-10h],edx
0040D859 mov eax,dword ptr [ebp-10h]
0040D85C add eax,dword ptr [ebp-10h]
0040D85F push eax
0040D860 mov ecx,dword ptr [ebp-10h]
0040D863 push ecx
0040D864 push offset string "%d\t%d\t%d\n" (00422fdc)
0040D869 call printf ()
0040D86E add esp,10h
: printf("%d\n",b1);
0040D871 mov edx,dword ptr [ebp-10h]
0040D874 push edx
0040D875 push offset string "%c\n" (0042201c)
0040D87A call printf ()
0040D87F add esp,
: return ;
0040D882 xor eax,eax
: }
【C】由printf("%d\t%d\t%d\n",a,a+=(a++),a);引起的思考的更多相关文章
- 由endl对printf和cout的思考
[前言]二者的区别就不介绍了.二者使用方法: printf("%s",a); cout<<a<<endl; endl的作用是什么? 一.endl作用 众所周 ...
- POJ 2455 - Secret Milking Machine
原题地址:http://poj.org/problem?id=2455 题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的 ...
- USACO Section 1.2 Name That Number 解题报告
题目 题目描述 在一个农场里面,每一头牛都有一个数字编号,但是现在这些牛不喜欢这种编号,它们想把这些数字编号转化成为可以接受的字母的形式.数字与字母的转换表如下: 2: A,B,C 5: J,K,L ...
- USACO2004 Open提交作业(区间DP)
Description 贝西在哞哞大学选修了C门课,她要把这些课的作业交给老师,然后去车站和同学们一 起回家.老师们在办公室里,办公室要等他们下课后才开,第i门课的办公室在Ti时刻后开放. 所有的办公 ...
- 20145232 韩文浩 《Java程序设计》第2周学习总结
教材学习内容总结 这周主要学习了注释的使用,运算符的基本使用,认识了类型,变量与常量,以及一些语句语法.复习了进制转换. 整数 Short整数占用2字节,储存整数范围-32768 ~ 32767(2- ...
- #C++初学记录(算法3)
C - 不要62 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司 ...
- POJ1716 贪心
题目大意:在[0,10000]上给出n个区间,要求在区间选整数点,每个区间至少包含两个点,问至少要几个点.题目保证有解决方案. 题目分析: 我们做过在区间上至少包含一个点的题目.类似的方法,我们先排序 ...
- C语言的一小步—————— 一些小项目及解析
——-------- 仅以此献给东半球第二优秀的C语言老师,黑锤李某鸽,希望总有那么一天我们的知识可以像他的丰臀一样渊博! bug跟蚊子的相似之处: 1.不知道藏在哪里. 2.不知道有多少. 3.总是 ...
- Codechef September Challenge 2019 Division 2
Preface 这确实应该是我打过的比较水的CC了(其实就打过两场) 但由于我太弱了打的都是Div2,所以会认为上一场更简单,其实上一场Div的数据结构是真的毒 好了废话不多说快速地讲一下 A Eas ...
随机推荐
- 重新认识一遍JavaScript - 2
1.JavaScript没有Java和C中的int.double,怎么识别这些类型的呢?或者说不支持 问:你认为呢? 答:var 支持所有数据类型(int.double.string),取决于你输入的 ...
- Solaris网络基础
划分子网: 把大网缩小为若干个小网.修改子网掩码,划分多个网络. 那么如何确定子网的子网掩码和IP地址? 以上你会发现少了6个IP. Ifconfig e1000g0 down down掉网卡 ...
- python(33)- 模块与包
一 模块 1 什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2 为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函 ...
- 网络通讯框架MINA和XSCOCKET的简单比较
http://www.blogjava.net/ghostdog/archive/2008/06/10/MinaVsXsocket.html实在无聊,考虑把当前应用的通讯模式由http移植为socke ...
- mysql性能优化-慢查询分析、优化索引和配置 MySQL索引介绍
MySQL索引介绍 聚集索引(Clustered Index)----叶子节点存放整行记录辅助索引(Secondary Index)----叶子节点存放row identifier-------Inn ...
- Excel应用----制作二级下拉菜单【转】
应用: 原始数据源是两列的源数据,那该如何制作二级下拉菜单, 当然可以将这两列的数据源,转换成上面的那种格式,再用上面的方法来制作. 今天教大学的方法是直接通过这种两列式的数据源来制作下拉菜单,如果A ...
- Android摄像头採集的视频数据流怎样通过Socket实时发送到目标服务端
分两块: 1.取得摄像头採集的视频流 2.发送到server端 protected MediaRecorder mMediaRecorder; private LocalServerSocket mL ...
- TIBCO RV
http://blog.csdn.net/tiercel2008/article/details/6799952
- 小贝_mysql主从复制作用以及案例
mysql主从复制 简要: 一.mysql用户授权 二.mysql bin-log日志 三.mysql主从复制 一.mysql用户授权 1.命令 2.作用:进行权限控制 3.样例: (备注: 同意 ...
- css-装饰
css -在标签上设置style样式 background-color:#2356a1 height:48px -编写样式方法 1.标签的style属性 2.鞋子head里面,style标签中编写 - ...