1. 程式人生 > >函式返回的幾種情況

函式返回的幾種情況


轉載地址:https://www.cnblogs.com/edwardcmh/archive/2012/03/20/2408359.html

1. 返回區域性變數的值

可以有兩種情況:返回區域性自動變數和區域性靜態變數,比如,

int func()
{
	int temp = 0;	// 返回區域性自動變數的值
	return temp;
}

區域性變數temp儲存在棧中,函式返回時會自動複製一份temp的copy給呼叫者,沒有問題。

int func()
{
	static int a = 1;	// 返回區域性靜態變數的值
	return a;
}

區域性變數a儲存在靜態(全域性)儲存區中,從初始化後一直有效直到程式結束,僅分配一次記憶體,並且函式返回後,變數不會銷燬,沒有問題。

vector<int> func()
{
	vector<int> v;
	v.push_back(0);
	return v;
}

返回的是v的值拷貝,沒有問題。

Person func()
{
	Person p1;
	p1.name = "test";
	return p1;
}

返回的也是值拷貝,會呼叫Person類的拷貝建構函式,沒有問題。

2. 返回區域性變數的指標

int* func()
{
	int temp = 0;	// 返回區域性變數的地址
	return &temp;
}

前面討論過,區域性變數temp儲存在棧中,函式返回時將已銷燬變數的地址返回給呼叫者,結果將是不可預知的。

int* func()
{
	static int temp = 1;
	return &temp;
}

區域性變數temp儲存在靜態儲存區,返回指向靜態儲存區變數的指標是可行的。

char* func()
{
	char *p = "test";
	return p;	// 返回指向常量字串的指標
}

對於字串的特殊情況,由於字串test儲存在常量儲存區(不是靜態儲存區),因此函式返回一個指向常量的字串指標是可行的。

char* func()
{
	char str[] = "test";
	return str;	// 返回區域性字串的指標
}

這種情況下,str被初始化為字串區域性變數,因此函式返回一個已銷燬的區域性變數是不可行的。解決辦法就是將字串str宣告為static。

char* func()
{
	char *str = (char *)malloc(sizeof(char) * BUFFER_SIZE);
	strcpy(str, "test");
	return str;
}

這種情況下,函式返回一個指向堆記憶體的指標,由於堆儲存區由程式設計師手動管理,因此這種做法是可行的,但是要防止出現記憶體洩露,函式呼叫完後需要手動釋放記憶體。這裡的sizeof作用於指標返回的是指標型別的長度1byte,而如果作用於陣列返回的則是陣列的長度。

char *temp = NULL;
temp = func();
// some operation...
free(temp);

3. 返回區域性變數的引用

int& func()
{
	int temp = 0;	// 返回區域性變數的引用
	return temp;
}

由引用的概念可知,函式返回的是temp本身,而temp在函式返回後已銷燬,結果將是不可預知的。

補充:靜態全域性變數和全域性變數的區別

靜態全域性變數只在當前檔案中可用,全域性變數在其他檔案中也可用,需要用extern宣告。

全域性變數和靜態變數如果沒有手動初始化,則預設由編譯器初始化為0。