写给初学者的有关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;
}


以上只是对初学者或新学者的一点点建议,如有不妥之处,请海涵
...全文
2414 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)

69,370

社区成员

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

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