写给初学者的有关printf("%d,%d,%d,%d\n", ++a,a++,--aa--);之类的表述

traceless 2010-01-18 08:33:58
论坛里经常会出现类似的提问:
int a=5;
printf("%d,%d,%d,%d",++a,a++,--a,a--);
为啥不是。。。为啥不是。。。而是。。。

有些初学者更是模糊,因为他们通过编译器编译得到的结果居然和论坛上有的结果不一样,和他们的预期也不一样。

1 > 这种题确实和编译器相关。有些人试图从得到的汇编来说,不要忘了汇编的代码也是经过编译器的编译逻辑决定的。经测试:上面的两行代码,vs2008 和 gcc得到是不一样的。gcc得到的结果与根据规则目测得到的结果一致。

那是不是根据这点就说明vs2008的编译器的实现不按照语法规则来编写 ?

2 > 不是。编译器是根据语法规则来实现的,只不过它还有“容错”和优化等功能,它考虑的问题比我们考虑到的还多。编译器、操作系统和搜索引擎号称最复杂的三大软件。虽然你有时写的代码有错误,但是依然得到预期的结果,像这种帖子也不少,“经典”之一的题目就是在函数里返回字符数组变量还是字符指针,有些编译器居然也给出预期结果。编译器确实很强大,你写的代码有缺陷,居然也会得到想要的结果。

但我们更强调的是规范:语法、实现和代码上的规范。

3 > 对于这种题型,我们都曾经不可避免遇到过。对于初学者,我建议不必要过多的纠结在这上面,特别是++i= ++i++i--之类的。你只要知道前缀和后缀的含义就行,前缀是先对变量自增再执行整个表达式,后缀是先执行表达式完了之后再执行变量的自增。而对于帖中的代码,你能答到函数的压栈顺序和自增自减的过程就可以了。
如果你想确定执行顺序和如果是按照规则来的话,可以用以下类似的方法:
记住千万不要拿反汇编得到的汇编来说事,汇编的代码也是经过编译器的编译译逻辑决定的,经过优化了的。
__inline int Geta(int *pa, int i);

int main()
{
int a = 5;
//printf("%d,%d,%d,%d\n", ++a, a++, --a, a--);
//这样就避免了优化,每次都是重新获取变量a的值,而且也确定了先后顺序。
printf("\n%d,%d,%d,%d\n", Geta(&a, 1), Geta(&a, 2), Geta(&a, 3), Geta(&a, 4));
return 0;
}

__inline int Geta(int *pa, int i)
{
switch (i)
{
case 4: printf("4th\n"); return (*pa)--;
case 3: printf("3th\n"); return --(*pa);
case 2: printf("2th\n"); return (*pa)++;
case 1: printf("1th\n"); return ++(*pa);
}
return 0;
}


以上只是对初学者或新学者的一点点建议,如有不妥之处,请海涵
...全文
2932 51 打赏 收藏 转发到动态 举报
写回复
用AI写文章
51 条回复
切换为时间正序
请发表友善的回复…
发表回复
loijianming 2010-12-14
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 bicky6121 的回复:]

__inline int Geta(int *pa, int i)
这句中的“_inline”是什么意思?不懂……
[/Quote]



内联函数,属于C++
lsf5921 2010-01-21
  • 打赏
  • 举报
回复
Thanks
camelisi 2010-01-20
  • 打赏
  • 举报
回复
勤奋的好人
go_Michael 2010-01-20
  • 打赏
  • 举报
回复
mark
yyg0303 2010-01-20
  • 打赏
  • 举报
回复
嗯,挺不错的。支持
tan870426 2010-01-20
  • 打赏
  • 举报
回复
fortuneboy 2010-01-20
  • 打赏
  • 举报
回复
写的多了这些东西就知道了
imwyw 2010-01-20
  • 打赏
  • 举报
回复
过来学学
xiaolangajun 2010-01-19
  • 打赏
  • 举报
回复
楼主很好,有多点这样的大虾出来指点下,我们这些初学者就少走点弯路咯~
bicky6121 2010-01-19
  • 打赏
  • 举报
回复
__inline int Geta(int *pa, int i)
这句中的“_inline”是什么意思?不懂……
godismydaughter 2010-01-19
  • 打赏
  • 举报
回复
up
DLevel 2010-01-19
  • 打赏
  • 举报
回复
++连起来用的都属于缺。。
一方小四 2010-01-19
  • 打赏
  • 举报
回复
这种是递归吗?

什么时候结束?

现在才发现,自己这么水啊。。。
Pepeet 2010-01-19
  • 打赏
  • 举报
回复
jf
不知名小ITer 2010-01-19
  • 打赏
  • 举报
回复
支持下..好像只要说句和编译器相关就行了啊...^_^
Pallbearer521 2010-01-19
  • 打赏
  • 举报
回复
pengzhixi 2010-01-19
  • 打赏
  • 举报
回复
这类问题只要想到求值顺序不确定的话,就没有什么兴趣研究了。每次碰到这问题,就有人拿汇编代码说事,我不知道是要证明一个什么。
某某9 2010-01-19
  • 打赏
  • 举报
回复
哦 理解了
love87less 2010-01-19
  • 打赏
  • 举报
回复
来拿分的。。。
TORSA 2010-01-19
  • 打赏
  • 举报
回复
想想自己当年也花很多时间来浪费。。。
加载更多回复(32)
【采用BPSK或GMSK的Turbo码】MSK、GMSK调制二比特差分解调、turbo+BPSK、turbo+GMSK研究(Matlab代码实现)【采用BPSK或GMSK的Turbo码】MSK、GMS内容概要:本文主要介绍了采用BPSK或GMSK调制方式的Turbo码相关技术研究,重点涵盖GMSK调制下的二比特差分解调方法、Turbo码与BPSK/GMSK调制相结合的系统性能分析,并提供了完整的Matlab代码实现方案。研究内容包括调制解调原理、编码结构设计、误码率仿真及系统优化等关键环节,旨在通过仿真手段验证所提出方案的有效性和可靠性,帮助研究人员深入理解现代数字通信系统中的关键技术和其实现方法。; 适合人群:具备一定通信原理和Matlab编程基础,从事无线通信、信号处理、编码理论等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握GMSK调制与Turbo码结合的系统设计与仿真方法;②学习二比特差分解调算法在实际通信系统中的应用;③通过Matlab代码实现提升对数字调制解调和信道编码技术的理解与实践能力;④为相关课题研究、毕业设计或工程项目提供参考和技术支持。; 阅读建议:建议读者结合文中提供的Matlab代码逐模块运行与调试,对照通信系统基本原理深入理解各环节功能,重点关注调制解调过程与Turbo译码的协同工作机制,并尝试修改参数以观察系统性能变化,从而达到理论与实践相结合的学习效果。

70,039

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧