BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #49080同步于 2011/1/25
CPP机器人发帖

[合集] printf是一个神奇的函数,个人表示已经被征服,求大牛来

shenlei
2011/1/25镜像同步0 回复
☆─────────────────────────────────────☆ fentoyal (长风长歌) 于 (Fri Jan 21 01:05:21 2011) 提到: 测试环境vs2008 void test3() { int x[5]={10,25,30,40,50}; int *p=x; printf("%d\n%d\n%d\n",*p, (*p)++, *p++); } 结果:26 25 10 据此及其他非官方小道消息,我们有理由认为,printf果真是从右向左执行的。 再看一个: void test3() { int x[5]={10,25,30,40,50}; int *p=x; printf("%d\n%d\n%d\n",*p, *p++, (*p)++); } 猜猜这是啥结果?我猜是25,11,10 结果呢:我猜对了... HOWEVER~~当我做了个更简化的例子时: void test3() { int x[5]={10,25,30,40,50}; int *p=x; printf("%d\n%d\n%d\n",*p, *p++,*p); } 无非是删掉了那个 ++ 符号,我猜是25,10,10 但是结果是25,10, 25. 我一下不淡定了。。 无论是从左往右还是从右往左,都不该是这个结果啊,因为完全对称的嘛,莫非是先中间再两边??? 再来个: void test3() { int x[5]={10,25,30,40,50}; int *p=x; printf("%d\n%d\n%d\n%d\n",*p, *p++, *p++, *p); } 结果是30 25 10 30。。 果断从了.. 求大牛解 ☆─────────────────────────────────────☆ bupteinstein (相期以茶) 于 (Fri Jan 21 01:08:27 2011) 提到: C++没规定函数参数求值顺序,楼下的大牛回答。 ☆─────────────────────────────────────☆ coolfantasy (Cool) 于 (Fri Jan 21 08:29:09 2011) 提到: ☆─────────────────────────────────────☆ siwind (siwind) 于 (Fri Jan 21 09:11:46 2011) 提到: 编程原则: 不要把 ++, -- 和其它 表达式混合写在一行, 否则会有无穷多的类似问题! ☆─────────────────────────────────────☆ caprice (矩阵实验室) 于 (Fri Jan 21 09:18:09 2011) 提到: 这是一个“未定义”的求值顺序问题,C99标准里专门有一条讲的这个问题。还可以参考cert的C++安全编程规范第10条:https://www.securecoding.cert.org/confluence/display/seccode/EXP10-C.+Do+not+depend+on+the+order+of+evaluation+of+subexpressions+or+the+order+in+which+side+effects+take+place ☆─────────────────────────────────────☆ GTQ (『热情一顶乐团』团长|【回帖终结者A2】) 于 (Fri Jan 21 09:23:20 2011) 提到: 好久没用它了。。 【 在 fentoyal (长风长歌) 的大作中提到: 】 : 测试环境vs2008 : void test3() : { : ................... ☆─────────────────────────────────────☆ kissme (kissme) 于 (Fri Jan 21 09:30:55 2011) 提到: 大学里玩这些牛角尖, 可不要工作后连一个完整的APP都不会写啊。 ☆─────────────────────────────────────☆ lanphon (上善若水) 于 (Fri Jan 21 11:04:15 2011) 提到: 旁门左道而已 ☆─────────────────────────────────────☆ encoreway (Colin) 于 (Fri Jan 21 11:32:05 2011) 提到: 日,这儿都能撞见你。。。。 ☆─────────────────────────────────────☆ Bogdanfan (bogdan) 于 (Fri Jan 21 11:45:29 2011) 提到: printf是C的包袱 嗯 ☆─────────────────────────────────────☆ changzhu (猪哥梁) 于 (Fri Jan 21 11:52:03 2011) 提到: 这个问题,++优先算,之后从右往左算 ☆─────────────────────────────────────☆ guo (计忆邮心|郭) 于 (Fri Jan 21 12:27:02 2011) 提到: 研究這個 沒太大意義 ☆─────────────────────────────────────☆ renne (歼灭天使 玲) 于 (Fri Jan 21 13:03:52 2011) 提到: 这是非常不明白为啥总有人要研究未定义的行为 你这结果说不定换个编译器就不同了,何必呢 当然,也总有一些公司喜欢笔试出这种题目…… 【 在 fentoyal (长风长歌) 的大作中提到: 】 : 测试环境vs2008 : void test3() : { : ................... ☆─────────────────────────────────────☆ zebraSecond (享儿先先贝.tar.gz) 于 (Fri Jan 21 13:17:16 2011) 提到: 标准里未定义,是编译器的自定义行为,换个编译器或许结果就不同了 ☆─────────────────────────────────────☆ wks (cloverprince) 于 (Fri Jan 21 13:21:39 2011) 提到: 强烈建议xw大牛给论坛加个正则表达式,把i++ + ++i屏蔽了吧。 ☆─────────────────────────────────────☆ Wizmann (Wizmann) 于 (Fri Jan 21 16:19:46 2011) 提到: 个人觉得没用。。。- = ☆─────────────────────────────────────☆ vins (小蚊子-巛儿) 于 (Fri Jan 21 22:22:41 2011) 提到: 很有意思··恩·· ☆─────────────────────────────────────☆ W27 (fdsakfds) 于 (Fri Jan 21 22:24:35 2011) 提到: 应该和side effect有关 ☆─────────────────────────────────────☆ czzc829z (zzz不厌其睡) 于 (Fri Jan 21 23:41:49 2011) 提到: 虽然一年没用C++了,不过还是能满足你的愿望 如下: 第一优先准则是计算++ 这是C++的++体现的地方(开玩笑的^_^),有++的地方先执行 第二优先准则是程序译码原理: 译码是由右往左译的,貌似所有编译器都是那样 printf("%d\n%d\n%d\n%d\n",*p, *p++, *p++, *p); 优先执行++,然后从右开始,所以第一句执行的是第三位置的*p++ 优先执行++,所以第二句执行的是第二位置的*p++ 类似了后面 另外也就是因为++优先级是奇高,所以*p++ = *(p++) 这就不用我说了吧,和printf就没关系 最后顺带鄙视一下C++ 搞工程都是MATLAB,效率不给力时候也是联合搞C C++就是沦落为纯做软件,GUI的时候才给力 也不知道老师们都想什么,通信上来C++ 亏我还各种卖力,结果发现现在就不用了。。 而且用MATLAB后,才感觉到神马是高级语言,囧 ☆─────────────────────────────────────☆ zhaoyu1999 (麦圈流光) 于 (Sat Jan 22 00:03:31 2011) 提到: 所谓术业有专攻…… 个人还是挺喜欢C++的 【 在 czzc829z 的大作中提到: 】 : 虽然一年没用C++了,不过还是能满足你的愿望 : 如下: : 第一优先准则是计算++ : ................... ☆─────────────────────────────────────☆ math (3664.2436498) 于 (Sat Jan 22 10:52:58 2011) 提到: MSC的编译器确实比较诡异,gcc的理解就和lz是一样的 可变形参的实现是通过堆栈来完成的,函数在堆栈里去拿数据,不过根据了不同的机器做了一些偏移 贴一下libc里面printf的实现 int printf(const char *format, ...) { va_list ap; int retval; va_start(ap, format); retval = _doprnt(format, ap, stdout); va_end(ap); return retval; } typedef char * va_list; #define _INTSIZEOF(n) \ //n 为 char * ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //这个值为4 (32bit机器) #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //偏移4bytes #define va_end(ap) ( ap = (va_list)0 ) *p++在有些编译器实现的时候很可能额外开栈,从而导致最后一个参数(实际上第一个传递)和看到的不同,实际上完成的是两个动作: q=*p; p=p+1; 因此编译器拿数据取值的时候就不一致了,可变形参的这种问题不同编译器处理是不一样的。 【 在 fentoyal 的大作中提到: 】 : 测试环境vs2008 : void test3() : { : ................... ☆─────────────────────────────────────☆ math (3664.2436498) 于 (Sat Jan 22 11:13:26 2011) 提到: 【 在 czzc829z 的大作中提到: 】 虽然一年没用C++了,不过还是能满足你的愿望 如下: 第一优先准则是计算++ 这是C++的++体现的地方(开玩笑的^_^),有++的地方先执行 ~~~~~~~~~~~~~~~ C++的++是这个意思吗? 第二优先准则是程序译码原理: 译码是由右往左译的,貌似所有编译器都是那样 printf("%d\n%d\n%d\n%d\n",*p, *p++, *p++, *p); 优先执行++,然后从右开始,所以第一句执行的是第三位置的*p++ ~~~~~~~~~~是优先执行++吗?*p++的p在被*取完值后才被累加 优先执行++,所以第二句执行的是第二位置的*p++ 类似了后面 另外也就是因为++优先级是奇高,所以*p++ = *(p++) ~~~~~~~~~~~~~~ ++操作的优先奇高吗?高得过下标和成员操作符吗? 这就不用我说了吧,和printf就没关系 ~~~~~~~~~~~~~~~ 这个问题和可变形参有关系。 最后顺带鄙视一下C++ ~~~~~~~~~~~~~~~~~~~ 语言不应该有高低之分,只有具体应用才会选择合适的语言 搞工程都是MATLAB,效率不给力时候也是联合搞C ~~~~~~~~~~~~~~~~ 不知道你走出校园了吗?搞工程用matlab才是少数 C++就是沦落为纯做软件,GUI的时候才给力 ~~~~~~~~~~~~~~~~~~在google中,大多数的系统是用C++写的,系统架构用C++更为合适,就算做软件的用得着用沦落这个词汇吗 也不知道老师们都想什么,通信上来C++ ~~~~~~~~~~~~~通信领域很多系统都是用C++写,你不会比你的老师更有经验 亏我还各种卖力,结果发现现在就不用了。。 而且用MATLAB后,才感觉到神马是高级语言,囧 ~~~~~~~~~~~~~会高级语言值得崇拜吗?MATLAB易用,门槛不高 ☆─────────────────────────────────────☆ czzc829z (zzz不厌其睡) 于 (Sat Jan 22 11:55:11 2011) 提到: ~~~~~~~~~~~~~~~ C++的++是这个意思吗? !都说了开玩笑的 ~~~~~~~~~~是优先执行++吗?*p++的p在被*取完值后才被累加 !当然先执行++, p++的返回值是p,然后取地址*,符号优先级是更高吧 ~~~~~~~~~~~~~~ ++操作的优先奇高吗?高得过下标和成员操作符吗? ! 我只是说在printf里的奇怪顺序,联系C++的名字开个玩笑,只是经验准则 ! printf("%d\n%d\n%d\n%d\n",*p, *p++, *p++, *p); ! 首先执行第三个*p++,*p++的值=*(p++),p++返回p ! 所以*p++的返回值等价于*p,然后z指针指向25 ! 所以显示由? ? ? ? -> ? ? 10 ? (?表示未知) ! 然后执行第二个*p++,*p++的值=*(p++),p++返回p ! 所以*p++的返回值等价于*p,当前指针指向25,所以返回25,指针指向30 ! 这个时候显示值就是 ? 25 10 ? ! 然后在执行2个*p,也就是30了 ! 所以显示由? 25 10 ? -> 30 25 10 30 ! 另外,从楼上贴出的PRINTF的核来看,确实是printf自己的问题 ! 楼上说的对,确实应该是编译器的问题, ! ++准则只是实际的一个使用准则,到底怎么回事显然是要看LIB的 ! 但是我记得似乎很多函数都有这样的问题,++准则一直都有用 ! 可能是我记错了~建议楼主多找几个其他函数实验一下 ! 我对C++的研究没楼上那么深入 ~~~~~~~~~~~~~~~~ 不知道你走出校园了吗?搞工程用matlab才是少数 ! 既然有语言C++那自然有给力的地方,这我不否认,但我确实不太接触 ! 我一点也不否认在做构架时候C++的牛X性,但是我不做那东西却要学这语言 ! 我一直觉得学C或者JAVA会更为给力些,但愿老师是对的,希望有学长现身说法 ! (现在有一种让楼上多学点马列毛邓的想法了,老师要求学的) ! 我知道您走出校园了,天天用C++计算仿真各种信道?看来我寡闻了 ~~~~~~~~~~~~~会高级语言值得崇拜吗?MATLAB易用,门槛不高 ! 我只希望语言能发展到说话一样简单,额外工具箱都有做好的封装 ! 我一直觉得越高级语言越简单才是,如果你非说汇编给力那也是事实 ☆─────────────────────────────────────☆ kearnel (专业路过帝) 于 (Sat Jan 22 13:11:14 2011) 提到: 【 在 czzc829z 的大作中提到: 】 : ~~~~~~~~~~~~~~~ C++的++是这个意思吗? : !都说了开玩笑的 : ~~~~~~~~~~是优先执行++吗?*p++的p在被*取完值后才被累加 : ................... 本来想反驳一下你,但是为了避装逼的风头,不解释了。 ☆─────────────────────────────────────☆ jmpesp (心爱走天涯 ) 于 (Sat Jan 22 14:53:54 2011) 提到: 围观ing... ☆─────────────────────────────────────☆ math (3664.2436498) 于 (Sat Jan 22 15:35:40 2011) 提到: 现在北邮的学生怎么变成这么浮躁了?都说不得的哦,难道是我落伍了? ☆─────────────────────────────────────☆ haozhy (moonstreet) 于 (Sat Jan 22 16:49:30 2011) 提到: ☆─────────────────────────────────────☆ math (3664.2436498) 于 (Sat Jan 22 17:38:52 2011) 提到: sorry,我不该打倒一片,和其他人无关。我话是说冲了点,别搞得最后全体byr来攻击我,要真这样的话,我消失得了。老校友了,这是我的主号,不是马甲,03年在论坛就注册了ID,现在早没了,这才注册了一个math。真看不惯那哥们的回帖,整个论坛也没人出来拍两句。我还没怎么动嘴呢,就扯到马列上去了。 ☆─────────────────────────────────────☆ bupteinstein (相期以茶) 于 (Sun Jan 23 13:46:51 2011) 提到: 咋又打起来了呢? ☆─────────────────────────────────────☆ frwjxwx (fr) 于 (Mon Jan 24 10:58:26 2011) 提到: printf是从右至左执行的 ☆─────────────────────────────────────☆ jokerlee (Jackal The Dire) 于 (Mon Jan 24 23:52:21 2011) 提到: 自己看汇编 丰衣足食 ☆─────────────────────────────────────☆ fentoyal (长风长歌) 于 (Tue Jan 25 08:51:22 2011) 提到: 结个帖 1.关于主题: 其实第一页caprice一个简单的side effect链接其实就已经解决这个问题了。继续爬楼纯属围观... 2.关于钻牛角尖:纯属个人爱好,喜欢瞎琢磨。不为考试不为工作,就是觉着好奇。 3.至于这位czzc829z同学的话,不太中听,你真的“满足”了我的拍人欲。C++真的是很好的以工具,若是硬拿java或c和它比,咱们还能讨论讨论优劣,这位直接搬出来了Matlab...肯定不是cs专业的啊,估计平时只是用c++做算术的。不过不但编程!=做算术 ,而且编程>>做算术。 你matlab能做的,我c++都能做...c++能做的。。c++能做google,能做microsoft,你可以用matlab编个windows么?当然你要硬觉着编windows这软件是“沦落的”人干的,我也不介意,bill gates是挺沦落哈。就退一万步说,c++能做出matlab,matlab能做个c++么?最后,提醒一下这位同学,printf是lz认为那个有资格和matlab平起平坐的c的,不是俺们c++的,我们都用std::cout. ☆─────────────────────────────────────☆ RaulSpain007 (Raul) 于 (Tue Jan 25 10:36:35 2011) 提到: 语法有二义性编译器自己规定了优先级吧 ☆─────────────────────────────────────☆ encoreway (Colin) 于 (Tue Jan 25 12:39:31 2011) 提到: 好好的楼怎么吵起来了... ☆─────────────────────────────────────☆ ayu (心中的流氓) 于 (Tue Jan 25 13:02:10 2011) 提到: 【 在 fentoyal 的大作中提到: 】 : 结个帖 : 1.关于主题: 其实第一页caprice一个简单的side effect链接其实就已经解决这个问题了。继续爬楼纯属围观... : 2.关于钻牛角尖:纯属个人爱好,喜欢瞎琢磨。不为考试不为工作,就是觉着好奇。 : ................... ...这话说的,matlab在cs领域用的也不少吧。 ☆─────────────────────────────────────☆ fentoyal (长风长歌) 于 (Tue Jan 25 13:24:41 2011) 提到: 【 在 ayu 的大作中提到: 】 : : 【 在 fentoyal 的大作中提到: 】 : : 结个帖 : ................... 我的话对人不对事,matlab其实挺好
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。