指標和引用

2021-10-03 18:57:33 字數 3492 閱讀 8052

記憶體位址

程式執行時,**和需要的資料都被儲存在記憶體中

記憶體是有序的位元組序列,每個位元組都有唯一的位址,使用該位址可以確定位元組的位置,用以儲存和獲取資料

直接訪問和間接訪問

通過變數的名字直接訪問為程式中定義的變數分配的記憶體單元,訪問變數的值

使用變數的記憶體位址找到存放資料的單元,間接訪問其中的內容

指標

指標的特點:

指標持有乙個物件的位址,稱為指標「指向」該物件

通過指標可以間接操縱它指向的物件

定義指標變數的語法

每個指標都有相關的型別,要在定義指標時指出

型別 *指標變數;
指標存放指定型別物件的位址,要獲取物件的位址,使用取位址運算子「&」

如果指標指向乙個物件,則可以通過指標間接訪該物件,使用指標解引用運算子「*」

指向乙個物件的指標有兩個儲存單元與之相關:

乙個是指標自己的儲存單元,裡面存放著所指物件的位址;

另乙個就是指標指向的物件的儲存單元,裡面存放該物件的值。

可以定義存放指標物件的位址的指標

**空指標:**指標值為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...

指標和引用

指標與引用看上去完全不同 指標用操作符 和 引用使用操作符 但是它們似乎有相同的功能。指標與引用都是讓你間接引用其他物件。你如何決定在什麼時候使用指標,在什麼時候使用引用呢?首先,要認識到在任何情況下都不能使用指向空值的引用。乙個引用必須總是指向某些物件。因此如果你使用乙個變數並讓它指向乙個物件,但...