記憶體位址
程式執行時,**和需要的資料都被儲存在記憶體中
記憶體是有序的位元組序列,每個位元組都有唯一的位址,使用該位址可以確定位元組的位置,用以儲存和獲取資料
直接訪問和間接訪問
通過變數的名字直接訪問為程式中定義的變數分配的記憶體單元,訪問變數的值
使用變數的記憶體位址找到存放資料的單元,間接訪問其中的內容
指標
指標的特點:
指標持有乙個物件的位址,稱為指標「指向」該物件
通過指標可以間接操縱它指向的物件
定義指標變數的語法
每個指標都有相關的型別,要在定義指標時指出
型別 *指標變數;
指標存放指定型別物件的位址,要獲取物件的位址,使用取位址運算子「&」
如果指標指向乙個物件,則可以通過指標間接訪該物件,使用指標解引用運算子「*」
指向乙個物件的指標有兩個儲存單元與之相關:
乙個是指標自己的儲存單元,裡面存放著所指物件的位址;
另乙個就是指標指向的物件的儲存單元,裡面存放該物件的值。
可以定義存放指標物件的位址的指標
**空指標:**指標值為0時是乙個空指標,不指向任何物件地指標 (0,null)
//生成空指標的方式
int *p1 = 0;
int *p2 = null;
//不能寫成下面的樣子:
int zero = 0;
int *p4 = zero;
指標運算:
同型別的指標可以進行相等(==)或不相等(!=)的比較操作,比較的結果是布林型別
可以進行加或整數值的算術運算
自增、自減運算適用於指向陣列元素的指標
void*指標:
可以持有任何型別的位址值,即通用指標
相關的值是個位址,但是該位址儲存的物件型別不知道
不能操縱void指標指向的物件,只能傳送該位址值或者和其他位址值進行比較
不允許void指標到其他型別指標的直接賦值
靜態(編譯時)分配空間
編譯器在處理程式源**時分配記憶體;
效率高,靈活性差,執行前就要知道程式需要的記憶體大小和型別
動態(執行時)分配空間
程式執行時呼叫執行時刻庫函式來分配記憶體;
占用程式執行時間,更靈活
靜態和動態記憶體分配在語法上的主要區別:
靜態物件是有名字的變數,可以直接對其進行操作;動態物件沒有名字,要通過指標間接地對它進行操作。
靜態物件的空間分配與釋放由編譯器自動處理,動態物件的空間分配與釋放必須由程式設計師顯式地管理。
堆(heap)、自由儲存區、動態儲存區:
系統為所有程式提供了乙個執行時可用的記憶體池,這個記憶體池被稱為程式的自由儲存區或堆
動態記憶體管理方法:
c++通過new和delete運算子進行動態儲存空間的管理
new運算子
在堆上動態分配空間,建立物件,並返回物件的位址
一般將new返回的位址儲存在指標變數中,以便間接訪問堆上的物件。
new表示式的三種形式:
分配單個物件:new 型別 或者 new 型別(初始值)
分配多個連續儲存的物件:new 型別[陣列大小]
定位new,在指定位置分配空間:new (指標) 型別;
delete運算子:
new運算子分配的空間用delete運算子釋放
釋放new分配的單個物件的delete形式
delete 指標;
釋放new分配的陣列的delete形式
delete 指標;
定位new沒有對應的delete表示式
空懸指標
執行delete運算後,指標ip指向的空間被釋放,不能再使用ip指向的記憶體,但是ip這個指標變數自己的儲存空間不受影響
delete後的ip不是空指標,而是「空懸指標」,即指向不確定的單元
delete之後,繼續通過ip間接使用這個單元是非法的,會引起不可預料的執行錯誤
引用又稱為別名,它可以作為物件的另乙個名字;
通過引用可以間接地操縱物件;
在程式中,引用主要用作函式的引數。
引用有型別識別符號和乙個說明符(&)來定義
type& refvariable = leftvalue;
引用必須被初始化,初始值是乙個有記憶體位址的物件
引用一旦初始化,就不能再指向其他的物件,對引用的所有操作都會被應用在它所指向的物件上
引用的初始化和賦值不同
const type *cp; 或者type const *cp;
cp是指向常量的指標,它所指向的記憶體中的內容不可以改變,即*cp的值不能改變
指向非const物件的const指標
type* const cp = initaddressvalue;
cp是常量指標,初始化後值不能改變,指向固定的單元
const限定引用
const引用僅對引用自己可參與的操作進行了限定,對所指向的物件本身是不是常量未作限定。因為指向的物件也可能不是const,所以允許通過其他途徑改變它的值
const限定的左值引用不可修改
const引用可以繫結到const物件
不能用非const引用指向const物件
陣列與指標
使用陣列時一般會轉換為指標
int ia[5];
ia是乙個int*型別的指標常量
ia和&ia[0]都表示陣列第乙個元素的位址
可以使用指針對陣列進行訪問
一維陣列元素在記憶體中按下標順序依次存放
一維陣列a[n]的元素a[i]在記憶體中位址是a+i。
多維陣列在記憶體中按行序儲存
二維陣列a[m][n]的元素a[i][j] 在記憶體中的位址是a+(i*n+j)
使用指標訪問陣列時需要控制指標的範圍,確保指標指向陣列的元素
庫函式begin()和end()
讓指標在陣列上的使用更簡單更安全
在標頭檔案中定義
//在陣列arr 中查詢第乙個負數:
int *pb = begin(arr), *pe = end(arr);
while(pb != pe && *pb >= 0)
++pb;
//逐個輸出陣列元素的迴圈
for(int p = begin(arr); p!= end(arr); ++p)
cout << *p << "\t";
指標和引用,const 指標和const 引用
指標和引用是在使用中經常弄混淆的兩個概念。引用 reference 為物件起了另外乙個名字,用符號 表示。name,例如 int i 1024 int ref i 一般在初始化變數時,初始值會被拷貝到新建立的物件中,然而定義引用時,程式把引用和它的初始值繫結 bind 在一起,而不是將初始值拷貝給引...
指標和引用
一 先看一段 include using namespace std void freeptr1 int p1 void freeptr2 int p2 void main 思考 在 freeptr1 和freeptr2 的比較中,你能發現它們的不同點嗎?二 對 進行解釋 include using...
指標和引用
指標與引用看上去完全不同 指標用操作符 和 引用使用操作符 但是它們似乎有相同的功能。指標與引用都是讓你間接引用其他物件。你如何決定在什麼時候使用指標,在什麼時候使用引用呢?首先,要認識到在任何情況下都不能使用指向空值的引用。乙個引用必須總是指向某些物件。因此如果你使用乙個變數並讓它指向乙個物件,但...