腾讯笔试题 printf

at8897253
  • 37
#include <stdio.h>

int f(int, int, int)
{
    return 0;
}

int main()
{
    return f(printf("a"), printf("b"), printf("c"));


}

这是今天晚上遇到的腾讯在线笔试题目,问题是 “代码结果是什么?”
这道题目结果是 cba 吗?为什么?

回复
阅读 6k
6 个回答

拿这种未定义行为出题的腾讯也是够了。建议回答“这个结果是不是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,因为调用约定多为从右向左穿参,出题者很可能误解为求值顺序也是如此

极风
  • 0
新手上路,请多包涵

但是main函数里面返回的是f函数,而f函数的返回值是0,那么main函数返回值为什么不是0呢?

宣传栏