函式(function)

函式:
1、函式不能返回內建的array型別,但可返回pointer指向array的某個元素。
2、如果函式接收一個pointer指向nonconst型別物件,此函式可以透過該pointer改變所指物件的值。

void reset(int *ip){
  *ip = 0;  //改變ip所指物件的值

}
3、如果想避免pointer所指值被改變,應該將參數定義為pointer to const

void fun(const int *p){
  //函式可讀取*p但不能改寫*p的值
}

4、函式被呼叫之前要先被宣告,函式只能定義一次,但可以宣告多次,通常宣告放在.c檔,定義放在.cpp檔。

函式參數:
1、因為引數會複製一份傳遞,所以我們可傳遞const或nonconst物件給接收const型別的函式。

void fun(const int i); //可以讀取不能寫入i
void fun(int i);       //對編輯器來說兩函式相同,所以會和上個函式產生重複定義的問題

2、nonconst reference參數彈性較低,不能以const物件、字面常數或需要型別轉換的物件當引數。

int fun(int &val);
int main(){
  short v1 = 0;
  const int v2 = 0;
  fun(v1);  //錯誤,v1不是int
  fun(v2);  //錯誤,v2是const
}

3、編譯器會忽略array參數指定的尺寸。

void fun(const int ia[5]);
int main(){
  int i = 0;
  int j[3] = {0,1,2};
  fun(&i); //沒問題
  fun(j);  //沒問題,j被轉成pointer
}

4、nonconst reference的參數彈性低,所以可以用此方式讓編譯器檢查array尺寸,下面函式參數限定為5個int的array。

void fun(int (&arr)[5]);
int main(){
  int i = 0;
  int j[3] = {0,1,2}; 
  int k[5] = {0,1,2,3,4};
  fun(&i); //錯誤,引數不是帶有5個int的array
  fun(j);  //錯誤,引數不是帶有5個int的array 
  fun(k);  //正確,引數是帶有5個int的array 
}

預設引數:
引數會從左至右依序代入,所以最可能為預設值的參數放在最後,且只能省略尾端引數。

void fun(int size=5, char type='');
int main(){
  fun();         //等價於 fun(5,'');
  fun(10);       //等價於 fun(10,'');
  fun(10,'abc'); //等價於 fun(10,'abc');
  fun(,'abc');   //錯誤,只能省略尾端引數
}

函式返回:
1、不能返回一個reference(pointer)to local物件:

const string& fun(const string &s){
  string ret = s;
  return ret; //錯誤,返回reference to local物件
}

2、函式如果返回nonconst reference可以更改返回元素,如果不想更改應將返回值宣告為const:

char& fun(string &s){
  return s[0];
}
int main(){
  string s = "a";
  fun(s) = "b"; //更改s[0]的值為b
}

3、上面函式假如改為:const char& fun(string &s);則不能改變返回值。