#include <stdio.h>
int f(int, int, int)
{
return 0;
}
int main()
{
return f(printf("a"), printf("b"), printf("c"));
}
这是今天晚上遇到的腾讯在线笔试题目,问题是 “代码结果是什么?”
这道题目结果是 cba 吗?为什么?
PHPz2017-04-17 14:37:40
拿這種未定義行為出題的騰訊也是夠了。建議回答「這個結果是不是cba並不重要,重要的是日常工作中不要寫出這樣的程式碼-- 盡量不要一行程式碼中寫太多函數調用,除非是鍊式調用;對於有副作用的函數調用那必須要分開成多行來寫。
高洛峰2017-04-17 14:37:40
大部分的呼叫約定是從右向左入棧,即最右邊的參數最先入棧,比如f(a, b, c),那麼最先入棧的就c,其次是b,最後是a 。具體到那你這裡,首先入棧的是printf("c")的回傳值,那麼這裡就會先對printf("c")進行一個呼叫。因此這段程式碼的函數呼叫順序最終為printf("c"), printf("b"),printf("a"),f(1,1,1)。所以程式碼結果是cba。
阿神2017-04-17 14:37:40
C語言預設的Calling Convention是cdecl,也就是從右向左壓棧。但是參數表求值順序是未定義行為,函數參數表中的逗號並不是序列點。 debug版的msvc和x86的gcc似乎都是從右到左求值的,但是據我所知Sparc上好像就是反過來的。至於優化過的release版則更無法確定了。
ringa_lee2017-04-17 14:37:40
考得就是參數入棧方向,答案就是cba,上面解釋的很好了。
想說的是,我記得騰訊筆試題前面是有針對考題的保密協議的,追求技術問題的答案並沒有錯,但題主也要遵循你同意過的協議。