第二章 C 基礎( )

2021-09-20 15:21:50 字數 4589 閱讀 8169

不必在結構名、聯合名、列舉名前加上字首

此外在結構和聯合中還可定義函式

左值指記憶體區域,用變數名進行操作

記憶體區域中的內容則稱為它的右值

指標變數 p所需要的記憶體大小都相同(取決於系統字長),與資料型別無關

p 儲存的位址,實質是某個記憶體區域的首位址

1 空指標
null

0nullptr(c++11引入)

2 void*
使用之前必須顯式的將其轉化為某種資料型別的指標

3 begin() end()
標頭檔案#include

int a=;

begin(a)        返回的是指向a[0]的指標

end(a)        返回的是指向最後元素後一位置的指標

4 new和delete/malloc和free
a.屬性

new/delete是c++關鍵字,需要編譯器支援。malloc/free是庫函式,需要頭》檔案支援c。

b.引數

使用new操作符申請記憶體分配時無須指定記憶體塊的大小,編譯器會根據類》型資訊自行計算。而malloc則需要顯式地指出所需記憶體的尺寸。

c.返回型別

new操作符記憶體分配成功時,返回的是物件型別的指標,型別嚴格與物件匹配,無須進行型別轉換,故new是符合型別安全性的操作符。而malloc記憶體分配成功則是返回void * ,需要通過強制型別轉換將void*指標轉換成我們需要的型別。

d. 分配失敗

new記憶體分配失敗時,會丟擲bac_alloc異常。malloc分配記憶體失敗時返回null。

e.自定義型別

new會先呼叫operator new函式,申請足夠的記憶體(通常底層使用malloc實現)。然後呼叫型別的建構函式,初始化成員變數,最後返回自定義型別指標。delete先呼叫析構函式,然後呼叫operator delete函式釋放記憶體(通常底層使用free實現)。

malloc/free是庫函式,只能動態的申請和釋放記憶體,無法強制要求其做自定義型別物件構造和析構工作。

f.過載

c++允許過載new/delete操作符,特別的,布局new的就不需要為物件分配記憶體,而是指定了乙個位址作為記憶體起始區域,new在這段記憶體上為物件呼叫建構函式完成初始化工作,並返回此位址。而malloc不允許過載。

智慧型指標的作用

程式設計師自己管理堆記憶體可以提高了程式的效率,但是整體來說堆記憶體的管理是麻煩的,c++11中引入了智慧型指標的概念,方便管理堆記憶體。使用普通指標,容易造成堆記憶體洩露(忘記釋放),二次釋放,程式發生異常時記憶體洩露等問題等,使用智慧型指標能更好的管理堆記憶體。

智慧型指標的使用

智慧型指標在c++11版本之後提供,包含在標頭檔案中,shared_ptrunique_ptrweak_ptr

定義形式:

x_ptr p;

x_ptr

p2(p)

; x_ptrp3(

newtype

(x))

;

兩個成員函式:

p.get()    //能夠返回p中儲存的指標

p.swap(p1) //交換指標的內容

智慧型指標與普通指標之間不能夠隨意賦值,不能把智慧型指標指向普通記憶體變數,或者把非智慧型指標賦值給智慧型指標。直接把智慧型指標賦值給普通指標是錯誤的,要通過get()成員函式獲取智慧型指標中的指標後,再賦值給普通指標

同型別的auto_ptr 、shared_ptr智慧型指標之間可以相互賦值,unique_ptr指標之間則不允許相互賦值

auto_ptr(已棄用):

auto_ptr的出現,主要是為了解決「有異常丟擲時發生記憶體洩漏」的問題。如下的簡單**是這類問題的乙個簡單示例。

int

* p =

newint

(100);

trycatch

(exception& e)

當dosomething();部分丟擲異常,將導致指標p所指向的空間得不到釋放而導致記憶體洩露。auto_ptr的引入解決了這類問題。

#include

using

namespace std;

intmain()

智慧型指標被定義後,可以像l2、l3那樣進行解引用,也只能像定義p1、p3那樣在定義智慧型指標的的時候直接分配空間或者用已定義指標進行初始化,或者像l1語句進行同類指標之間的賦值,而不能像l4一樣直接用new為它分配空間

為auto_ptr建立的動態物件,只能有乙個auto_ptr型別的智慧型指標指向它。

當程式結束後,auto_ptr指標會自動被銷毀,不用delete

shared_ptr和unique_ptr:

unique_ptr持有對物件的獨有權,同一時刻只能有乙個unique_ptr指向給定物件(通過禁止拷貝語義,禁止了指標之間的賦值,也不可以用乙個指標來初始化另乙個指標,只有移動語義來實現)。

unique_ptr指標本身的生命週期:從unique_ptr指標建立時開始,直到離開作用域。

離開作用域時,若其指向物件,則將其所指物件銷毀(預設使用delete操作符,使用者可指定其他操作)。

shared_ptr 允許多個該智慧型指標共享第「擁有」同一堆分配物件的記憶體,這通過引用計數(reference counting)實現,會記錄有多少個shared_ptr共同指向乙個物件,一旦最後乙個這樣的指標被銷毀,也就是一旦某個物件的引用計數變為0,這個物件會被自動刪除。

另:weak_ptr

weak_ptr 是為配合 shared_ptr 而引入的一種智慧型指標來協助 shared_ptr 工作,它可以從乙個 shared_ptr 或另乙個 weak_ptr 物件構造,它的構造和析構不會引起引用計數的增加或減少。

引用:就是某一變數(目標)的乙個別名,對引用的操作與對變數直接操作完全一樣。

左值引用:

左值引用的宣告方法:型別識別符號 &引用名=目標變數名;

例:

char ch;

char

&rp=ch;

1)引用僅是變數的別名,而不是實實在在地定義了乙個變數,因此引用本身並不占用記憶體,而是和目標變數共同指向目標變數的記憶體位址.

2)表示式中的取位址符&不再是取變數的位址,而是用來表示該變數是引用型別的變數。

3)定義乙個引用時,必須對其初始化。

4)建立引用時應當型別匹配

5)可以有引用陣列或者陣列元素的引用,但是不能有引用陣列

如下:

int

main()

,*b[10]

;int

(&ra)[10

]=a;

//正確,這是對陣列a[10]的引用

int&&aa=a[0]

;//正確,這是對陣列元素的引用

int*

(&rpa)[10

]=b;

//正確,是對具有10個整型指標的陣列的引用

int&ia[10]

=a;//錯誤,ia變成了引用陣列,每個元素都為引用

}

6)指標與引用

可以建立指標的引用,但不能建立指向引用的指標

定義方式:

int i;

int&

*ip=i;

//錯誤,ip是指向引用的指標

int*pi=

&i;int

*&pr=pi;

//正確,pr是指標的引用

右值引用:

等號右邊應該為乙個計算表示式,不能只有乙個變數

部分內容**其他部落格…具體鏈結不記得了…

第二章 演算法基礎

引言 演算法導論 在本章將向我們介紹乙個演算法設計和分析框架,在後續的章節也將在這個框架的基礎上來分許演算法。名詞解釋 1 偽 偽 就是以最清晰 最簡潔的表示方法來說明演算法,而忽略資料抽象 模組性和錯誤處理的問題 2 迴圈不變式 每次迴圈從陣列a中取出第j個元素插入有序數列a 1 j 1 然後遞增...

第二章 演算法基礎

2.1 插入排序 insertion sort 時間複雜度 o n 對於少量元素的排序,是乙個有效的演算法。為什麼叫插入排序呢?可以模擬撲克牌整牌 將未排序的數字通過遍歷插入到已排好序的數字中的對應位置 如何實現呢 num j 1 key 插入 for int i 1 i n i printf n ...

第二章基礎語法

using system using system.collections.generic using system.linq using system.text using system.threading.tasks 引用命名空間 namespace 2.1csharp程式結構 命名空間或者專案...