1. 程式人生 > 其它 >C++ 指標與陣列

C++ 指標與陣列

前言

C, C++的指標和陣列的聯絡非常緊密。陣列的真正面目是什麼?如何傳遞一個數組到函式中?為什麼可以這麼訪問陣列?函式如何返回多個返回值?這些問題老生常談。至於答案。。。。

1 陣列名與指標

這一切的一切都要從陣列名是一個指標開始說起。

陣列名是一個指標! 陣列名是一個指標! 陣列名是一個指標!

我們先來看一個例子。

#include <iostream>
using namespace std;

int main ()
{
	// 帶有 5 個元素的雙精度浮點型陣列
	double Array[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
	double *p;
	
	p = Array;
	cout<< "p : addr "<< p << "\t"<< "Array : addr " << Array << endl ;
	cout<< endl;
	
	cout << "使用 p 指標的陣列值 " << endl; 
	for ( int i = 0; i < 5; i++ )
	{
	   cout << "*(p + " << i << ") : ";
	   cout << *(p + i) << endl;
	   cout << "p[" << i << "] : ";
	   cout << p[i] << endl;
	}
	
	cout<< endl;
	cout << "使用 Array 作為地址的陣列值 " << endl;
	for ( int i = 0; i < 5; i++ )
	{
	   cout << "*(Array + " << i << ") : ";
	   cout << *(Array + i) << endl;
	   cout << "Array[" << i << "] : ";
	   cout << Array[i] << endl;
	}
	
	return 0;
}

執行結果:

p : addr 0x6ffde0       Array : addr 0x6ffde0

使用 p 指標的陣列值
*(p + 0) : 1000
p[0] : 1000
*(p + 1) : 2
p[1] : 2
*(p + 2) : 3.4
p[2] : 3.4
*(p + 3) : 17
p[3] : 17
*(p + 4) : 50
p[4] : 50

使用 Array 作為地址的陣列值
*(Array + 0) : 1000
Array[0] : 1000
*(Array + 1) : 2
Array[1] : 2
*(Array + 2) : 3.4
Array[2] : 3.4
*(Array + 3) : 17
Array[3] : 17
*(Array + 4) : 50
Array[4] : 50

我們發現,陣列名就是一個指標(The type of Array is double *)!

將這個 Array 指標(double *)所指向的記憶體地址賦值給double * p。兩者指向的地址是一樣的0x6ffde0, 即陣列第一個元素所在記憶體的地址。

由此,p指標獲得了一個數組,或者說此時的p就是一個數組名,可以用任何正常訪問陣列的方式來訪問這個p陣列。*(p+i) or p[i]

2 陣列傳參

既然我們知道了陣列名就是一個指標,那麼傳參的時候把指標傳過去就行了。

有三種傳遞的方式,但是實質還是傳指標過去。上程式碼。

#include <iostream>
using namespace std;

void outArray1(double* arr, int size);
void outArray2(double arr[], int size);
void outArray3(double arr[5], int size);

int main ()
{
	// 帶有 5 個元素的雙精度浮點型陣列
	double Array[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
	double *p;
	
	p = Array;
	cout<< "p : addr "<< p << "\t"<< "Array : addr " << Array << endl ;
	cout<< endl; 

	outArray1(Array, 5);
	outArray2(Array, 5);
	outArray3(Array, 5);
	
	return 0;
}

void outArray1(double* arr, int size){
	cout<<"outArray1(double* arr, int size)"<<endl;
	for ( int i = 0; i < size; i++ )
	{
	   cout << arr[i] << " " ;
	}
	cout<< endl;
	
}

void outArray2(double arr[], int size){
	cout<<"outArray3(double arr[], int size)"<<endl;
	for ( int i = 0; i < size; i++ )
	{
	   cout << arr[i] << " " ;
	}
	cout<< endl;
}

void outArray3(double arr[5], int size){
	cout<<"outArray3(double arr[5], int size)"<<endl;
	for ( int i = 0; i < size; i++ )
	{
	   cout << arr[i] << " " ;
	}
	cout<< endl;
}

執行結果:

p : addr 0x6ffdf0       Array : addr 0x6ffdf0

outArray1(double* arr, int size)
1000 2 3.4 17 50
outArray3(double arr[], int size)
1000 2 3.4 17 50
outArray3(double arr[5], int size)
1000 2 3.4 17 50

綜上這三種方法分別為:

  1. (double* arr, int size)

  2. (double arr[], int size)

  3. (double arr[size], int size) // arr[1] or arr[2] 需要將陣列實際大小標註出來!

3 返回陣列

陣列名是指標,我們讓函式返回一個指標,同時按陣列來訪問。這樣可以麼?思路絕對沒錯,可是...

我們學習過編譯原理的話,就會明白,子函式執行時被載入到程式記憶體中,子函式執行完畢後會從程式記憶體中刪除。所以內裡的一切資料和指令也會被清除,函式中的待返回的陣列也會被清除,當你返回指標(存著陣列首地址)後,陣列被清除了,結果就是訪問不到資料了!

有沒有可以讓函式執行完畢之後,內裡的資料還存在的方法呢?這樣我們就能將指向這個資料地址的指標返回出來,並且正確訪問。

答案是 static 資料。static資料的生存週期是整個 main()函式的生存週期,也就是說,函式沒了,資料還在,並不會被銷燬!

接下來看示例程式碼

#include <iostream>
using namespace std;

double* return5ArrayNotST();
double* return5ArrayST();

int main ()
{
	double *p;
	
	p = return5ArrayNotST();
	cout << "使用 p : addr "<< p <<" 指標接收的 not static array " << endl; 
	cout << "double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};" << endl;
	for ( int i = 0; i < 5; i++ )
	{
	   cout << "p[" << i << "] : ";
	   cout << p[i] << endl;
	}
	
	cout<< endl;
	
	p = return5ArrayST();
	cout << "使用 p : addr "<< p <<" 指標接收的 static array " << endl; 
	cout << "static double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};" << endl; 
	for ( int i = 0; i < 5; i++ )
	{
	   cout << "p[" << i << "] : ";
	   cout << p[i] << endl;
	}
	
	return 0;
}

double* return5ArrayNotST(){
	double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};
	cout<<"arr in return5ArrayNotST() : addr " << arr << endl;
	return arr;
}

double* return5ArrayST(){
	static double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};
	cout<<"arr in return5ArrayST() : addr " << arr << endl;
	return arr;
}

執行結果:

arr in return5ArrayNotST() : addr 0x6ffda0
使用 p : addr 0x6ffda0 指標接收的 not static array
double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};
p[0] : 6.12209e-317
p[1] : 4.94066e-324
p[2] : 2.17389e-322
p[3] : 6.12209e-317
p[4] : 3.62622e-317

arr in return5ArrayST() : addr 0x472020
使用 p : addr 0x472020 指標接收的 static array
static double arr[5] = {6.0, 6.1, 6.2, 6.3, 6.4};
p[0] : 6
p[1] : 6.1
p[2] : 6.2
p[3] : 6.3
p[4] : 6.4

Refferences:
https://www.runoob.com/cplusplus/cpp-arrays.html
https://ecomputernotes.com/what-is-c/array/static-arrays

文章會隨時改動,要到部落格園裡看偶。一些網站會爬取本文章,但是可能會有出入。
轉載請註明出處哦( ̄︶ ̄)↗ 
https://www.cnblogs.com/asmurmur/