有趣的C語言--函式宣告和形參問題
阿新 • • 發佈:2019-01-04
1.舊式無參宣告
ANSI C是美國國家標準協會(ANSI)對C語言釋出的標準。使用C的軟體開發者被鼓勵遵循ANSI C文件的要求,因為它鼓勵使用跨平臺的程式碼。
在ANSI C規範之前,我們在宣告函式的時候只要宣告其返回型別,這樣就可能有如下問題產生:
#include<stdio.h>
int imax(); //舊式函式宣告,沒有引數
int main()
{
printf("The maximum of %d adn %d is %d. \n",3,5,imax(3));
printf("The maximum of %d and %d is %d . \n",3,5,imax(3.0,5.0));
return 0;
}
int imax(n,m)
{
int max;
if(n>m)
max=n;
else
max=m;
return max;
}
可能輸出如下:
The maximum of 3 adn 5 is 4273984.
The maximum of 3 and 5 is 1074266112.
由於作業系統的內部機制不同,上面的錯誤結果可能也不同。
第一個執行過程如下:
- 呼叫函式首先把引數放入堆疊臨時儲存
- 被呼叫函式從堆疊中讀取這些引數
- 被呼叫函式是根據其形參的型別進行資料讀取的。因此,函式呼叫imax(3)把一個整數放到堆疊中
- 當函式imax()執行時,會從堆疊中讀取兩個整數,但實際只有一個正確的整數在堆疊中,所以第二個資料是當時恰好在堆疊中的其它數這裡是4273984
第二個執行過程如下:
- 呼叫函式時,傳遞的是float型別,這會將兩個double型別的數值存放在堆疊中(float作為引數傳遞時會被轉成double型別)。這意味著兩個64位數值,也就是128位的資料被儲存在堆疊中。
- 因為int是32位,那麼imax()會從堆疊中讀取兩個int型別資料
2.解決方法
對於此的解決方案是在宣告函式的同時為其指定引數型別。
我們可以使用如下宣告:
int imax(int a,int b);
int imax(int,int);
使用這替代上面的聲明後,我們重新編譯程式,會發現第一種情況,也就是缺少引數的會提示錯誤資訊:傳遞引數過少。修改過後,再編譯,就能通過。
The maximum of 3 adn 5 is 5.
The maximum of 3 and 5 is 5.
這裡我們在使用imax(3.0,5.0)的時候,編譯沒有錯誤提示,但是會有警告,提示double型別被轉成int型別,這可能導致損失資料。
如
imax(3.9,5.4);
等價於
imax(3,5);
3.無參和不確定參
無參:int imax(void);
不確定引數:int imax(int b,…);