六、關於c++的複合類型(四)

指針

1.指針是一個變量,但這個變量與普通變量最大的不同就是普通變量存儲着值,而指針存儲着值的地址而不是值本身。

2.一個變量的地址要怎麼找到呢?這裏使用地址運算符&,可以獲取一個變量的地址,地址一般是一個十六進制表示的整數。

   int a;

   int *b = &a;//這樣就可以得到變量a的地址

3.指針存儲的是變量的地址,所以指針名錶示地址。*運算符被稱爲間接值或解除引用運算符,常用於指針,得到該地址處存儲的值。

   int a = 100;

   int *b = &a;

   *b;  //100

4.聲明和初始化指針

int * a; //這裏我們說的類型是指向int的指針(int *),也可以這麼說,a是指針(地址),*a是int,而不是指針

注:把int *看成一種複合類型,是指向int的指針

5.指針的危害

指針我們可以這樣理解,跟我們普通變量一樣,一開始會分配一塊內存空間,而普通變量在內存空間裏存的是值,而指針變量在分配的內存空間裏存的是另一個變量地址。在C++創建指針時,計算機就給分配了一塊地址,但是這塊地址中存的另一個變量的地址計算機就沒有給分配。

int *a; //分配了指針變量a的內存地址,但這時還不知道這塊地址裏面存的是哪個變量的地址

*a =223323; //*a是指存的變量的值,而上面並沒有指定是哪個變量的地址,所以223323不知道要放到什麼地方,可能就會放到                        我 們有用的內存區域造成數據損壞

所以在指針應用解除引用運算符(*)前,要注意看看指針是不是已經指向一個明確的地址(int *a =&b;)

6.關於不同類型的指針

int *a,b;

double *c,d;

a = &b;(注意不是*a = &b,*a是指所指向內存的值)

c = &d;

sizeof(a);  //4

sizeof(c);  //4 (爲什麼這個是4而不是8,因爲c的類型不是double而是double *,指針是一個地址,所以是4)

sizeof(b);  //4

sizeof(d);  //8

不管是double指針還是int指針都是一個地址,4字節

7.使用new來分配內存

指針的真正用武之地在於運行階段分配未命名的內存以存儲值。在這種情況下就只能用指針來訪問內存。new運算符就是在運行時來分配未命名的內存的。程序員只要告訴new需要爲什麼樣的數據類型分配內存,new就會找到一塊長度正確的內存並返回這塊內存的首地址,而程序員再把這塊地址賦給一個指針(變量)

如:

int *a = new int; //  new int 告訴程序要適合存儲int類型的內存地址,new返回一塊地址的首地址賦給指針變量a

與普通指針作比較

int b;

int *a = &b;

下面這種情況除了可以用指針變量a拿到b的地址還可以用&b拿到這塊內存地址,除了可以用*a拿到這塊地址裏存儲的值,還可以直接用b拿到,而上面的情況只能用a拿到指向的內存地址,*a拿到指向地址存儲的值。

注:new分配的內存塊與普通變量聲明分配的內存塊是不一樣的。普通變量存儲在棧中,而new是從堆或者自由存儲區的內存區域分配內存。

8.使用delect釋放內存

8.1delect和new要配對使用,且delect只能釋放new分配的內存(如果沒有配對使用,將發生內存泄漏,即分配出去的內存將再也無法使用)

int *a = new int;

int *b =a;

delect b; 

首先new分配一塊內存區域,a指針指向這塊內存區域,int *b = a; 聲明一個指針變量b,而我們知道指針變量a其實是一個地址,將一個地址賦給指針變量b,就是讓b指針也指向這塊區域,使用指針a,b都指向同一塊內存區域,delect b;回收這塊區域,因爲delect能釋放new分配的內存,只要這塊內存是new分配的就可以回收,使用delect b沒有問題。

8.2 int * ps = new int;

      delete ps;

delete釋放了ps指向的內存,但是不會刪除指針ps,ps還是可以重新指定一塊內存區域。

9.使用new創建動態數組以及使用指針訪問數組元素

9.1使用new創建動態數組

int * a = new int [10];

new返回第一個元素的地址,再把地址賦給a

同樣也要配對使用delect釋放這一塊內存

delect [] a; 

[]告訴程序要釋放整個數組,而不單單隻釋放a指針指向的元素。

9.2操作動態數組

int *a = new int[3];

創建指針a指向包含10個int值的內存的第一個元素

這時指針就想到於一根手指。int佔4個字節,a+1,表示指針移動到第二個元素,而從a到a+1所指的內存要走的就是一個int的長度,我們可以使用*a拿到第一個元素的值,*(a+1)那到第二個元素的值,*(a+2)拿到第三個元素的值。

還有另一種就是類似數組的訪問方式,a[0]訪問第一個元素相當於*a,a[1]訪問第二個元素相當於*(a+1),a[2]訪問第三個元素相當於*(a+2)

a[0] = 1;

*(a+1) = 2;

這時數組就變成了{1,2,任意值},因爲第三個元素沒有賦值,所以爲任意值

注:*(a+1)和*a+1的區別

*的優先級高於+,*(a+1),是先把指針a向正確方向移動一個類型的長度(這裏是int類型,就是4字節),到達第二個元素,再*訪問該地址存儲的值。而*a+1,由於優先級*a先執行,讀取出當前第一個元素的值,再把值+1。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章