20240712
最近開始看候捷的c++影片,影片是從類開始講的,過程中發現很多c的知識有點忘了,而且c++也有很多新的語法特性。因此看完前幾個影片後花點時間過一下c++ primer前六章,記錄一下需要學習的c++新特性和程式碼規範。
- 學引用時有點亂,抽時間搞一下值型別的總結
#第二章
基本型別
long long型別:64位
- 數值不為負時使用unsinged,這裡尤其要注意迴圈的使用
錯誤例子:
//死迴圈程式碼
for(unsigned a =10; a>=0; a--)
-
最優先使用的型別:整數int,浮點數double,超越int範圍long long
-
char在一些機器上是有符號的而一些上是無符號的,因此使用時要明確指定signed char或者unsigned char
變數
-
字面值常量,其形式和型別決定它的資料型別,可以使用字首或者字尾進行指定
-
c++11新特性,列表初始化
-
統一語法:使用花括號
{}
進行初始化。 -
自動避免窄化轉換:在列表初始化中,如果初始化過程會導致資料丟失(如,從 double 到 int 的轉換),編譯器會報錯。
int a{1.1};
-
適用於所有型別:包括 POD(Plain Old Data)型別、聚合型別、類型別等。
- 變數的宣告與定義:用於分離式編譯
-
變數宣告規定變數的型別與名字,使用關鍵字 extern
-
定義則在宣告的基礎上為之申請儲存空間
extern int a;/宣告
int a;//宣告並定義
extern int a = 1;//定義
變數只能被定義一次,但能夠進行多次宣告。在多個檔案中使用同一個變數時,其定義只能出現在一個檔案中,其他使用時需進行宣告。
- 型別檢查:c++作為靜態型別語言,編譯器在編譯階段對變數進行型別檢查,因此在使用變數時必須進行宣告,也就是說賦予其型別。
- 注意作用域與作用域運算子
複合型別
這裡由於&,*這兩個符號的多重意義,在作為宣告的一部分出現時最好和資料型別寫在一起
引用
c++11中分為左值引用、常量左值引用、右值引用。這裡先只學習左值引用
- 左值引用(即通常意義下的引用)
語法:
int a=1;
int& refa1=a;//refa是對a的引用
int b=1;
-
引用即別名:引用不是新定義一個變數,而是給已存在的變數取了一個別名,它和它引用的變數共用同一塊記憶體空間。引用只能繫結物件,而引用本身不是物件,是別名。
-
引用在定義時必須初始化,而不能先宣告再賦值。而且型別必須嚴格匹配。只能繫結左值而不能繫結。
int& refa2; refa = 2a;//報錯 double& dref = a;//報錯 int& ref10 = 10;//錯誤,10為字面值常量,右值 string str = "abc"; string &s = str;//正確。字串字面值為左值
-
引用不能重新繫結
&refa1=b;//報錯 lvalue required as left operand of assignment,=的左值是一個常量
-
一個變數可以有多個引用,同時一個引用也可以繼續引用。
int& refa2=a;//正確 int& ref=refa1;//正確。refa1即使a的別名,均會與a進行繫結
指標
- 語法:資料型別* 指標變數名;
指標是一個變數,儲存另一個變數的記憶體地址。宣告中指標的型別用於指定它所指向物件的型別
int a=1;
int* p1;
p1 = &a;//&作為取址符,p中存放a的地址。因此p是一個指向int的指標
p1 = a;//報錯
double* p2 = &a;//報錯
std::cout<<*p1;//輸出1,解引用符*來訪問指標指向的物件。
*p1 = 2;
std::cout<<a;//輸出2
- 指標值總會是下列四種狀態之一:
-
指向一個物件的地址
-
指向緊鄰物件所佔空間的下一個位置
-
空指標,意味著指標沒有指向任何物件。其地址為0,任何程式資料都不會儲存在地址為0的記憶體塊中,它是被作業系統預留的記憶體塊。
int* p = NULL; int* p = nullptr;//優先使用 int* p = 0; std::cout<<p;//輸出0
-
無效指標(野指標),上述情況之外的其他值。未經初始化的指標就是個無效指標,任何一個指標變數在做解地址操作前,都必須保證它指向的是有效的、可用的記憶體塊,否則會出現無法預料的錯誤,而編譯器無法檢查出此類錯誤。所以在定義指標變數的時候一定要進行初始化。如果實在是不知道指標的指向,則初始化為空指標。
-
void* 指標
void* 可以存放任何型別的地址,而不能訪問其物件
int a=1; void* p = &a; std::cout<<p;//正確,輸出a的地址 std::count<<*p;//報錯 'void*' is not a pointer-to-object type
-
指向指標的指標
透過*的個數區分指標的級別,
int a = 1; int* p = &a; int** pp = &p;
-
指向指標的引用
int i = 1; int* p = nullptr; int*& r = p;//從右往左讀,&說明r是一個引用,*說明r引用的是一個指標,int說明r引用的指標的型別是int r = &i;//相當於令p指向了i; *r = 0;//將i的值改為0;