1. 程式人生 > >C/C++之指標

C/C++之指標

知乎上有個關於指標的問題:為什麼說指標是C語言的精髓?答案五花八門,今天來加深對指標的理解。

首先要知道指標的概念,在百科上, 在電腦科學中, 指標 (Pointer)是程式語言中的一個物件,利用地址,它的值直接指向(points to)存在電腦儲存器中另一個地方的值。學習任何東西,明確概念是非常重要的,指標首先是個物件,與類(class)、結構體(struct)、整數變數(int)都是一樣的。指標是一個變數,具有變數的特性,變數要存放在記憶體中,變數有值。它的值儲存著儲存器的一個地址,那麼指標在記憶體中佔用的空間應該是一樣的,因為它存放的是地址,而地址的長度是不變的。無論這個指標指向的地址型別是怎樣的,如整數指標、字元指標、結構體指標、類指標、函式指標,它佔用的記憶體都是相同的。寫個程式使用sizeof驗證。

#include <bits/stdc++.h>
using namespace std;

struct structA {
        int member1;
        int member2;
};

class classB {
        int member1;
        char member2;
};
int main(){
        int* int_ptr;
        char* char_ptr;
        structA* struct_ptr;
        classB* class_ptr;
        cout << "sizeof(int_ptr) = " << sizeof(int_ptr) << endl;
        cout << "sizeof(char_ptr) = " << sizeof(char_ptr) << endl;
        cout << "sizeof(struct_ptr) = " << sizeof(struct_ptr) << endl;
        cout << "sizeof(class_ptr) = " << sizeof(class_ptr) << endl;

        return 0;

}

輸出結果如下:

sizeof(int_ptr) = 8

sizeof(char_ptr) = 8

sizeof(struct_ptr) = 8

sizeof(class_ptr) = 8

我的計算機是64位的,地址長度是64位,所以一個指標變數佔8個位元組。

有了以上這些解釋後,指標的內容也就是這些。

但是,有些人見到指標就害怕,不敢在程式中使用指標,沒有發揮指標的優勢。下面討論一些指標的誤區和使用。

1,陣列名實質上是指標?

以前聽到過這樣一句話“陣列名實質上是指標”,驗證這句話是否正確,用事實說話就可以了,使用sizeof列印陣列名,看長度是否等於地址長度,然後列印陣列名,值是否是地址。

#include <bits/stdc++.h>
using namespace std;
int main(){
        int a[3] = {1,2,3};
        cout << "sizeof(a) = " << sizeof(a) << endl;
        cout << "a = " << a << endl;
        char s[3] = "ab";
        cout << "sizeof(s) = " << sizeof(s) << endl;
        cout << "s = " << s << endl;
        return 0;
}

結果:

sizeof(a) = 12

a = 0x22fe40

sizeof(s) = 3

s = ab

表明陣列名不是一個指標,因為sizeof列印的長度並不是地址的長度。而列印字元陣列名的時候,不是地址,而是列印字元陣列的資料。第二行列印內容整數陣列名a,確實是一個地址。但是它不是一個指標,陣列名代表一個數組,由它可以求出陣列型別,陣列大小等,但它本質上不是指標。

2,指標的宣告

假如宣告一個int型別的指標

int* a_ptr; // 1

int *b_ptr; // 2

兩種方式都是正確的,不過我更提倡採用第1種方式。這樣方便理解,ptr的型別是int*,第2種更讓人以為*b_ptr的型別是int,這樣說是沒錯的,使用“*”取指標指向的地址的值,但是第1種更突出a_ptr是一個變數。

函式指標的宣告,在很多優秀的開原始碼中經常會碰到函式指標。

例如 int (*func)(int, int);

函式指標名是func,它指向的函式有兩個引數,都是int,返回值也是int。注意一定要加括號,(*func),不然就是宣告一個指標函式。

有一個函式

int max(int a, int b){

return a > b ? a : b;

}

宣告一個函式指標func後,就可以使用了。

func = max; //表明函式指標func指向函式名為max的函式。

當然你也可以這樣做來賦值,和上面的方式沒有區別。

func = &max; //將函式max的地址給指標func。

(*func)(2,3); //使用函式指標。

我們前面提過,使用“*”來取指標指向的地址的值,現在*func就表明取func指向的“max函式”,取的值是一個“函式物件”。

func(2,3); //使用函式指標。

這種方式也可以得到正確的結果,為什麼這樣也正確?

下面這段話摘自《C++ prime plus》:

3,函式指標和指標函式的區別

“函式指標”,函式修飾指標,本質上是個指標。

“指標函式”,指標修飾函式,表示函式的返回值是個指標型別的變數。