C Primer 學習(第四章)

2021-08-28 07:26:45 字數 2642 閱讀 4427

1.左值和右值

c++中可以這樣簡單的理解左值和右值:能夠取位址的、有名字的就是左值,反之,不能取位址的、沒有名字的就是右值。當乙個物件被用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)。乙個重要的原則是在需要右值的地方可以用左值來代替,但是不能把右值當成左值(也就是位置)使用。當乙個左值被當成右值使用時,實際使用的是它的內容(值)。

2.c++中整除:(-m)/n和m/(-n)都等於-(m/n)。

取餘運算:如果%左邊的運算元為負數時,結果為負數或0;如果%左邊的運算元為正數時,結果為正數或0

例如:

21/-5;//結果為-4,即-(21/5)=-4

-21/5;//結果為-4,即-(21/5)=-4

-21%-8;//結果為-5,而不是3

21%-8;//結果為5,而不是-3

3.因為後置遞增運算子的優先順序高於解引用運算子,所以*p++等價於*(p++)。

因為解引用運算子的優先順序低於點運算子,所以執行解引用運算的子表示式兩端必須加上括號。例如:

*p.size();//錯誤,p是乙個指標,它沒有名為size的成員
4.條件運算子的優先順序非常低,因此當一條長表示式中巢狀了條件運運算元表示式時,通常需要在它兩端加上括號。

注意觀察下述**:

cout<<((grade<60) ? "fail":"pass";//輸出pass或者fail

cout<<(grade<60) ? "fail":"pass";//輸出1或者0

cout《上述**第2行,grade和60的比較結果是《運算子的運算物件,因此如果grade<60為真輸出1,否則輸出0。《運算子的返回值是cout,接下來cout作為條件運算子的條件。所以第2行**等價於下述**:

cout<<(grade<60);//輸出1和0

cout ? "fail":"pass";//根據cout的值是true還是false產生對應的字面值

上述**第3行等價於下述**:

cout<5.sizeof運算子:

sizeof運算子返回一條表示式或乙個型別名字所佔的位元組數,運算子的運算物件有兩種形式:

sizeof (type)

sizeof expr

其中,第2種形式中,sizeof返回的是表示式結果型別的大小。與眾不同的一點是,sizeof並不實際計算其運算物件的值。

sizeof運算子的結果部分依賴於其作用的型別:

知道上面的一些特性,可以利用sizeof做一些事情,例如求陣列中的元素的個數。

例如:

int x[10];

cout《上述**輸出結果為10,其中,sizeof(x)返回陣列中所有元素所佔空間的大小,sizeof(*x)返回陣列中單個元素所佔空間的大小,故相除可以得到陣列中元素的個數。

6.命名的強制型別轉換

格式:cast-name(expression)

其中,type是轉換的目標型別,expression是要轉換的值。cast-name是static_castdynamic_castconst_castreinterpret_cast中的一種。

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

例如:int i=2,j=5;

double slope=ststic_cast(j) / i;

上述**中,把整型的j強制轉化為double型別的j。

又如:

void* p=&d;

double *dp=static_cast(p);

上述**中,由於p是乙個void指標,其可以存放任意型別物件的位址,但是無法操作其所指的物件。通過上述**,就可以把指標強制轉化為double型別的指標。需要注意的是,轉換後得到的型別必須是指標所指的型別。(我的理解是轉換後的double型別應該和指標所指的d的型別一致,即d是double型別,我們才能把void指標轉換為double型別)。

const_cast:const_cast只能改變運算物件的底層const,不能改變物件的型別,只有const_cast能改變物件的常量屬性。

注意下述**:

const char *cp;

char *q=static_cast(cp);//錯誤,static_cast不能改變常量屬性

static_cast(cp);//正確,字串字面值轉換成了string型別,只是改變了型別,沒有改變const性質

const_cast(cp);//錯誤:const_cast不能改變型別,只能改變常量屬性

需要注意的是,如果物件本身不是乙個常量,使用強制型別轉換獲得寫許可權是合法的行為。然而如果物件是乙個常量,再使用const_cast執行寫操作就會產生未定義的結果。

例如:

const int j=3;

int *pj=const_cast(&j);

*pj=4;//錯誤,因為其用去掉const性質的指標去修改乙個原本就是常量的值

C primer(第四章)學習筆記

第四章 表示式 1.表示式由乙個或者多個運算物件operand組成,對表示式求值將得到乙個結果result。字面值和變數是簡單的表示式expression。把乙個運算子operator和乙個或多個運算物件組合起來可以生成交複雜的表示式。一元運算子 取位址符 解引用符 二元運算子 相等運算子 乘法運算...

C PRIMER第四章練習

4.1 先乘除後加減,105 4.2a vec.begin b vec.begin 1 4.3可以接受,可以提高編譯器效率,潛在缺陷只要注意不讓表示式指向並修改同一物件就可以忽略 4.4 12 3 4 5 15 24 4 2 91 4.5a 86 b 18 c 0d 2 4.6if ival 2 為...

C Primer 第四章筆記

左值和右值 乙個左值表示式的求職結果是乙個物件或者乙個函式,然而以常量物件為代表的某些左值實際上不能作為賦值語句的左側運算物件。當乙個物件用作右值的時候,用的是物件的值 內容 當物件被用作左值的時候,用的是物件的身份 在記憶體中的位置 對於某些沒有執行順序的運算子來說,如果表示式指向並修改了同乙個物...