# 指標的概念

指標是一種數據類型,指標與內存單元的地址密切相關。

# 內存單元

內存:由內存單元構成

# 內存單元的地址與內容

內存單元的地址:指內存單元的編號
內存單元的內容:存放在內存單元中的數據

# 內存單元的直接與間接訪問

在 C/C++ 語言中,每個變數都分配有確定的內存空間。
使用變數名可直接訪問內存中的數據;
通過變數的地址也可間接訪問內存中的數據。

# 地址與指標

定義一個變數,系統按變數類型為變數分配不同數目的內存單元,將其第一個內存單元的地址作為變數的地址。如: int a;
在 C/C++ 中,允許定義一種特殊變數,用於存放某變數的地址。
現假設變數 pta 中存放著整數變數 a 的地址。 pta=&a;
pta 與變數 a 之間的關聯,形像地表示為: pta->a
讀作: pta 指向 a
其中: -> 為指標示意符。
由此,我們說 pta 中存放的是指向變數 a 的指標。即 pta 是一個指標變數。

將存放 “地址” 的變數稱為指標變數,這裡的 “地址” 就是指標。
因此,變數的地址就是變數的指標。

# 指標類型的主要用途

  1. 參數傳遞
    指標作參數可以實現參數按引用傳遞的功能。
  2. 動態分配
    利用動態分配可構建動態數組,動態數組需要藉助指標實現。
  3. 數據結構
    創建可伸縮的數據結構,如鍊表、棧與隊列、樹和圖等。
  4. 多態處理
    面向對象編程中 “運行多態性” 的處理是利用指標與引用實現的。

# 指標變數的使用

變數有地址,指標變數可以存放變數的地址。
當指針變數中存放某個變數的地址後,我們就說該指標變數指向這個變數。

# 定義指標變數

即給指標變數分配內存空間

<資料型態> *<變數名>
  • * 是指標類型變數的標誌符號。
  • <變數名> 為指標變數名(構成同標識符)。
  • <資料型態> 為指標變數所指向變數的資料型態。
  • <資料型態> * 表示指標類型。

# 初始化

  1. 在定義指標變數的同時為指標變數提供初值。
    如: int a=5,*pta=&a;
    其中 a 的初值為 5pta 的初值為整型變數 a 的地址
    即,指標變數 pta 指向變數 apta->a
  2. 使用賦值語句為變量提供初始值
    上述定義語句: int a=5,*pta=&a;
    與下面語句組的功能是等效的。
int a, *pta; // 先定義變數
a = 5; // 使用賦值語句提供初值
pta = &a; // 使用賦值語句提供初值

pta=&a; 不可寫成: *pta=&a; 因為, *pta 並不表示指標變數 pta ,而表示 pta 所指向的變數 a 。 指針變數與指標變數所指向的變數是兩個完全不同的概念。

# 單元運算子 & *

  • & 取地址運算子
&<變數名> // 獲得該變數內存單元位址
  • * 指標運算子
    也稱為間接訪問運算子
// 表示該指標所指向的變數 
*<指標變數名> 
// 或 
*<指標常數>

如果指標變數 pta 中存放著變數 a 的指標,則 *pta 表示 pta 所指向的變數即變數 a 。這是一種間接訪問的表示。

int a=5,*pta=&a;
*pta=a+8;
cout<<a<<","<<*pta<<endl;
// 在這裡,*pta 是表示 pta 所指的對象,即變數 a。
// *pta 等同於變數 a
// 輸出結果為:13,13
int a=5,*p=&a;
cout<<&a<<endl;//a 的地址 0x23fe4c
cout<<a<<endl;//a 的值 5
cout<<&p<<endl;//p 的地址 0x23fe40
cout<<p<<endl;//p 的值 0x23fe4c
cout<<*p<<endl;//p 所指變數的值 5
  1. *p*(&a) 等價,即就是 ap 是一個指標變數,而 &a 是一個指標常數。
  2. 指標變數的值一定是 “地址”;指標變數所指對象的值不一定是 “地址”。

# 注意

  • 不要訪問沒有被初始化的指標變數
int *p;
cin>>*p;

由於 p 變數為初始化, p 中可能存放一個不確定的單元地址,這時的輸入將會改變原存儲單元的值,造成結果混亂。

  • 指標變數可以有空值,即指標不指向任何變數
    常用符號常數 NULL 表示空指標,其實, NULL 表示的值其實是整數 0 。變異系統約定 0 單元不放存有效數據。

# 函式與指標

一個函式在編譯時被分配一個入口地址,這個入口地址就稱為函式的指標。
在 C++ 中, 函式名代表函式的入口地址。

# 指標作函數的參數

實現地址傳遞,用途如下:

  • 指標作函式參數,這時形參接受的是實參的地址。函式中通過對指針的間接訪問實現參數的按 “引用傳遞” 功能。
  • 設置多個指標參數可從函式中帶回多個結果值。
  • 對於傳遞一塊連續的內存區域數據,傳遞首地址比傳遞數據值,不僅開銷小而且效率高。

# 例子:地址傳遞

編寫交換兩個變數值的函式

// 實現交換的函數
void swap(int *xp, int *yp) // 形參為指標變數
{
	int t;
	t = *xp;
	*xp = *yp; // 交換時透過間接訪問運算子
	*yp = t;
}
// 主函式
int main()
{
	int x=2,y=3;
	cout<<"調用前:x="<<x<<",y="<<y<<endl;
	swap(&x,&y); // 實參為變數的地址
	cout<<"調用後:x="<<x<<",y="<<y<<endl;
	return 0;
}

# 帶回函式中的多個值

計算一維數組元素的平均值,並能帶回數組中的最大值與最小值。

其中:

  • s - 一维数组
  • n - 数组中元素个数
  • max - 指向最大值
  • min - 指向最小值
  • 將平均值作為函數返回值
double faver(int s[],int n,int *max,int *min)
{
	// 變數定義即初始化
	double aver=s[0];
	*max=*min=s[0];
	for(int i=1;i<n;i++)
	{
		aver+=s[i];
		if(s[i]>*max)
		{
			*max=s[i];
		}
		if(s[i]<*min)
		{
			*min=s[i];
		}
	}
	return aver/n;
}
int main()
{
	int a[5]={80,89,67,76,98},max,min;
	double aver;
	aver=faver(a,5,&max,&min); // 調用函式
	cout<<"max="<<max<<"\n"<<"min="<<min<<endl;
	cout<<"aver="<<aver<<endl;
	return 0;
}

# 返回指標的函式

<資料型態> *<函式名>(<形式参數表>)
{
	<語句序列>
}

<資料型態> * - 為函式的返回值類型,是一個指標類型。

# 例子:返回字元串

編寫函式,返回字元串中首次出現的非空格字元開始的字元串。
如: " I am very excited;" 返回 "I am very excited;"

// 返回字元指標的函式
char *noblank(char *str)
{
	while(*str==' ') {
		str++;
	}
	return str;
}
int main()
{
	char *s1=" I am very excited;", *s2;
	s2=noblank(s1);
	cout<<s2<<endl;
	return 0;
}

# 指向函式的指標變數

使用指向函式的指標變數可以存放函式的指標。

<函式返回值類型> (*<指標變數名>) (<形參型態表列>);

函式名就是函式的地址,也就是函式的指標。
例如:定義指向 double 型函式的指標變數,該函式有一個 double 型參數

double (*pf)(double );
pf = sqrt; //pf 指向一個平方根函式

這時,使用 *pf 可以調用該函式。

cout<<(*pf)(2.0)<<endl; // 輸出根號 2 的值,與下方表達式等價
cout<<sqrt(2.0)<<endl;
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay