C Primer 讀書筆記01

2021-10-24 11:55:58 字數 3975 閱讀 3149

陣列與指標

begin 和 end (11)

左值右值:

賦值運算子

遞增和遞減運算子

成員訪問運算子

sizeof

強制型別轉換

範圍 for

區域性靜態物件:將區域性變數定義成 static 型別

函式宣告

initializer_list

列表初始化返回值(c++11)

返回陣列指標

constexpr

assert

疑惑:

「c++ primer」

變數宣告和定義

const

int errnum = 0;

int *const curerr = &errnum; // curerr 將一直指向 errnum

const double pi = 3.14;

const double *const pip = π // pi 是乙個指向常量物件的常量指標

陣列與指標

陣列指標

int (*parray)[10] = &arr;	// parray 指向乙個含有 10 個整數的陣列

int (&arrref)[10] = arr; // arrref 引用乙個含有 10 個整數的陣列

指標陣列

int *ptrs[10];	// 含有 3 個整數的陣列

begin 和 end (11)

int ia = ;

int *beg = begin(ia); // 指向 ia 首元素的指標

int *last = end(ia); // 指向 ia 尾元素的下一位置的指標,這兩個函式定義在 iterator 標頭檔案中

左值

可以出現在operator=左邊

當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)

右值:可以出現在operator=右邊

當乙個物件被用作右值的時候,用的是物件的值(內容)

如果表示式的求值結果是左值,decltype作用於該表示式(不是變數)得到乙個引用型別

int *p = nullptr;

decltype(*p) x; // 解應用得到的結果是左值,所以 x 是 int&

decltype(&p) y; // 取位址運算子生成右值,所以 y 是 int**

賦值運算子

賦值運算子的結果是它的左側運算物件,並且是乙個左值

如果賦值運算子的左右兩個運算物件型別不同,則右側運算物件將轉換成左側運算物件的型別

賦值運算子滿足右結合律

int ival, jval;

ival = jval = 1; // 正確

遞增和遞減運算子

成員訪問運算子

點運算子與箭頭運算子的關係:ptr->mem 等價於 (*ptr).mem

sizeof

sizeof是乙個運算子而不是乙個函式,返回一條表示式或者乙個型別名字所佔的位元組數,返回值為size_t型別。

sales_data data, *p;

sizeof(sales_data); // 儲存 sales_data 型別的物件所佔的空間的大小

sizeof(data); // data 的型別的大小,即 sizeof(sales_data)

sizeof p; // 指標所佔空間大小

sizeof *p; // p 所指型別的空間大小,即 sizeof(sales_data)

sizeof data.revenue // sales_data 的 revenue 成員對應型別的大小

sizeof sales_data& // 即 sizeof(sales_data)

強制型別轉換

static_cast任何具有明確定義的型別轉換,只要不包含底層const都可以使用

double slope = static_cast(j) / i;

const_cast只能改變運算物件的底層const(即指標指向的物件是乙個常量)

const char *pc;

char *p = const_cast(pc); // 去掉了 const 屬性

dynamic_cast

用於動態型別轉換。只能用於含有虛函式的類,用於類層次間的向上和向下轉化。只能轉指標或引用。

向上轉換:指的是子類向基類的轉換

向下轉換:指的是基類向子類的轉換

範圍 for

for (declaration : expression)

statement

expression表示的必須是乙個序列,如花括號括起來的初始值列表、陣列、vector string等,這些型別的共同特點是擁有能返回迭代器的beginend成員

區域性靜態物件:將區域性變數定義成 static 型別

區域性靜態物件在程式執行路徑第一次經過物件定義語句時初始化,並且知道程式終止時才被銷毀,在此期間物件所在的函式結束執行也不會對它有影響。

函式宣告

類似於變數,函式只能定義一次,但是可以宣告多次

initializer_list

一種標準庫型別,用於表示某種特定型別的值的陣列,定義在同名頭檔案中,和vector不同,initializer_list中的元素永遠是常量值,無法改變。

列表初始化返回值(c++11)

vectorprocess() ;

else if (expected == actual) return ;

else return ;

}

返回陣列指標
int (*func(int i))[10];	// func 引數是 int ,返回乙個指向大小為 10 的陣列的指標

auto func(int i) -> int(*)[10]; // c++11 後等價的寫法

constexpr

constexpr函式指能用於常量表示式的函式,該函式的返回型別及所有形參的型別都是字面值型別,且函式體中必須有且只有一條return語句

constexpr int new_sz() 

constexpr int foo = new_sz();

foo初始化時,編譯器把對constexpr的呼叫結果替換成其結果值,且constexpr函式被隱式的指定為內聯函式

內聯函式和constexpr函式可以多次定義,所以可以將其定義在標頭檔案中

assert

assert是一種預處理巨集,當assert(expr)求值為假時,assert輸出資訊並終止程式,否則宣告也不做

如果定義了ndebug,則assert什麼也不做,編譯時可以使用cc -d ndebug main.c來定義預處理變數

assert應該僅用於驗證那些確實不可能發生的事情

疑惑:習題 6.14 迭代器為何不能作為引用傳遞

C primer 讀書筆記

第2 章 變數和基本型別 1 變數直接初始化和變數 複製初始化 int ival 1024 direct initialization int ival 1024 copy initialization 初始化不是賦值 2 內建型別復 制初始化和直接初始化幾乎沒有區別 但 對類型別物件來 說,有些初...

C Primer讀書筆記

前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...

C Primer讀書筆記

前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...