1-7 C++指標

Bean Wang發表於2020-10-13

一、指標的定義與使用

1.指標的作用和定義

通過指標可以間接訪問記憶體。指標的定義語法為:資料型別  *  指標變數名;

int a = 10;
int * p;  // 定義指標p
p = &a;   // 指標p記錄a的地址

2.指標的使用

通過解指標(指標變數前加 *)的方式訪問指標指向的記憶體。

int a = 10;
int * p;  // 定義指標p
p = &a;   // 指標p記錄a的地址

*p = 100; // 解指標,並將p所指向的記憶體內容改為100

cout << a << endl;
cout << *p << endl;
100
100
請按任意鍵繼續. . .

3.指標佔用記憶體空間

指標儲存的為地址資訊,在32位系統中,記憶體地址需要4個位元組進行儲存;在64位系統中,記憶體地址需要8個位元組進行儲存。

int a = 10;
int * p;  // 定義指標p
p = &a;   // 指標p記錄a的地址

cout << sizeof(p) << endl;
cout << sizeof(int *) << endl;
4
4
請按任意鍵繼續. . .

注:float * 、double *等與int *所佔用的記憶體空間一樣(地址需要的記憶體空間一樣)。

二、空指標與野指標

1.空指標

指向記憶體編號為零的指標,一般用於指標定義時的初始化。

int * p = NULL;  // 定義空指標p

注:空指標的記憶體是不可以訪問的。

2.野指標

野指標,也就是指向不可用記憶體區域的指標。如果對野指標進行操作,將會使程式發生不可預知的錯誤,甚至可能直接引起崩潰。造成野指標的三種情況:

  • 指標變數沒有被初始化。任何指標變數剛被建立時不會自動成為NULL指標,為避免這種情況造成的野指標,指標變數在建立時應當被初始化,要麼將其設定為NULL,要麼讓它指向合法的記憶體。
  • 指標指向的記憶體被釋放了,而指標本身沒有置NULL。指標指向的記憶體被釋放了,而指標本身沒有置NULL,此時p既不是NULL指標,它也不指向合法的記憶體塊,因此成為野指標。所以在指標指向的記憶體被釋放後,應該將指標置為NULL。
  • 指標超過了變數的作用範圍。即在變數的作用範圍之外使用了指向變數地址的指標。這一般發生在將呼叫函式中的區域性變數的地址傳出來引起的。這點容易被忽略,雖然程式碼是很可能可以執行無誤,然而卻是極其危險的。區域性變數的作用範圍雖然已經結束,記憶體已經被釋放,然而地址值仍是可用的,不過隨時都可能被記憶體管理分配給其他變數。

三、const修飾指標

1.常量指標:const 資料型別 * 指標變數名

const修飾的是指標,指標指向可以變,但是不可以通過解指標的方式改變指向記憶體的值

int a = 10;
int b = 20;
const int * p = $a;

// 指標指向可以修改
p = &b;

// 指標指向地址的內容不可修改
*p = 100; // 該行是錯誤的

2.指標常量:資料型別 * const 指標變數名

const修飾的是常量,指標指向不可以變,但是可以通過解指標的方式改變指向記憶體的值

int a = 10;
int b = 20;
const int * p = $a;

// 指標指向不可以修改
p = &b;  // 該行是錯誤的

// 指標指向地址的內容可修改
*p = 100; 

3.const 資料型別 * const 指標變數名

const既修飾指標也修飾常量,指標指向不可以變,也不可以通過解指標的方式改變指向記憶體的值

int a = 10;
int b = 20;
const int * p = $a;

// 指標指向不可以修改
p = &b;  // 該行是錯誤的

// 指標指向地址的內容也不可修改
*p = 100; // 該行是錯誤的

四、指標與陣列

通過指標可以訪問陣列中的元素。

int a[5] = {1,2,3,4,5};
int * p = a;

// 獲取陣列的長度
int len = sizeof(a)/sizeof(a[0]);

// 通過指標列印陣列
for(int i = 0; i < len; i++)
{
  cout << *p << endl;
  p++;    // 指標p的資料型別是int *,因此在自增時其指向的地址增加4個位元組
}
1
2
3
4
5
請按任意鍵繼續. . .

五、指標與函式

在函式呼叫時,一般變數使用值傳遞的方式實現實參與形參的值傳遞,此時形參的改變不會影響實參。在函式呼叫時,也可進行地址傳遞,從而實現函式體內改變函式外的變數值。

#inclued <iostream>
using namespace std;

void swap(int * p1, int * p2);

int main()
{
  int a = 10;
  int b = 100;
  swap(&a, &b);

  cout << a << endl;
  cout << b << endl;

  system("pause");

  return 0;
}

void swap(int * p1, int * p2)
{
  int temp = *p1;
  *p1 = *p2;
  *p2 = temp;
}

注:函式傳遞陣列引數時使用地址傳遞。

相關文章