回頭再看C 第六天

2021-10-02 13:45:48 字數 3918 閱讀 8757

指標的指標

指標賦值

指標和引用

特殊指標

要理解指標的含義和使用方法,首先要了解計算機的資料儲存。計算機使用多個連續的二進位制位來記錄資料。學過數字邏輯的同學很容易理解,記憶體就是成組的暫存器按規律排列而成,可以簡單的理解為乙個**,每個格仔內儲存乙個二進位制的0或1。按照一定的次序和組合讀取這個**,就可以由二進位制數得到寫入的資訊。

為了準確的讀取資訊,我們需要對這些格仔進行分組和編號,一般是相鄰的八個格仔為一組,也就是乙個位元組,然後對**中的組編號,也就是按次序對位元組編號。這個過程叫記憶體編址。

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-qlfkg7dc-1580870952656)(en-resource://database/435:1)]

c++的指標,就是專門用來存放記憶體位址的資料型別。對於初學者來說可能有些難以理解,但有過一定的程式設計經驗的同學應該能夠體會到使用指標必要性。

嚴格地說,乙個指標是乙個位址,是乙個常量。而乙個指標變數卻可以被賦予不同的指標值,是變數。但常把指標變數簡稱為指標。為了避免混淆,我們約定:"指標"是指位址,是常量,"指標變數"是指取值為位址的變數。定義指標的目的是為了通過指標去訪問記憶體單元。

從指標的意義上來說,指標實際上是指向乙個「資料」,乙個資料結構在記憶體中的儲存都是連續的,而依據指標指向的「資料」的首位址,可以方便的讀取整個「資料」。

在c++語言中,定義指標的方式如下:

《型別名》* 《變數名》

//例如

int* pint;

string* pstring;

float* pfloat;

double* p1, p2;

也有這樣的寫法:

《型別名》 *《變數名》
但不太推薦。相比於後者,前一種寫法能夠更直觀的說明「變數名」是乙個指標,當然,這只是筆者個人的習慣,不必拘泥於此。

大部分時候可以使用sizeof運算子來獲取變數的長度,再依據長度判斷某個變數是指標還是其他資料型別。

一般按照指標指向的物件分類,如果指標指向的物件也為指標,可以按級劃分,按照此原則,c++指標可以分為單級間指標和多級間指標。單級間指標直接指向物件,多級 間指標仍然指向指標。指標的級數由指標定義時的指標識別符號表示,每出現乙個*就增加一級。

指標被定義後,僅依據其指向型別分配了乙個記憶體單元,而沒有對指標進行初始化處理。如果沒有初始化,那麼指標的指向是隨機的、未知的,即野指標。直接引用野指標可能回破壞程式的執行,甚至影響到作業系統的安全。使用指標前必須進行初始化。一般有兩種方法。

可以使用乙個已經被初始化的指標位址來初始化乙個指標,之後兩個指標將會指向相同的單元。如果兩個指標的型別相同,可以直接賦值;否則應轉換為與被初始化指標相同型別的指標。

可以使用已經定義的變數來初始化指標,此時需要用到取位址運算子&。

指標= & 變數;
同樣需要指標和變數對應的型別相同。

3. new分配記憶體單元

指標 = new 型別名;

指標 = new 型別名[n];

其中,[n]表示需要n個"型別名"長度的儲存單元;new返回新分配的記憶體單元位址。當申請完記憶體單元後,如果不再需要就要收回這個記憶體單元,此時需要delete運算子來完成。

delete 指標名;

delete 指標名;

malloc函式:

由c中繼承來的方法。使用malloc/free對來分配和釋放動態記憶體,

extern void* malloc(unsigned int num_bytes);
此函式在標頭檔案malloc.h中,其功能是申請nums_bytes位元組的連續記憶體塊。如果申請成功則返回該塊的首位址;否則返回空指標null。

type* p;

p = (type*)malloc(sizeof(type)* n);

p是type型指標,sizeof(type)是計算乙個type型資料需要的位元組數,n表示需要儲存n個type型資料。(type*)是對malloc的返回值進行強制轉換。該式的含義是申請可以儲存n個type型資料的記憶體塊,並且將塊的首位址轉換為type型賦給p。

當用malloc分配的記憶體不再使用時,應使用free()函式將記憶體塊釋放。

free p;
同delete一樣,free也沒有破壞指標p的內容,只是告訴系統收回這片記憶體單元,可以重新利用。所以free後,最好將p顯式置空指標。

指標作為變數,可以進行運算處理,但c++指標的運算種類很有限,且變化規律受其所指向的型別的制約。

指標只能進行加減兩種算術運算。指標的加減變化規律要受所指向的型別約束。它只能與以整型作為基型別的資料 型別進行運算,或者在指標變數之間。指標的加減運算不是單純的在原位址基礎上加減1,而是加減乙個資料型別的長度。所以,指標運算中"1"的意義隨資料型別的不同而不同。

尤其要注意的是指標的運算要限定在事先申請號的記憶體單元內,最近在做leetcode題目時常遇到越界錯誤,就是忽略了這一點。

兩指標之間只能進行減運算。兩個指標的減法表示計算它們之間的元素個數。如果差為負 數,表示位址高的指標需要後移幾次才能到位址低的指標處。如果是正數,表示位址低的 指標需要移動幾次才能前進到位址高的指標處。這個值實際是指標位址的算術差除以型別 寬度得到的。

指標的關係運算是比較位址間的關係,這包括兩方面:一方面是判斷指標是否為空;另一 方面是比較指標的相對位置。進行關係運算的兩個指標必須指向相同的資料型別

p1==p2:判斷p1和p2是否指向同乙個記憶體位址。

p1>p2:判斷p1是否處於比p2高的高位址記憶體位置。

p1>=p2:判斷p1是否處於不低於p2的記憶體位置。

p1即指向指標的指標,又稱二級間指:

type** p;
按這樣的方式可以定義n級間指,只需在型別名後加上對應數量的『*\』號即可。

很少直接把位址值賦給指標,一般都是利用已定義的變數完成

p1 = &var;      //把var的位址賦給p1

p1 = p2; //把p2的值賦給p1

*p1 = var; //把var放進p1指向的位址

*操作符也叫間接訪問運算子,用來表示指標所指的變數,結合性為從右到左,屬於單目運算。*運算子後跟的必須是指標變數。如果作為左值,則是向指標所指單元中寫入資料。如果作為右值,則是從指標所指單元中讀資料。

&操作符是取位址運算子,表示變數的位址值。可以用於一般變數也可用於指標變數。

引用就是別名或同義詞,它是同一塊記憶體單元的不同名稱。常用於替代傳值方式,傳遞參 數和返回值。具有指標的特點,可節省記憶體複製帶來的開銷。

type &ref=var;
type是型別名稱,&在此不是求位址運算,而是起標識作用,ref是引用的名稱,var是與引用同型別的變數名稱。容易發現,對ref和var使用&運算,得到的位址值是一樣的,即兩個變數使用的是同一塊記憶體空間。

關於引用的詳細內容可以參考引用的用法

無型別指標,沒有型別,只是指向一塊申請號的記憶體單元

void* p;
定義了乙個指標p,但未規定應該按何種格式來解釋其指向的記憶體單元的內容。p本身的儲存空間是定義時就申請好的,但p指向的空間可以到需要時再申請。

如下語句

void x;     //不被允許
void只是說明被定義變數的型別,而不涉及記憶體的分配。

在malloc()函式的宣告格式中,返回值就為void型。這表明malloc只是按照要求的大小分配了記憶體單元,不負責解釋這些記憶體單元的格式。因此,在使用malloc時,一定要用強制類 型轉換,轉換為需要的型別。

空指標就是什麼都不指的指標,一般賦0值或null值。常用於指標的初始化。需要注意的是,空指標不能進行取值(*)操作。

C 第六天學習

一次性儲存或者宣告多個相同型別的變數 陣列 陣列型別 陣列名 new 陣列型別 陣列長度 int nums new int 10 nums 0 1 nums 1 2 nums 2 3 nums 3 4 nums 4 5 nums 5 6 nums 6 7 nums 7 10 nums 8 9 num...

第六天 風氣

第六天 風氣 答 人有了,就得定規矩,否則就是一幫烏合之眾,而不是團隊。1必須朝九晚五。嚴格控制員工手裡有辦公室鑰匙。下班必須準時鎖門,員工準時離開。斷公司外網。要加班必須上級主管簽字,更不准在辦公室留宿,洗澡。這一條很重要,不要讓程式設計師活得像個浪子,精神恍惚,口中神叨,鬍子拉碴,這都是浮動工作...

開課第六天

今天是開課第六天,老師上午沒有講課,講了一上午的題,下午又講了新知識,如下 1 順序結構 從上到下順序進行。2 分支結構 if boolean表示式 else switch 值 case 值 break case 值 break switch 執行流程,switch的值和case的值一一比較,如果一...