新聞中心
sizeof 運(yùn)算符返回一條表達(dá)式 或 一個(gè)類(lèi)型名字所占的字節(jié)數(shù)。sizeof 運(yùn)算符滿(mǎn)足右結(jié)合律,其所得的值是一個(gè)size_t 類(lèi)型的常量表達(dá)式。
Person person, * p;
sizeof(Person); //存儲(chǔ)Person類(lèi)型的對(duì)象所占空間的大小
sizeof person; //person的類(lèi)型的大小,即 sizeof (Person)
sizeof p; //指針?biāo)伎臻g的大小
sizeof* p; //p 所指類(lèi)型的空間大小,即 sizeof (Person)
sizeof person.age; //Person 的 age成員對(duì)應(yīng)類(lèi)型的大小
sizeof Person::age; //另一種獲取age大小的方式
因?yàn)?sizeof 不會(huì)實(shí)際求運(yùn)算對(duì)象的值,所以即使 p 是一個(gè)無(wú)效(即 未初始化的)指針,也不會(huì)有影響。
在 sizeof 的運(yùn)算對(duì)象中解引用一個(gè)無(wú)效的指針仍然是一種安全的行為,因?yàn)橹羔槍?shí)際上并沒(méi)有被真正的使用。sizeof 不需要真正的解引用指針也能知道它所指對(duì)象的類(lèi)型。
- 對(duì)char 或 類(lèi)型為char的表達(dá)式執(zhí)行sizeof運(yùn)算,結(jié)果為1
- 對(duì)引用類(lèi)型執(zhí)行sizeof運(yùn)算得到被引用對(duì)象所占空間大小
- 對(duì)指針執(zhí)行sizeof 運(yùn)算得到指針本身所占空間大小
- 對(duì)解引用指針執(zhí)行 sizeof 運(yùn)算得到指針指向的對(duì)象所占空間大小,指針不需要有效
- 對(duì)數(shù)組執(zhí)行 sizeof 運(yùn)算得到整個(gè)數(shù)組所占空間大小,等價(jià)于對(duì)數(shù)組中的所有元素各執(zhí)行一次 sizeof 運(yùn)算 并將所得結(jié)果求和。注意:sizeof 運(yùn)算不會(huì)把數(shù)組轉(zhuǎn)換成指針處理
- 對(duì) string 對(duì)象 和 vector對(duì)象 執(zhí)行sizeof 運(yùn)算 只返回該類(lèi)型固定部分的大小,不會(huì)計(jì)算對(duì)象中的元素占用了多少空間。
如果兩種類(lèi)型可以相互轉(zhuǎn)換,那么他們就是關(guān)聯(lián)的。
C++ 不會(huì)直接將兩個(gè)不同類(lèi)型的值相加,而是先根據(jù)類(lèi)型轉(zhuǎn)換規(guī)則設(shè)法將運(yùn)算對(duì)象的類(lèi)型統(tǒng)一后再求值。
發(fā)生隱式轉(zhuǎn)換的時(shí)機(jī):
- 在大多數(shù)表達(dá)式中,比 int 類(lèi)型小的整型值首先提升為較大的整數(shù)類(lèi)型
- 在條件中,非布爾值轉(zhuǎn)換成布爾類(lèi)型
- 初始化過(guò)程中,初始值轉(zhuǎn)換成變量的類(lèi)型;在賦值語(yǔ)句中,右側(cè)運(yùn)算對(duì)象轉(zhuǎn)換成左側(cè)運(yùn)算對(duì)象的類(lèi)型
- 如果算術(shù)運(yùn)算 或 關(guān)系運(yùn)算的運(yùn)算對(duì)象有多種類(lèi)型,需要轉(zhuǎn)換成同一種類(lèi)型
- 函數(shù)調(diào)用時(shí)也會(huì)發(fā)生類(lèi)型轉(zhuǎn)換
算術(shù)轉(zhuǎn)換的含義是把一種算術(shù)類(lèi)型轉(zhuǎn)換成另一種算術(shù)類(lèi)型
1. 整型提升整型提升負(fù)責(zé)把小整數(shù)類(lèi)型轉(zhuǎn)換成較大的整數(shù)類(lèi)型。對(duì)于 bool,char,signed char,unsigned char,short 和 unsigned short 來(lái)說(shuō),只要它們所有可能的值都能存在 int 里,它們就會(huì)提升為 int 類(lèi)型;否則提升成 unsigned int 類(lèi)型。
2. 無(wú)符號(hào)類(lèi)型的運(yùn)算對(duì)象如果某一個(gè)運(yùn)算符的運(yùn)算對(duì)象不一致,這些運(yùn)算對(duì)象將轉(zhuǎn)換成同一種類(lèi)型。
如果一個(gè)運(yùn)算對(duì)象是無(wú)符號(hào)類(lèi)型,另一個(gè)是有符號(hào)類(lèi)型,而其中的無(wú)符號(hào)類(lèi)型 不小于 有符號(hào)類(lèi)型,那么有符號(hào)運(yùn)算對(duì)象轉(zhuǎn)換成無(wú)符號(hào)對(duì)象。
如果有符號(hào)類(lèi)型大于無(wú)符號(hào)類(lèi)型。如果無(wú)符號(hào)類(lèi)型的所有值都能存在該有符號(hào)類(lèi)型中,則無(wú)符號(hào)類(lèi)型轉(zhuǎn)換成有符號(hào)類(lèi)型;否則有符號(hào)類(lèi)型轉(zhuǎn)換成無(wú)符號(hào)類(lèi)型。
3. 理解算數(shù)轉(zhuǎn)換bool flag;
char cval;
short sval;
unsigned short usval;
int ival;
unsigned int uival;
long lval;
unsigned long ulval;
float fval;
double dval;
3.14159L + 'a'; // 'a' 提升成int,然后int值轉(zhuǎn)換為 long double
dval + ival; //ival 轉(zhuǎn)換成 double
dval + fval; //fval 轉(zhuǎn)換成 double
ival = dval; //dval 轉(zhuǎn)換成int (舍去小數(shù)部分)
flag = dval; //如果 dval是0 flag為false,否則為true
cval + fval; //cval 提升成 int ,然后 int 再轉(zhuǎn)換成 float
sval + cval; //sval 和 cval 都提升成 int
cval + lval; //cval 轉(zhuǎn)換成 long
ival + ulval; //ival 轉(zhuǎn)換成 unsigned long
usval + ival; //根據(jù) unsigned short 和 int 所占空間的大小進(jìn)行提升
uival + lval; //根據(jù) unsigned int 和 long 所占空間的大小進(jìn)行轉(zhuǎn)換
2. 隱式類(lèi)型轉(zhuǎn)換數(shù)組轉(zhuǎn)換成指針: 在大多數(shù)用到數(shù)組的表達(dá)式中,數(shù)組自動(dòng)轉(zhuǎn)換成指向數(shù)組首元素的指針。
當(dāng)數(shù)組被用作 decltype 的參數(shù),或者作為取地址符 & ,sizeof 以及 typeid 等運(yùn)算符的對(duì)象時(shí),不會(huì)發(fā)生轉(zhuǎn)換。
指針的轉(zhuǎn)換: 常量整數(shù)0 或 字面值nullptr 能轉(zhuǎn)換成任意指針類(lèi)型;指向任意非常量的指針能轉(zhuǎn)換成 void*;指向任意對(duì)象的指針能轉(zhuǎn)換成 const void*
轉(zhuǎn)換成布爾類(lèi)型:如果指針或算數(shù)類(lèi)型的值為0,轉(zhuǎn)換結(jié)果是false;否則為true
轉(zhuǎn)換成常量: 允許將指向非常量類(lèi)型的指針轉(zhuǎn)換成指向相應(yīng)常量類(lèi)型的指針,對(duì)于引用也是這樣。
int i;
const int& j = i; //非常量轉(zhuǎn)換成 const int 的引用
const int* p = &i; //非常量的地址轉(zhuǎn)換成const 的地址
int& r = j, * q = p; //錯(cuò)誤: 不允許const 轉(zhuǎn)換成非常量
類(lèi) 類(lèi)型定義的轉(zhuǎn)換:類(lèi) 類(lèi)型定義由編譯器自動(dòng)執(zhí)行的轉(zhuǎn)換,不過(guò)編譯器每次只能執(zhí)行一種類(lèi) 類(lèi)型轉(zhuǎn)換
3. 顯式轉(zhuǎn)換有時(shí)我們希望顯式的將對(duì)象強(qiáng)制轉(zhuǎn)換為另一種類(lèi)型。雖然有時(shí)不得不使用強(qiáng)制類(lèi)型轉(zhuǎn)換,但這種方法本質(zhì)上是非常危險(xiǎn)的。
static_cast任何具有明確定義的類(lèi)型轉(zhuǎn)換,只要不包含頂層 const ,都可以使用 static_cast。
int i, j;
double slope = static_cast(j) / i; //強(qiáng)制類(lèi)型轉(zhuǎn)換以便執(zhí)行浮點(diǎn)數(shù)除法
當(dāng)需要把一個(gè)較大的算術(shù)類(lèi)型 賦值給一個(gè)較小的類(lèi)型時(shí),static_cast 非常有用。
static_cast 對(duì)于編譯器無(wú)法自動(dòng)執(zhí)行的類(lèi)型轉(zhuǎn)換也非常有用。例如:我們可以使用 static_cast 找回存在于 void* 指針中的值:
int d = 3;
void* ptr = &d;
double* dp = static_cast(ptr);
強(qiáng)制轉(zhuǎn)換的結(jié)果將與原始的地址相等。因此我們必須確保轉(zhuǎn)換后所得的類(lèi)型就是指針?biāo)傅念?lèi)型。
const_castconst_cast 只能改變運(yùn)算對(duì)象的底層 const
const char* pc;
// 正確: 但是通過(guò) p 寫(xiě)值是未定義的行為
char* p = const_cast(pc);
對(duì)于常量對(duì)象轉(zhuǎn)換為非常量對(duì)象的行為,一般稱(chēng)之為“去掉const性質(zhì)”。
如果一個(gè)對(duì)象是 const 常量,再使用const_cast 執(zhí)行寫(xiě)操作就會(huì)產(chǎn)生未定義的后果。
只有 const_cast 能改表表達(dá)式的常量屬性,使用其他的 命名強(qiáng)制類(lèi)型轉(zhuǎn)換 改變表達(dá)式的常量屬性都將引發(fā)編譯器錯(cuò)誤。
const char* cp;
//錯(cuò)誤: static_cast 不能轉(zhuǎn)換掉 const屬性
char* q = static_cast(cp);
static_cast(cp);
//錯(cuò)誤: const_cast 只改變常量屬性
const_cast(cp);
reinterpret_castreinterpret_cast 通常為運(yùn)算對(duì)象的位模式提供較低層次的重新解釋。
int* ip;
char* pc = reinterpret_cast(ip);
//這一句在運(yùn)行時(shí)就會(huì)發(fā)生錯(cuò)誤
string str(pc);
reinterpret_cast 本質(zhì)上依賴(lài)于機(jī)器。要想安全的使用 reinterpret_cast 必須對(duì)涉及 類(lèi)型 和 編譯器實(shí)現(xiàn)轉(zhuǎn)換的過(guò)程都非常了解。
建議:盡量避免強(qiáng)制類(lèi)型轉(zhuǎn)換。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
當(dāng)前題目:C++讀書(shū)筆記——4.表達(dá)式-創(chuàng)新互聯(lián)
標(biāo)題來(lái)源:http://fisionsoft.com.cn/article/epjjh.html