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,函式指標和指標函式的區別
“函式指標”,函式修飾指標,本質上是個指標。
“指標函式”,指標修飾函式,表示函式的返回值是個指標型別的變數。