C++ Primer 讀書筆記(7)

函數的定義和調用

我們將函數與操作符對應,操作符有操作數和操作結果,函數的定義由其函數名和其操作數即參數(parameter)組成,而其操作結果即返回值,由return語句進行返回。調用函數需要調用操作符(),調用操作符的操作數就是函數名和傳入參數(argument)。

雖然都翻譯成參數,但是parameter是函數定義時的參數,由參數類型和參數名(可省略)組成,用逗號隔開,而argument是調用函數時傳給函數的參數,可以是變量、常量或表達式,對於同一個參數,parameter和argument的數量必須相同、類型必須是相同的或可以相互轉換的。如果parameter的類型不是引用類型,那麼在函數中改變parameter是不會改變相應的argument的。parameter是形參,argument是實參。

引用型參數

非引用型的參數(argument)不會被函數改變,函數改變的只是它自己定義的參數(parameter),在調用函數時,傳入的argument是用來初始化函數的parameter,而我們知道變量的初始化如 int v=n (n爲int類型的變量),只是將變量n的值複製(copy)到變量v的空間,此後對於v的任何修改都不會影響到n,同理,我們在調用的函數裏修改parameter是不會影響到argument的。舉個例子,比如我們想調用一個函數swap來交換i和j的值,代碼如下:

void swap(int a, int b)
{
    int temp=a;
    a=b;
    b=temp;
}

int main()
{
    int i=1, j=10;
    swap(i,j);
}

事實上,只是將i和j的值分別賦值給a和b,然後交換a和b的值,此後a=10, b=1, 但是i=1, j=10還是沒有變。因此我們在定義swap時,應該將參數(parameter)設爲引用型:

void swap(int &a, int &b)
{
    int temp=a;
    a=b;
    b=temp;
}

這樣在傳入參數是,實際上進行的是如下操作, int &a=i, int &b=j,我們知道,引用型變量只是現有變量的另一個名字,即a是i的另一個名字,都是同一個變量,因此對a的修改就是對i的修改,這樣就可以真正修改argument的值了。

另外,因爲函數的return只能返回一個值,而我們有時候希望一個函數返回我們多個結果,這個時候也要用到引用類型的參數。例如,我們要用函數find_val在一個int型的vector中找到某個值,返回它第一次出現的迭代器,同時還需要返回這個vector中有該值出現了多少次,我們可以這樣做:

vector<int>:: iterator find_val(vector<int>:: iterator beg, vector<int> :: iterator end, int val, int &cnt)
{
    vector<int>:: iterator it=beg;
    vector<int>:: iterator ret=end;
    cnt=0;
    for (; it!=end; ++it)
    {
         if (*it==val)
         {
               ++cnt;    //目標值出現次數增加
               if (ret==end)
                   ret=it;
         }
    }
    return ret;
}

在這裏,我們用函數的返回值返回查找目標第一齣現的迭代器,同時設置一個引用型參數cnt來記錄查找目標的出現次數,這樣在find_val函數外cnt所指的變量還是可見的,相當於函數返回了出現次數。另外值得注意的是,該函數遍歷vector僅僅需要兩個迭代器beg和end,分別記錄vector的第一個元素位置和最後一個元素的下一個位置,突顯了迭代器與指針作用的類似,事實上,在C語言中就是用指針實現對傳入的argument值的改變的。

在使用引用型參數時,要主要一點:如果函數不會改變該參數的值,即對於該參數是隻讀的,那麼最好使用const引用類型,因爲非const引用類型會有限制,例如string &a定義的參數a,只能用字符串變量進行對其進行賦值,而字符串常量“hello world”是不能賦值給a的,而const string &a則可用字符串變量、常量、結果爲rvalue的表達式等賦值,大大增加了a的賦值範圍,減少出錯的可能。

指針的引用型是這麼定義的,int *&ptr,我們可以從右往左理解這個定義,ptr是一個引用型的指向int型的指針變量,所以一個交換兩個指針值的函數應該這麼寫:

void swap(int *&ptr1, int *&ptr2)
{
    int *temp=ptr1;
    ptr1=ptr2;
    ptr2=temp;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章