C++ 返回值

2023-03-20 15:51 更新

前面我們用過的一些內置函數(如數學函數)都會生成結果值。也就是說,調用函數的效果是產生一個新值,一般我們會把這個值賦給變量,或用作表達式的一部分。例如:

double e = exp(1.0);
double height = radius * sin(angle);

但到目前為止,我們編寫的所有函數都是void函數,它們不返回任何值。調用void函數時,常見的是函數調用語句本身占一行,沒有賦值操作:

nLines(3);
countdown(n-1);

本章我們將學習編寫帶有返回值的函數,因為沒有更好的名字,我索性直接稱之為“有返回值的函數”。第一個例子是area函數,它以一個double值為參數,返回以給定參數值為半徑的圓的面積:

double area(double radius) {
  double pi = acos(-1.0);
  double area = pi * radius * radius;
  return area;
}

首先要注意到,該函數定義的開始部分與void函數(如果以“void”開始,則說明這是void函數)不同,這里使用了double,說明函數返回double類型的值。

再就是注意最后一行,這是return語句的一種可選形式,它帶了一個返回值。這句話的意思是,”以其后的表達式為返回值,立即從函數返回?!氨磉_式可以非常復雜,所以area函數可以簡化為:

double area(double radius) {
  return acos(-1.0) * radius * radius;
}

另一方面,像area這樣的臨時變量會使調試更容易。不管哪種情況,return語句中表達式的類型必須與函數的返回類型匹配。換句話說,當把函數的返回類型聲明為double時,就要保證函數最終會得到一個double值。如果不返回任何表達式,或者返回了類型不匹配的表達式,編譯器都會報錯。

有時包含多個返回語句是有用的,比如每個分支一個:

double absoluteValue(double x){
  if (x < 0) {
    return -x;
  } else {
    reurn x;
  }
}

這些return語句分布在不同的條件分支中,只有一個能執(zhí)行。雖然函數可以有多個return語句,但是只要其中一個執(zhí)行,函數也就隨之結束了,不會再執(zhí)行后面的語句。

return語句后面的代碼,或任何不可能執(zhí)行到的代碼,稱為“死代碼”。如果存在死代碼,有的編譯器會給出警告。

如果return語句在一個條件分支中,必須保證每個可能的路徑都能碰到return語句。例如:

double absoluteValue(double x) {
  if(x < 0) {
    return –x;
  } else if(x > 0) {
    return x;
  }            // 錯誤
}

這個函數是錯誤的,因為當x為0的時候,所有條件都不滿足,最終函數找不到相應的return語句。非常不幸,很多C++編譯器并不捕捉此類錯誤,程序可以通過編譯并運行,但是當x==0時返回值可能是任意值,而且在不同環(huán)境下也可能有不同表現。

現在你可能還是很討厭看到編譯錯誤信息,但是隨著經驗的增長,你會意識到:當程序有錯誤時,不出現編譯錯誤會比出現更糟糕。

有時會有這樣的事情,你用一些值測試了absoluteValue函數,而且該函數看起來是可以正常工作的,可是當你把程序交給別人在其他環(huán)境下測試時,卻出現了不可思議的bug,經過幾天的調試你才發(fā)現absoluteValue的實現有問題。要是編譯器能早發(fā)現問題并警告你該多好啊!

從現在開始,如果編譯器指出了程序中的錯誤,請不要抱怨編譯器。相反,你應該感謝編譯器幫你找出錯誤,而且節(jié)約了你數天的調試時間。有的編譯器可以通過選項指定更嚴格的編譯檢查并報告所有錯誤。你要一直開著這些選項。

說句題外話,math庫中的fabs函數能夠正確計算double變量的絕對值。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號