C++中爲什麼引用可以作爲函數返回值?

C++中爲什麼引用可以作爲函數返回值?

本文背景

程序設計與算法(三)第01周測驗003:好怪異的返回值裏面,題目的解答是這樣子的:

#include <iostream>

using namespace std;
int & getElement(int * a, int i)
{
	return a[i];
}

int main()
{
	int a[] = {1,2,3};
	getElement(a,1) = 10;
	cout << a[1] ;
	return 0;
}

有讀者奇怪的是,爲什麼int & getElement(int * a, int i)要加&,直接int getElement(int * a, int i)不可以麼?

真機測試

那我們在CLion裏不加&試試。

#include <iostream>

using namespace std;
int getElement(int * a, int i)//不加&
{
	return a[i];
}

int main()
{
	int a[] = {1,2,3};
	getElement(a,1) = 10;
	cout << a[1] ;
	return 0;
}

調試信息

調試,返回錯誤:

====================[ Build | test1 | Debug ]===================================
/opt/clion/bin/cmake/linux/bin/cmake --build /home/mrcangye/CLionProjects/test1/cmake-build-debug --target test1 -- -j 2
[ 50%] Building CXX object CMakeFiles/test1.dir/main.cpp.o
/home/mrcangye/CLionProjects/test1/main.cpp: In function ‘int main()’:
/home/mrcangye/CLionProjects/test1/main.cpp:12:20: error: lvalue required as left operand of assignment
   12 |  getElement(a,1) = 10;
      |                    ^~
make[3]: *** [CMakeFiles/test1.dir/build.make:63: CMakeFiles/test1.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test1.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test1.dir/rule] Error 2
make: *** [Makefile:118: test1] Error 2

調試信息指出了程序第12行,getElement(a,1) = 10;出現錯誤。

這也是接下來需要講述的問題。

參考資料

爲了解決這個問題,我拿出了C++ Primer Plus 第六版中文版 人民郵電出版社2012年七月第一版,2019年1月北京第31次印刷版本,第8章 函數探幽 第268頁

基本原理

重點在於:

getElement(a,1) = 10;

這是一個賦值語句

在賦值語句中,語句左邊,也就是=號左邊,必須是可以修改的值,深入瞭解一下,必須是一個可以修改的內存塊。重點是這個等號左邊的值必須是可以修改的。

常規(非引用)的返回類型是放在=右邊的,是不能通過地址訪問的值。不可以出現在=號左邊。

爲什麼呢?因爲常規的返回值是存在臨時內存單元中的,運行到下一條語句時,這個返回值就不存在了。return後面的表達式將結果的值計算出來,然後這個值被複制到一個臨時位置,返回給調用函數,調用函數再到臨時位置使用這個值

複製到
返回給
return返回值
臨時位置
調用函數調用

解答

上面的原理和調試出錯的信息是一致的。

如果我們不加&,那麼返回的是一個確切的int數值11 = 10是不符合左邊可以修改的值的要求。

爲了符合這個要求,我們就需要加&號,使得這個函數getElement(a,1)返回值是int &

,並將int &返回,就是:a[1] = 10,這樣就合法了

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