天天看點

C++ 控制結構和函數(二) —— 函數I(Functions I)

通過使用函數(functions)我們可以把我們的程式以更子產品化的形式組織起來,進而利用C++所能提供的所有結構化程式設計的潛力。

一個函數(function)是一個可以從程式其它地方調用執行的語句塊。以下是它的格式:

type name ( argument1, argument2, ...) statement

這裡:

  • type 是函數傳回的資料的類型
  • name 是函數被調用時使用的名
  • argument 是函數調用需要傳入的參量(可以聲明任意多個參量)。每個參量(argument)由一個資料類型後面跟一個辨別名稱組成,就像變量聲明中一樣(例如,int x)。參量僅在函數範圍内有效,可以和函數中的其它變量一樣使用, 它們使得函數在被調用時可以傳入參數,不同的參數用逗号(comma)隔開.
  • statement 是函數的内容。它可以是一句指令,也可以是一組指令組成的語句塊。如果是一組指令,則語句塊必須用花括号{}括起來,這也是我們最常見到情況。其實為了使程式的格式更加統一清晰,建議在僅有一條指令的時候也使用花括号,這是一個良好的程式設計習慣。

下面看一下第一個函數的例子:

// function example

#include <iostream.h>

int addition (int a, int b)

{

    int r;

    r=a+b;

    return (r);

}

int main ()

{

    int z;

    z = addition (5,3);

    cout << "The result is " << z;

    return 0;

}

The result is 8

記得在我們教程開始時說過:一個C++程式總是從main函數開始執行。 是以我們從那裡開始。

我們可以看到 main 函數以定義一個整型變量z 開始。緊跟着我們看到調用addition 函數。我們可以看到函數調用的寫法和上面函數定義本身十分相似:

C++ 控制結構和函數(二) —— 函數I(Functions I)

參數有明顯的對應關系。在main 函數中我們調用addition 函數,并傳入兩個數值: 5 和3 , 它們對應函數addition 中定義的參數int a 和int b。

當函數在main 中被調用時,程式執行的控制權從main轉移到函數addition。調用傳遞的兩個參數的數值 (5 和3) 被複制到函數的本地變量(local variables) int a 和int b 中。

函數addition 中定義了新的變量(int r;),通過表達式r=a+b;, 它把a 加b 的結果賦給r 。因為傳過來的參數a 和b 的值分别為5 和3 ,是以結果是8。

下面一行代碼:

return (r);

結束函數addition,并把控制權交還給調用它的函數(main) ,從調用addition的地方開始繼續向下執行。另外,return 在調用的時候後面跟着變量r (return (r);), 它當時的值為8, 這個值被稱為函數的傳回值。

C++ 控制結構和函數(二) —— 函數I(Functions I)

函數傳回的數值就是函數的計算結果,是以, z 将存儲函數addition (5, 3)傳回的數值, 即8。用另一種方式解釋,你也可以想象成調用函數(addition (5,3)) 被替換成了它的傳回值 (8)。

接下來main中的下一行代碼是:

cout << "The result is " << z;

它把結果列印在螢幕上。

C++ 控制結構和函數(二) —— 函數I(Functions I)

變量的範圍(Scope of variables)

你必須考慮到變量的範圍隻是在定義該變量的函數或指令塊内有效,而不能在它的函數或指令塊之外使用。 例如,在上面的例子裡就不可能在main 中直接使用變量a, b 或 r ,因為它們是函數addition的本地變量(local variable)。在函數addition中也不可能直接使用變量z,因為它是main的本地變量。

是以,本地變量 (local variables)的範圍是局限于聲明它的嵌套範圍之内的。盡管如此,你還可以定義全局變量(global variables),它們可以在代碼的任何位置被通路,不管在函數以内還是以外。要定義全局變量,你必須在所有函數或代碼塊之外定義它們,也就是說,直接在程式體中聲明它們。

這裡是另一個關于函數的例子:

// function example

#include <iostream.h>

int subtraction (int a, int b)

{

    int r;

    r=a-b;

    return (r);

}

int main ()

{

    int x=5, y=3, z;

    z = subtraction (7,2);

    cout << "The first result is " << z << '\n';

    cout << "The second result is " << subtraction (7,2) << '\n';

    cout << "The third result is " << subtraction (x,y) << '\n';

    z= 4 + subtraction (x,y);

    cout << "The fourth result is " << z << '\n';

    return 0;

}

The first result is 5

The second result is 5

The third result is 2

The fourth result is 6

在這個例子中,我們定義了函數subtraction。這個函數的功能是計算傳入的兩個參數的內插補點并将結果傳回。

在 main 函數中,函數subtraction被調用了多次。我們用了幾種不同的調用方法,是以你可以看到在不同的情況下函數如何被調用。

為了更好的了解這些例子,你需要考慮到被調用的函數其實完全可以由它所傳回的值來代替。例如在上面例子中第一種情況下 (這種調用你應該已經知道了,因為我們在前面的例子中已經用過這種形式的調用):

z = subtraction (7,2);

cout << "The first result is " << z;

如果我們把函數調用用它的結果(也就是5)替換,我們将得到:

z = 5;

cout << "The first result is " << z;

同樣的

cout << "The second result is " << subtraction (7,2);

與前面的調用有同樣的結果,但在這裡我們把對函數subtraction 的調用直接用作cout的參數。這可以簡單想象成我們寫的是:

cout << "The second result is " << 5;

因為5 是subtraction (7,2)的結果。

cout << "The third result is " << subtraction (x,y);

中,與前面的調用唯一的不同之處是這裡調用subtraction 時的參數使用的是變量而不是常量。這樣用時毫無問題的。在這個例子裡,傳入函數subtraction 的參數值是變量x 和y中存儲的數值,即分别為5 和3,結果為2。

第四種調用也是一樣的。隻要知道除了

z = 4 + subtraction (x,y);

我們也可以寫成:

z = subtraction (x,y) + 4;

它們的結果是完全一樣的。注意在整個表達式的結尾寫上分号semicolon sign (;)。它并不需要總是跟在函數調用的後面,因為你可以有一次把它們想象成函數被它的結果所替代:

z = 4 + 2; z = 2 + 4;

沒有傳回值類型的函數,使用void.

如果你記得函數聲明的格式:

type name ( argument1, argument2 ...) statement

就會知道函數聲明必須以一個資料類型(type)開頭,它是函數由return 語句所傳回資料類型。但是如果我們并不打算傳回任何資料那該怎麼辦呢?

假設我們要寫一個函數,它的功能是列印在螢幕上列印一些資訊。我們不需要它傳回任何值,而且我們也不需要它接受任何參數。C語言為這些情況設計了void 類型。讓我們看一下下面的例子:

// void 函數示例
#include <iostream>
using namespace std;

void printmessage ()
{
  cout << "I'm a function!";
}

int main ()
{
  printmessage ();
  return 0;
}
      
I'm a function!

void還可以被用在函數參數位置,表示我們明确希望這個函數在被調用時不需要任何參數。例如上面的函數printmessage也可以寫為以下形式:

void printmessage (void)
{
  cout << "I'm a function!";
}      

雖然在C++ 中void可以被省略,我們還是建議寫出void,以便明确指出函數不需要參數。

你必須時刻知道的是調用一個函數時要寫出它的名字并把參數寫在後面的括号内。但如果函數不需要參數,後面的括号并不能省略。是以調用函數 printmessage 的格式是

printmessage();

函數名稱後面的括号就明确表示了它是一個函數調用,而不是一個變量名稱或其它什麼語句。以下調用函數的方式就不對:

printmessage;

繼續閱讀