(高階)C函式呼叫

2021-08-29 10:26:30 字數 2363 閱讀 4078

筆者最近看《c與指標》這本書,發現了許多從前學習時沒有遇見的有趣問題。

最讓筆者震驚的是第五章5.8習題中第二題,讓筆者又從頭認真學習了一遍c語言的static變數。

剛開始,筆者用一向的慣性思維思考這個問題。

因此筆者自信地寫下了answer的值為 -2.

結果開啟vim 編輯之後,發現事情沒有這麼簡單。。。

是的,輸出的結果是 -10。 嗯??????

身為一位新時代的年輕人,不禁想問一句,「什麼鬼操作???」

不如吃茶去。。。

腦子一機靈,不如化簡?

不錯不錯,根據筆者的想法,將源**的主函式化為:

int answer;

int a = fun();

//printf("a %d\n", a);

int b = fun();

//printf("b %d\n", b);

//printf("mul %d\n", a*b);

answer= fun() - a * b;

printf("%d\n", answer);

vim 執行完之後結果,恰好是筆者寫的 -2 。當然,這個結果是完全錯誤的。。。

到底問題出在哪了呢?

那麼?答案不是 4-2*3 = -2 麼?不是,事情沒有那麼簡單。。。

繼續繼續,我們認真觀察這一天語句:

answer = fun() - fun() * fun() ;
必須要清楚的是,fun() 不是乙個變數,而是乙個返回值。fun() 函式位址是一定的,因此其實結果是 answer = 4 - 4*4 ,這樣結果就是 -10了麼。 是這樣麼???

想知道我們的推理是否正確,不如將 「-」 改為 「+」。

因此我們將源**這條語句改為:

answer = fun() + fun() * fun() ;
如果按照我們的推理,得到的結果應該是20 才對。

14??? 不按常量出牌啊老鐵。

證明我們的想法是完全錯誤的。。。

不過,我們已經將函式的返回值與變數值之間的關係區分開了。這時看到《c與指標》上的一段話:

什麼意思呢?

不如讓我們拋棄算數邏輯的先後順序。 從左向右執行下去。

這樣的話,我們再將得到的返回值進行邏輯運算。

answer = fun() - fun() * fun() ;

// 相當於 answer = 2 - 3 * 4 自然就是 -10

answer = fun() + fun() * fun();

// 相當於 answer = 2 + 3 * 4 自然就是 14

這樣我們就清楚了。

我們可以得到這麼一條結論:

當語句中存在函式時,會優先執行函式的操作,而後進行運算子的執行。

其實這麼說有些果斷,片面。 因為當了解資料結構中,運算的實現原理之後,就會明白為什麼筆者現在會這麼說。 大致來說,運算的實現是又兩個「棧」實現的,乙個「運算子儲存棧」,乙個「變數儲存棧」。關於這個問題的具體詳解,筆者後面會講到。

C 高階 C 函式呼叫過程深入分析

c 函式呼叫過程深入分析 0.引言 首先對三個常用的暫存器做一下說明,eip是指令指標,即指向下一條即將執行的指令的位址 ebp為基址指標,常用來指向棧底 esp為棧指標,常用來指向棧頂。看下面這個簡單的程式並在vc 6.0中檢視並分析彙編 1.函式呼叫 g func函式呼叫的彙編 如圖2 首先是三...

C 高階函式

函式式程式設計有很多優點,詳情可以參考我的博文 卡馬克 用c 進行函式式程式設計 在c 中,我們可以借助於函式物件或者函式指標來實現高階函式。高階函式是至少滿足下列乙個條件的函式 接受乙個或多個函式作為輸入 輸出乙個函式 公式 1 int sumint int a,int b for int i a...

(C )函式高階

include iostream using namespace std intfunc int a,int b 20,int c 30 1.如果某個位置已經有了預設引數,在這個引數之後都必須有預設引數 intfunc2 int a,int b 10,int c 10 b有預設引數,則c也需要有預設...