C++程式設計:函式的返回型別

首頁 > 科技

C++程式設計:函式的返回型別

來源:怎樣不禿頂 釋出時間:2023-06-10 00:51

函式可以透過return語句,終止函式的執行並“返回”函式呼叫的地方;並且可以給定返回值。返回值的型別由函式宣告時的“返回型別”決定。

return語句可以有兩種形式:

return;// 直接返回,無返回值

return 表示式; // 返回表示式的值

1. 無返回值

當函式返回型別為void時,表示函式沒有返回值。可以在函式中需要返回時直接執行 return語句,也可以不寫。由於返回型別為void的函式執行完最後一句,會自動加上return返回。

例如,可以將之前“兩元素值互換”的程式碼,包裝成一個函式。可以先做一個判定,假如兩者相等就直接返回,這樣可以進步執行效率。

// 元素互換

void swap(int& x, int& y)

{

if (x == y)

return; // 不需要交換,直接返回

int temp = x;

x = y;

y = temp;

}

這裡判定假如元素相等就直接返回,有些類似於流程控制中的break。最後一句程式碼後面省略了return。

2. 有返回值

假如函式返回型別不為void,那麼函式必需執行return,並且每條return必需返回一個值。返回值的型別應該跟函式返回型別一致,或者可以隱式轉換為一致。

(1)函式返回值的原理

函式在呼叫點會建立一個“臨時量”,用來留存函式呼叫的結果。當使用return語句返回時,就會用返回值去初始化這個臨時量。所以返回值的相關規則,跟變數或者形參的初始化是一致的。

之前寫過一個“比較字串長度”的isLonger函式,我們可以稍作修改,讓它可以返回較長的那個字串:

// 字串比較長度,返回較長的

string longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

int main()

{

string str1 = "hello world!", str2 = "c++ is interesting!";

cout << longerStr(str1, str2) << endl;

}

呼叫這個函式,經由判定發現str2較長,這時執行return將返回str2。因為返回型別是string,所以將用str2對一個string臨時量做初始化,執行的是值複製。終極返回的值,是str2的一個副本。

(2)返回引用型別

對於string物件,顯然做值複製並不高效。所以我們依然可以鑑戒之前的經驗,使用引用型別來做返回值的傳遞,這樣就可以避免值複製。

// 返回一個string常量物件的引用,不做值複製

const string & longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

這裡我們同樣把返回值定義成了常量引用,方式和作用跟形參完全一樣。

上面函式返回的是形參str1或者str2的引用;而函式中的形參本身又是引用型別,所以終極是實參物件的引用。

而假如返回的是一個函式內區域性變數的引用,好比:

const string & f()

{

string str = "test";

return str;

}

這樣做是不安全的:由於str是函式內部的區域性物件,函式執行完成後就銷燬了;而返回值是它的引用,相當於引用了一個不存在的物件,這可能會導致無法預料的問題。

所以,函式返回引用型別時,不能返回區域性物件的引用;同樣道理,也不應該返回指向區域性物件的指標。

(3)返回類物件後連續呼叫

假如函式返回一個類的物件,那麼我們可以繼承呼叫這個物件的成員函式,這樣就形成了“鏈式呼叫”。例如:

longerStr(str1, str2).size();

呼叫運算子,和訪問物件成員的點運算子優先順序相同,並且滿意左結合律。所以鏈式呼叫就是從左向右依次呼叫,程式碼可讀性會更高。

3. 主函式的返回值

主函式main是一個特殊函式,它是我們執行程式的進口。所以C++中對主函式的返回值也有特殊的劃定:即使返回型別不是void,主函式也可以省略return語句。假如主函式執行到結尾都沒有return語句,編譯器就會自動插入一條:

return 0;

主函式的返回值可以看做程式執行的狀態指示器:返回0表示執行成功;返回非0值則表示失敗。非0值詳細的含義依靠機器決定。

這也是為什麼之前我們在主函式中都可以不寫return。

4. 返回陣列指標

與形參的討論類似,因為陣列“不能複製”的特點,函式也無法直接返回一個數組。同樣的,我們可以使用指標或者引用來實現返回陣列的目標;通常會返回一個數組指標。

int arr[5] = { 1,2,3,4,5 };

int* pa[5]; // 指標陣列,pa是包含5個int指標的陣列

int(*ap)[5] = &arr; // 陣列指標,ap是一個指標,指向長度為5的int陣列

int(*fun(int x))[5]; // 函式宣告,fun返回值型別為陣列指標

這裡對於函式fun的宣告,我們可以進行層層解析:

l fun(int x) :函式名為fun,形參為int型別的x;

l ( * fun(int x) ):函式返回的結果,可以執行解引用操縱,說明是一個指標;

l ( * fun(int x) )[5]:函式返回結果解引用之後是一個長度為5的陣列,說明返回型別是陣列指標;

l int ( * fun(int x) )[5]:陣列中元素型別為int

陣列指標的定義比較繁瑣,為了簡化這個定義,我們可以使用關鍵字typedef來定義一個型別的別號:

typedef int arrayT[5]; // 類型別號,arrayT代表長度為5的int陣列

arrayT* fun2(int x); // fun2的返回型別是指向arrayT的指標

C++ 11新尺度還提供了另一種簡化方式,用一個->符號跟在形參列表後面,再把型別單獨提出來放到最後。這種方式叫做“尾置返回型別”。

auto fun3(int x) -> int(*)[5]; // 尾置返回型別

由於返回型別放到了末尾,所以前面的型別用了自動推斷的auto。

函式可以透過return語句,終止函式的執行並“返回”函式呼叫的地方;並且可以給定返回值。返回值的型別由函式宣告時的“返回型別”決定。

return語句可以有兩種形式:

return;// 直接返回,無返回值

return 表示式; // 返回表示式的值

1. 無返回值

當函式返回型別為void時,表示函式沒有返回值。可以在函式中需要返回時直接執行 return語句,也可以不寫。由於返回型別為void的函式執行完最後一句,會自動加上return返回。

例如,可以將之前“兩元素值互換”的程式碼,包裝成一個函式。可以先做一個判定,假如兩者相等就直接返回,這樣可以進步執行效率。

// 元素互換

void swap(int& x, int& y)

{

if (x == y)

return; // 不需要交換,直接返回

int temp = x;

x = y;

y = temp;

}

這裡判定假如元素相等就直接返回,有些類似於流程控制中的break。最後一句程式碼後面省略了return。

2. 有返回值

假如函式返回型別不為void,那麼函式必需執行return,並且每條return必需返回一個值。返回值的型別應該跟函式返回型別一致,或者可以隱式轉換為一致。

(1)函式返回值的原理

函式在呼叫點會建立一個“臨時量”,用來留存函式呼叫的結果。當使用return語句返回時,就會用返回值去初始化這個臨時量。所以返回值的相關規則,跟變數或者形參的初始化是一致的。

之前寫過一個“比較字串長度”的isLonger函式,我們可以稍作修改,讓它可以返回較長的那個字串:

// 字串比較長度,返回較長的

string longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

int main()

{

string str1 = "hello world!", str2 = "c++ is interesting!";

cout << longerStr(str1, str2) << endl;

}

呼叫這個函式,經由判定發現str2較長,這時執行return將返回str2。因為返回型別是string,所以將用str2對一個string臨時量做初始化,執行的是值複製。終極返回的值,是str2的一個副本。

(2)返回引用型別

對於string物件,顯然做值複製並不高效。所以我們依然可以鑑戒之前的經驗,使用引用型別來做返回值的傳遞,這樣就可以避免值複製。

// 返回一個string常量物件的引用,不做值複製

const string & longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

這裡我們同樣把返回值定義成了常量引用,方式和作用跟形參完全一樣。

上面函式返回的是形參str1或者str2的引用;而函式中的形參本身又是引用型別,所以終極是實參物件的引用。

而假如返回的是一個函式內區域性變數的引用,好比:

const string & f()

{

string str = "test";

return str;

}

這樣做是不安全的:由於str是函式內部的區域性物件,函式執行完成後就銷燬了;而返回值是它的引用,相當於引用了一個不存在的物件,這可能會導致無法預料的問題。

所以,函式返回引用型別時,不能返回區域性物件的引用;同樣道理,也不應該返回指向區域性物件的指標。

(3)返回類物件後連續呼叫

假如函式返回一個類的物件,那麼我們可以繼承呼叫這個物件的成員函式,這樣就形成了“鏈式呼叫”。例如:

longerStr(str1, str2).size();

呼叫運算子,和訪問物件成員的點運算子優先順序相同,並且滿意左結合律。所以鏈式呼叫就是從左向右依次呼叫,程式碼可讀性會更高。

3. 主函式的返回值

主函式main是一個特殊函式,它是我們執行程式的進口。所以C++中對主函式的返回值也有特殊的劃定:即使返回型別不是void,主函式也可以省略return語句。假如主函式執行到結尾都沒有return語句,編譯器就會自動插入一條:

return 0;

主函式的返回值可以看做程式執行的狀態指示器:返回0表示執行成功;返回非0值則表示失敗。非0值詳細的含義依靠機器決定。

這也是為什麼之前我們在主函式中都可以不寫return。

4. 返回陣列指標

與形參的討論類似,因為陣列“不能複製”的特點,函式也無法直接返回一個數組。同樣的,我們可以使用指標或者引用來實現返回陣列的目標;通常會返回一個數組指標。

int arr[5] = { 1,2,3,4,5 };

int* pa[5]; // 指標陣列,pa是包含5個int指標的陣列

int(*ap)[5] = &arr; // 陣列指標,ap是一個指標,指向長度為5的int陣列

int(*fun(int x))[5]; // 函式宣告,fun返回值型別為陣列指標

這裡對於函式fun的宣告,我們可以進行層層解析:

l fun(int x) :函式名為fun,形參為int型別的x;

l ( * fun(int x) ):函式返回的結果,可以執行解引用操縱,說明是一個指標;

l ( * fun(int x) )[5]:函式返回結果解引用之後是一個長度為5的陣列,說明返回型別是陣列指標;

l int ( * fun(int x) )[5]:陣列中元素型別為int

陣列指標的定義比較繁瑣,為了簡化這個定義,我們可以使用關鍵字typedef來定義一個型別的別號:

typedef int arrayT[5]; // 類型別號,arrayT代表長度為5的int陣列

arrayT* fun2(int x); // fun2的返回型別是指向arrayT的指標

C++ 11新尺度還提供了另一種簡化方式,用一個->符號跟在形參列表後面,再把型別單獨提出來放到最後。這種方式叫做“尾置返回型別”。

auto fun3(int x) -> int(*)[5]; // 尾置返回型別

由於返回型別放到了末尾,所以前面的型別用了自動推斷的auto。

函式可以透過return語句,終止函式的執行並“返回”函式呼叫的地方;並且可以給定返回值。返回值的型別由函式宣告時的“返回型別”決定。

return語句可以有兩種形式:

return;// 直接返回,無返回值

return 表示式; // 返回表示式的值

1. 無返回值

當函式返回型別為void時,表示函式沒有返回值。可以在函式中需要返回時直接執行 return語句,也可以不寫。由於返回型別為void的函式執行完最後一句,會自動加上return返回。

例如,可以將之前“兩元素值互換”的程式碼,包裝成一個函式。可以先做一個判定,假如兩者相等就直接返回,這樣可以進步執行效率。

// 元素互換

void swap(int& x, int& y)

{

if (x == y)

return; // 不需要交換,直接返回

int temp = x;

x = y;

y = temp;

}

這裡判定假如元素相等就直接返回,有些類似於流程控制中的break。最後一句程式碼後面省略了return。

2. 有返回值

假如函式返回型別不為void,那麼函式必需執行return,並且每條return必需返回一個值。返回值的型別應該跟函式返回型別一致,或者可以隱式轉換為一致。

(1)函式返回值的原理

函式在呼叫點會建立一個“臨時量”,用來留存函式呼叫的結果。當使用return語句返回時,就會用返回值去初始化這個臨時量。所以返回值的相關規則,跟變數或者形參的初始化是一致的。

之前寫過一個“比較字串長度”的isLonger函式,我們可以稍作修改,讓它可以返回較長的那個字串:

// 字串比較長度,返回較長的

string longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

int main()

{

string str1 = "hello world!", str2 = "c++ is interesting!";

cout << longerStr(str1, str2) << endl;

}

呼叫這個函式,經由判定發現str2較長,這時執行return將返回str2。因為返回型別是string,所以將用str2對一個string臨時量做初始化,執行的是值複製。終極返回的值,是str2的一個副本。

(2)返回引用型別

對於string物件,顯然做值複製並不高效。所以我們依然可以鑑戒之前的經驗,使用引用型別來做返回值的傳遞,這樣就可以避免值複製。

// 返回一個string常量物件的引用,不做值複製

const string & longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

這裡我們同樣把返回值定義成了常量引用,方式和作用跟形參完全一樣。

上面函式返回的是形參str1或者str2的引用;而函式中的形參本身又是引用型別,所以終極是實參物件的引用。

而假如返回的是一個函式內區域性變數的引用,好比:

const string & f()

{

string str = "test";

return str;

}

這樣做是不安全的:由於str是函式內部的區域性物件,函式執行完成後就銷燬了;而返回值是它的引用,相當於引用了一個不存在的物件,這可能會導致無法預料的問題。

所以,函式返回引用型別時,不能返回區域性物件的引用;同樣道理,也不應該返回指向區域性物件的指標。

(3)返回類物件後連續呼叫

假如函式返回一個類的物件,那麼我們可以繼承呼叫這個物件的成員函式,這樣就形成了“鏈式呼叫”。例如:

longerStr(str1, str2).size();

呼叫運算子,和訪問物件成員的點運算子優先順序相同,並且滿意左結合律。所以鏈式呼叫就是從左向右依次呼叫,程式碼可讀性會更高。

3. 主函式的返回值

主函式main是一個特殊函式,它是我們執行程式的進口。所以C++中對主函式的返回值也有特殊的劃定:即使返回型別不是void,主函式也可以省略return語句。假如主函式執行到結尾都沒有return語句,編譯器就會自動插入一條:

return 0;

主函式的返回值可以看做程式執行的狀態指示器:返回0表示執行成功;返回非0值則表示失敗。非0值詳細的含義依靠機器決定。

這也是為什麼之前我們在主函式中都可以不寫return。

4. 返回陣列指標

與形參的討論類似,因為陣列“不能複製”的特點,函式也無法直接返回一個數組。同樣的,我們可以使用指標或者引用來實現返回陣列的目標;通常會返回一個數組指標。

int arr[5] = { 1,2,3,4,5 };

int* pa[5]; // 指標陣列,pa是包含5個int指標的陣列

int(*ap)[5] = &arr; // 陣列指標,ap是一個指標,指向長度為5的int陣列

int(*fun(int x))[5]; // 函式宣告,fun返回值型別為陣列指標

這裡對於函式fun的宣告,我們可以進行層層解析:

l fun(int x) :函式名為fun,形參為int型別的x;

l ( * fun(int x) ):函式返回的結果,可以執行解引用操縱,說明是一個指標;

l ( * fun(int x) )[5]:函式返回結果解引用之後是一個長度為5的陣列,說明返回型別是陣列指標;

l int ( * fun(int x) )[5]:陣列中元素型別為int

陣列指標的定義比較繁瑣,為了簡化這個定義,我們可以使用關鍵字typedef來定義一個型別的別號:

typedef int arrayT[5]; // 類型別號,arrayT代表長度為5的int陣列

arrayT* fun2(int x); // fun2的返回型別是指向arrayT的指標

C++ 11新尺度還提供了另一種簡化方式,用一個->符號跟在形參列表後面,再把型別單獨提出來放到最後。這種方式叫做“尾置返回型別”。

auto fun3(int x) -> int(*)[5]; // 尾置返回型別

由於返回型別放到了末尾,所以前面的型別用了自動推斷的auto。

函式可以透過return語句,終止函式的執行並“返回”函式呼叫的地方;並且可以給定返回值。返回值的型別由函式宣告時的“返回型別”決定。

return語句可以有兩種形式:

return;// 直接返回,無返回值

return 表示式; // 返回表示式的值

1. 無返回值

當函式返回型別為void時,表示函式沒有返回值。可以在函式中需要返回時直接執行 return語句,也可以不寫。由於返回型別為void的函式執行完最後一句,會自動加上return返回。

例如,可以將之前“兩元素值互換”的程式碼,包裝成一個函式。可以先做一個判定,假如兩者相等就直接返回,這樣可以進步執行效率。

// 元素互換

void swap(int& x, int& y)

{

if (x == y)

return; // 不需要交換,直接返回

int temp = x;

x = y;

y = temp;

}

這裡判定假如元素相等就直接返回,有些類似於流程控制中的break。最後一句程式碼後面省略了return。

2. 有返回值

假如函式返回型別不為void,那麼函式必需執行return,並且每條return必需返回一個值。返回值的型別應該跟函式返回型別一致,或者可以隱式轉換為一致。

(1)函式返回值的原理

函式在呼叫點會建立一個“臨時量”,用來留存函式呼叫的結果。當使用return語句返回時,就會用返回值去初始化這個臨時量。所以返回值的相關規則,跟變數或者形參的初始化是一致的。

之前寫過一個“比較字串長度”的isLonger函式,我們可以稍作修改,讓它可以返回較長的那個字串:

// 字串比較長度,返回較長的

string longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

int main()

{

string str1 = "hello world!", str2 = "c++ is interesting!";

cout << longerStr(str1, str2) << endl;

}

呼叫這個函式,經由判定發現str2較長,這時執行return將返回str2。因為返回型別是string,所以將用str2對一個string臨時量做初始化,執行的是值複製。終極返回的值,是str2的一個副本。

(2)返回引用型別

對於string物件,顯然做值複製並不高效。所以我們依然可以鑑戒之前的經驗,使用引用型別來做返回值的傳遞,這樣就可以避免值複製。

// 返回一個string常量物件的引用,不做值複製

const string & longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

這裡我們同樣把返回值定義成了常量引用,方式和作用跟形參完全一樣。

上面函式返回的是形參str1或者str2的引用;而函式中的形參本身又是引用型別,所以終極是實參物件的引用。

而假如返回的是一個函式內區域性變數的引用,好比:

const string & f()

{

string str = "test";

return str;

}

這樣做是不安全的:由於str是函式內部的區域性物件,函式執行完成後就銷燬了;而返回值是它的引用,相當於引用了一個不存在的物件,這可能會導致無法預料的問題。

所以,函式返回引用型別時,不能返回區域性物件的引用;同樣道理,也不應該返回指向區域性物件的指標。

(3)返回類物件後連續呼叫

假如函式返回一個類的物件,那麼我們可以繼承呼叫這個物件的成員函式,這樣就形成了“鏈式呼叫”。例如:

longerStr(str1, str2).size();

呼叫運算子,和訪問物件成員的點運算子優先順序相同,並且滿意左結合律。所以鏈式呼叫就是從左向右依次呼叫,程式碼可讀性會更高。

3. 主函式的返回值

主函式main是一個特殊函式,它是我們執行程式的進口。所以C++中對主函式的返回值也有特殊的劃定:即使返回型別不是void,主函式也可以省略return語句。假如主函式執行到結尾都沒有return語句,編譯器就會自動插入一條:

return 0;

主函式的返回值可以看做程式執行的狀態指示器:返回0表示執行成功;返回非0值則表示失敗。非0值詳細的含義依靠機器決定。

這也是為什麼之前我們在主函式中都可以不寫return。

4. 返回陣列指標

與形參的討論類似,因為陣列“不能複製”的特點,函式也無法直接返回一個數組。同樣的,我們可以使用指標或者引用來實現返回陣列的目標;通常會返回一個數組指標。

int arr[5] = { 1,2,3,4,5 };

int* pa[5]; // 指標陣列,pa是包含5個int指標的陣列

int(*ap)[5] = &arr; // 陣列指標,ap是一個指標,指向長度為5的int陣列

int(*fun(int x))[5]; // 函式宣告,fun返回值型別為陣列指標

這裡對於函式fun的宣告,我們可以進行層層解析:

l fun(int x) :函式名為fun,形參為int型別的x;

l ( * fun(int x) ):函式返回的結果,可以執行解引用操縱,說明是一個指標;

l ( * fun(int x) )[5]:函式返回結果解引用之後是一個長度為5的陣列,說明返回型別是陣列指標;

l int ( * fun(int x) )[5]:陣列中元素型別為int

陣列指標的定義比較繁瑣,為了簡化這個定義,我們可以使用關鍵字typedef來定義一個型別的別號:

typedef int arrayT[5]; // 類型別號,arrayT代表長度為5的int陣列

arrayT* fun2(int x); // fun2的返回型別是指向arrayT的指標

C++ 11新尺度還提供了另一種簡化方式,用一個->符號跟在形參列表後面,再把型別單獨提出來放到最後。這種方式叫做“尾置返回型別”。

auto fun3(int x) -> int(*)[5]; // 尾置返回型別

由於返回型別放到了末尾,所以前面的型別用了自動推斷的auto。

函式可以透過return語句,終止函式的執行並“返回”函式呼叫的地方;並且可以給定返回值。返回值的型別由函式宣告時的“返回型別”決定。

return語句可以有兩種形式:

return;// 直接返回,無返回值

return 表示式; // 返回表示式的值

1. 無返回值

當函式返回型別為void時,表示函式沒有返回值。可以在函式中需要返回時直接執行 return語句,也可以不寫。由於返回型別為void的函式執行完最後一句,會自動加上return返回。

例如,可以將之前“兩元素值互換”的程式碼,包裝成一個函式。可以先做一個判定,假如兩者相等就直接返回,這樣可以進步執行效率。

// 元素互換

void swap(int& x, int& y)

{

if (x == y)

return; // 不需要交換,直接返回

int temp = x;

x = y;

y = temp;

}

這裡判定假如元素相等就直接返回,有些類似於流程控制中的break。最後一句程式碼後面省略了return。

2. 有返回值

假如函式返回型別不為void,那麼函式必需執行return,並且每條return必需返回一個值。返回值的型別應該跟函式返回型別一致,或者可以隱式轉換為一致。

(1)函式返回值的原理

函式在呼叫點會建立一個“臨時量”,用來留存函式呼叫的結果。當使用return語句返回時,就會用返回值去初始化這個臨時量。所以返回值的相關規則,跟變數或者形參的初始化是一致的。

之前寫過一個“比較字串長度”的isLonger函式,我們可以稍作修改,讓它可以返回較長的那個字串:

// 字串比較長度,返回較長的

string longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

int main()

{

string str1 = "hello world!", str2 = "c++ is interesting!";

cout << longerStr(str1, str2) << endl;

}

呼叫這個函式,經由判定發現str2較長,這時執行return將返回str2。因為返回型別是string,所以將用str2對一個string臨時量做初始化,執行的是值複製。終極返回的值,是str2的一個副本。

(2)返回引用型別

對於string物件,顯然做值複製並不高效。所以我們依然可以鑑戒之前的經驗,使用引用型別來做返回值的傳遞,這樣就可以避免值複製。

// 返回一個string常量物件的引用,不做值複製

const string & longerStr(const string& str1, const string& str2)

{

return str1.size() > str2.size() ? str1 : str2;

}

這裡我們同樣把返回值定義成了常量引用,方式和作用跟形參完全一樣。

上面函式返回的是形參str1或者str2的引用;而函式中的形參本身又是引用型別,所以終極是實參物件的引用。

而假如返回的是一個函式內區域性變數的引用,好比:

const string & f()

{

string str = "test";

return str;

}

這樣做是不安全的:由於str是函式內部的區域性物件,函式執行完成後就銷燬了;而返回值是它的引用,相當於引用了一個不存在的物件,這可能會導致無法預料的問題。

所以,函式返回引用型別時,不能返回區域性物件的引用;同樣道理,也不應該返回指向區域性物件的指標。

(3)返回類物件後連續呼叫

假如函式返回一個類的物件,那麼我們可以繼承呼叫這個物件的成員函式,這樣就形成了“鏈式呼叫”。例如:

longerStr(str1, str2).size();

呼叫運算子,和訪問物件成員的點運算子優先順序相同,並且滿意左結合律。所以鏈式呼叫就是從左向右依次呼叫,程式碼可讀性會更高。

3. 主函式的返回值

主函式main是一個特殊函式,它是我們執行程式的進口。所以C++中對主函式的返回值也有特殊的劃定:即使返回型別不是void,主函式也可以省略return語句。假如主函式執行到結尾都沒有return語句,編譯器就會自動插入一條:

return 0;

主函式的返回值可以看做程式執行的狀態指示器:返回0表示執行成功;返回非0值則表示失敗。非0值詳細的含義依靠機器決定。

這也是為什麼之前我們在主函式中都可以不寫return。

4. 返回陣列指標

與形參的討論類似,因為陣列“不能複製”的特點,函式也無法直接返回一個數組。同樣的,我們可以使用指標或者引用來實現返回陣列的目標;通常會返回一個數組指標。

int arr[5] = { 1,2,3,4,5 };

int* pa[5]; // 指標陣列,pa是包含5個int指標的陣列

int(*ap)[5] = &arr; // 陣列指標,ap是一個指標,指向長度為5的int陣列

int(*fun(int x))[5]; // 函式宣告,fun返回值型別為陣列指標

這裡對於函式fun的宣告,我們可以進行層層解析:

l fun(int x) :函式名為fun,形參為int型別的x;

l ( * fun(int x) ):函式返回的結果,可以執行解引用操縱,說明是一個指標;

l ( * fun(int x) )[5]:函式返回結果解引用之後是一個長度為5的陣列,說明返回型別是陣列指標;

l int ( * fun(int x) )[5]:陣列中元素型別為int

陣列指標的定義比較繁瑣,為了簡化這個定義,我們可以使用關鍵字typedef來定義一個型別的別號:

typedef int arrayT[5]; // 類型別號,arrayT代表長度為5的int陣列

arrayT* fun2(int x); // fun2的返回型別是指向arrayT的指標

C++ 11新尺度還提供了另一種簡化方式,用一個->符號跟在形參列表後面,再把型別單獨提出來放到最後。這種方式叫做“尾置返回型別”。

auto fun3(int x) -> int(*)[5]; // 尾置返回型別

由於返回型別放到了末尾,所以前面的型別用了自動推斷的auto。

上一篇:為節約您的時... 下一篇:nginx配置中...
猜你喜歡
熱門閱讀
同類推薦