84669 personnes étudient
152542 personnes étudient
20005 personnes étudient
5487 personnes étudient
7821 personnes étudient
359900 personnes étudient
3350 personnes étudient
180660 personnes étudient
48569 personnes étudient
18603 personnes étudient
40936 personnes étudient
1549 personnes étudient
1183 personnes étudient
32909 personnes étudient
#include <stdio.h> int f(int, int, int) { return 0; } int main() { return f(printf("a"), printf("b"), printf("c")); }
这是今天晚上遇到的腾讯在线笔试题目,问题是 “代码结果是什么?”这道题目结果是 cba 吗?为什么?
业精于勤,荒于嬉;行成于思,毁于随。
拿这种未定义行为出题的腾讯也是够了。建议回答“这个结果是不是cba并不重要,重要的是日常工作中不要写出这样的代码 -- 尽量不要一行代码中写太多函数调用,除非是链式调用;对于有副作用的函数调用那必须要分开成多行来写。”
大部分的调用约定是从右向左入栈,即最右边的参数最先入栈,比如f(a, b, c),那么最先入栈的就c,其次是b,最后是a。具体到那你这里,首先入栈的是printf("c")的返回值,那么这里就会先对printf("c")进行一个调用。因此这段代码的函数调用顺序最终为printf("c"), printf("b"),printf("a"),f(1,1,1)。所以代码结果是cba。
C语言默认的Calling Convention是cdecl,也就是从右向左压栈。但是参数表求值顺序是未定义行为,函数参数表中的逗号并不是序列点。debug版的msvc和x86的gcc貌似都是从右到左求值的,但是据我所知Sparc上好像就是反过来的。至于优化过的release版则更无法确定了。
考得就是参数入栈方向,答案就是cba,上面解释的很好了。想说的是,我记得腾讯笔试题前面是有针对考题的保密协议的,追求技术问题的答案并没有错,但题主也要遵循你同意过的协议。
传参顺序不等于求值顺序,也就是说这道题目应该是错的,但是如果选的话建议选cba,因为调用约定多为从右向左穿参,出题者很可能误解为求值顺序也是如此
但是main函数里面返回的是f函数,而f函数的返回值是0,那么main函数返回值为什么不是0呢?
拿这种未定义行为出题的腾讯也是够了。建议回答“这个结果是不是cba并不重要,重要的是日常工作中不要写出这样的代码 -- 尽量不要一行代码中写太多函数调用,除非是链式调用;对于有副作用的函数调用那必须要分开成多行来写。”
大部分的调用约定是从右向左入栈,即最右边的参数最先入栈,比如f(a, b, c),那么最先入栈的就c,其次是b,最后是a。具体到那你这里,首先入栈的是printf("c")的返回值,那么这里就会先对printf("c")进行一个调用。因此这段代码的函数调用顺序最终为printf("c"), printf("b"),printf("a"),f(1,1,1)。所以代码结果是cba。
C语言默认的Calling Convention是cdecl,也就是从右向左压栈。但是参数表求值顺序是未定义行为,函数参数表中的逗号并不是序列点。debug版的msvc和x86的gcc貌似都是从右到左求值的,但是据我所知Sparc上好像就是反过来的。至于优化过的release版则更无法确定了。
考得就是参数入栈方向,答案就是cba,上面解释的很好了。
想说的是,我记得腾讯笔试题前面是有针对考题的保密协议的,追求技术问题的答案并没有错,但题主也要遵循你同意过的协议。
传参顺序不等于求值顺序,也就是说这道题目应该是错的,但是如果选的话建议选cba,因为调用约定多为从右向左穿参,出题者很可能误解为求值顺序也是如此
但是main函数里面返回的是f函数,而f函数的返回值是0,那么main函数返回值为什么不是0呢?