本博文為本人閱讀c++ primer plus第4章復合型別後做的小筆記,僅記錄本人不熟悉或者容易犯錯的地方指標是乙個變數,儲存的是值得位址,而不是值本身
位址運算子&,可以獲得變數的所在位址
指標名表示的是位址,*
運算子被稱為間接值(indirect value)或者解除引用(dereferencing);簡單來說,使用*
可以獲得指標指向的記憶體位址的值
由指標的說明可以知道,指標的大小和機器的虛擬位址位數相同(因為它的值是位址),例如本人的電腦為64位,那麼指標大小為8個位元組(可用sizeof自己驗證,順便多說一句,記憶體中可定址的最小單位為位元組,sizeof顯示的值單位為位元組);
宣告(int型別指標):int* ptr;
易錯:int* ptr1, ptr2;
建立乙個指標ptr1和乙個int變數ptr2
初始化
int val = 2;
ptr = &val;
在c++中建立指標,計算機會分配用來儲存位址的記憶體,但不會分配用來儲存指標所指的資料的記憶體
long * fellow;
*fellow = 233; // a problem
問題原因
指標的真正用武之地就是在執行時分配未命名的記憶體來儲存值;c語言中使用malloc
來分配,c++使用new
運算子
事例:int * pn = new int
使用new分配的記憶體塊通常和常規變數宣告分配的記憶體塊不同
c++中,值為0的指標稱為空指標(null pointer),c++確保空指標不會指向有效的資料,因此可以用於表示運算子或函式失敗(如記憶體耗盡,無法再使用new分配記憶體)
使用delete,後面加上指向記憶體塊的指標(這些記憶體塊最初由new分配);如下**所示,這只會釋放指標指向的記憶體,但是不會刪除指標ps本身
int * ps = new int;
...delete ps;
注意
在編譯時給陣列分配記憶體稱為靜態聯編(static binding),意味著陣列是在編譯時加入到程式的
在程式執行時選擇陣列的長度,這稱為動態聯編(dynamic binding),意味著陣列是在程式執行時建立的,這種陣列稱為動態陣列
建立動態陣列例子:int * ps = new int[10];
釋放陣列:delete ps;
以上面的例子來說,編譯器不會對ps指標指向10個整數中的第乙個這種情況進行跟蹤,我們需要跟蹤記憶體塊中的元素個數
不能使用sizeof運算子確定動態分配的陣列包含的位元組數
動態陣列的使用和靜態聯編情況下的陣列使用是相似的,用下標即可,例如ps[1]
,指標和陣列這種奇妙的關係下面來學習一下
指標變數增加1,增加的量等於它指向的型別的位元組數,如指向double的指標增加1,那麼數值增加8(如果系統使用8個位元組儲存double),這種結果是很好理解的。
c++將陣列名解釋為位址
雖然指標和陣列名都可以表示位址,但是它們是有區別的
陣列名被解釋為其第乙個元素的位址,但是對陣列名用&
運算子,得到的是整個陣列的位址,可以嘗試一下例子
int a[3];
cout << a << endl;
cout << &a << endl;
cout << a + 1 << endl;
cout << &a + 1 << endl;
實際上,a是乙個int指標(*int
),但是&a
是乙個指向包含3個元素的int陣列(int(*)a[3])
5. 宣告指向整個陣列的指標:int (*ps)[3] = &a;
- `()`不可省略,如果省略,由優先順序規則將使得ps先和`[3]`結合,導致ps是乙個int指標陣列,含3個元素
- 要描述型別,可以去掉宣告中的變數名,如ps的型別是`int(*)[20]`
- 由於ps被設定為`&a`,故`*ps`和a等價,`(*ps)[0]`為a陣列的第乙個元素
先看簡單的例子
char f[10] = "rose";
cout << f << "s are red\n";
可以知道:
顯示字串位址
char a = "test";
cout << (int *) a << endl; // show address
char* b = a;
建立:person * p = new person;
訪問結構成員(如name):
c++管理記憶體的方式
下面作簡單的說明,詳細內容不在本章內容
函式記憶體定義的常規變數使用自動儲存空間,稱為自動變數(automatic variable),它們在函式呼叫時自動產生,函式結束時消亡
自動變數是區域性變數,作用域為**塊
自動變數通常儲存在棧中,lifo(last in first out)的方式,程式執行過程中,棧不斷增大或者減少
靜態儲存整個程式執行期間都存在
宣告方式
new和delete的方式更加靈活,它們管理乙個記憶體池,在c++中稱為自由儲存區(free store)或者堆(heap),該記憶體池中用於靜態變數和自動變數的記憶體是分開的
使用new的資料的生命週期不受程式或者函式的生存時間控制
建立並初始化:person * class[3] = ;
訪問成員:class[n]->name;
(0 <= n <= 2)
還可以建立指向上述陣列的指標:person ** t = class;
訪問成員(以name為例子):(*(t+n))->name;
如果不理解上面的內容,個人認為可以大致畫出一下幾種情況在記憶體中的情況,然後就能很好理解了(可以先用**輸出某乙個變數的位址或者值)
int a[2];
int * b = new int[2];
int ** c = new int * [2];
for (int i = 0; i < 2; i++) c[i] = new int[2];
int d[2][2];
c 學習之 指標和自由儲存空間
1.申明和初始化指標 int p1 這表明 p1的型別為int 由於 操作符被用於指標,因此p1變數本身必須是指標。可以這樣說,p1是指標 也即是位址空間 p1是int,而不是指標 順便說一下,操作符兩邊的空格是可選的 傳統上c程式設計師用 int p1,而很多c 程式設計師用int p1 可以在申...
8 C 指標和自由儲存空間
8 c 指標和自由儲存空間 電腦程式在儲存資料時必須跟蹤3中基本屬性。指標是 乙個變數,其儲存的是值得記憶體位址 對於常規變數的位址,只需要對變數應用位址運算子 就可以獲得它的位置 例如,如果home是乙個變數,那麼 home就是他的位址。include stdafx.h include 引用庫函式...
指標和自由儲存空間 陣列 指標算術
第4章,第7 8節 指標和自由儲存空間 是變數,儲存的是值的位址 int p1,p2 中 p1表示指標,而p2表示整型變數 指標本身的長度通常相同 建立時,會分配用來儲存指標位址的記憶體,但不會分配用來儲存指標所指向的資料的記憶體 指標不是整型,不能簡單地將整數賦給指標 new是從heap或free...