網(wǎng)站建設(shè)免費(fèi)教程我是seo關(guān)鍵詞
字節(jié)與字符
計(jì)算機(jī)內(nèi)存的基本單位是位(bit),字節(jié)(byte)通常指的是8位的內(nèi)存單元,從這個(gè)意義上來(lái)說(shuō),字節(jié)指的就是描述計(jì)算機(jī)內(nèi)存量的度量單位。
C++對(duì)字節(jié)的定義則有些不同,C++字節(jié)由至少能夠容納實(shí)現(xiàn)的基本字符集的相鄰位組成,也就是說(shuō),可能取值的數(shù)目必須等于或超過(guò)字符數(shù)目。最開(kāi)始的基本字符集ASCII由于只支持拉丁字符,可以用8位來(lái)容納,因此ASCII編碼是1個(gè)字節(jié)表示一個(gè)字符。但是在國(guó)際編程可能需要使用更大的字符集,即Unicode,根據(jù)編碼方式可以分為UTF-8(變長(zhǎng)編碼,使用1-4個(gè)字節(jié)表示一個(gè)字符)、UTF-16(變長(zhǎng)編碼,使用2或4個(gè)字節(jié)表示一個(gè)字符)、UTF-32(定長(zhǎng)編碼,使用4個(gè)字節(jié)表示一個(gè)字符)。
英文字符和漢字字符在UTF-8編碼環(huán)境下,測(cè)試結(jié)果如下:
#include <iostream>
#include <cstring>using namespace std;int main()
{char a = 'a';cout << a << endl; // 輸出:a// 1、‘中’字符超出了char單個(gè)字節(jié)的存儲(chǔ)范圍char b = '中'; // 編譯告警: overflow in conversion from 'int' to 'char' changes value from '14989485' to ''\37777777655'' [-Woverflow]cout << b << endl; // 輸出:亂碼// 2、‘中’字符在UTF-8編碼中占用字節(jié)數(shù)為3,char數(shù)組定義為4是為了在末位存儲(chǔ)結(jié)束符‘\0’// char bs1[2] = "中"; //編譯報(bào)錯(cuò):error: initializer-string for array of chars is too long [-fpermissive]char bs2[4] = "中";cout << bs2 << endl; // 輸出:中cout << strlen("中") << endl; // 輸出:3return 0;
}
整型
常用的整數(shù)類(lèi)型有char、short、int、long、long long,根據(jù)是否能存儲(chǔ)負(fù)值,又可以進(jìn)一步劃分為有符號(hào)整型和無(wú)符號(hào)整型。
由于系統(tǒng)環(huán)境或編譯器環(huán)境不同,每種整型所占的字節(jié)數(shù)可能會(huì)有差異,此處以64位編譯器為例,舉例說(shuō)明整型的取值范圍:
類(lèi)型 | 占用字節(jié)數(shù) | 取值范圍 |
---|---|---|
signed char | 1 | -2^7 ~ 2^7-1 |
unsigned char | 1 | 0 ~ 2^8-1 |
short | 2 | -2^15 ~ 2^15-1 |
unsigned short | 2 | 0 ~ 2^16-1 |
int | 4 | -2^31 ~ 2^31-1 |
unsigned int | 4 | 0 ~ 2^32-1 |
long | 4 | -2^31 ~ 2^31-1 |
unsigned long | 4 | 0 ~ 2^32-1 |
long long | 8 | -2^63 ~ 2^63-1 |
unsigned long long | 8 | 0 ~ 2^64-1 |
擴(kuò)展1:為什么無(wú)符號(hào)類(lèi)型和有符號(hào)類(lèi)型的最大值相比會(huì)多一個(gè)2次方?
計(jì)算機(jī)內(nèi)存儲(chǔ)數(shù)據(jù)是使用二進(jìn)制來(lái)表示的。有符號(hào)類(lèi)型的最高位會(huì)被用為符號(hào)位,而無(wú)符號(hào)類(lèi)型則多了最高位用來(lái)表示數(shù)值。
擴(kuò)展2:為什么在有符號(hào)類(lèi)型中負(fù)數(shù)取值范圍會(huì)比正數(shù)多一位?
計(jì)算機(jī)內(nèi)是使用補(bǔ)碼來(lái)存儲(chǔ)整數(shù)的(正數(shù)補(bǔ)碼是它本身,負(fù)數(shù)補(bǔ)碼=對(duì)應(yīng)正數(shù)原碼取反+1)。以signed char類(lèi)型為例,從概念上來(lái)說(shuō),0數(shù)值是可以分為+0(00000000)和-0(10000000)的,而這時(shí)候我們已經(jīng)選擇用+0來(lái)表示數(shù)字0了,-0就可以用于表示其他值,將-0采用補(bǔ)碼規(guī)則是映射到-128的(正數(shù)128原碼為010000000,取反為101111111,再+1為110000000,截掉前面的溢出位1結(jié)果為10000000),因此自然而然就用于表示-128了。
bool
bool類(lèi)型用于表示邏輯上的真和假,取值范圍為字面值true和false,其可以提升為int類(lèi)型——true轉(zhuǎn)為1,false轉(zhuǎn)為0。
另外值得注意的是,任何數(shù)字值或指針值都可以隱式轉(zhuǎn)換為bool值,任何非零值轉(zhuǎn)為true,而零值轉(zhuǎn)為false。
wchar_t
前面提到,程序需要處理的字符集可能無(wú)法用一個(gè)8位的字節(jié)表示,此時(shí)C++有兩種處理方式:一種是編譯廠商可以將char定義為一個(gè)16位的字節(jié)或更長(zhǎng)的字節(jié)(例如,在Java語(yǔ)言中char的長(zhǎng)度就是2個(gè)字節(jié));另一種是使用寬字符類(lèi)型wchar_t來(lái)表示擴(kuò)展字符集(wchar_t是整數(shù)類(lèi)型,具體類(lèi)型取決于系統(tǒng)實(shí)現(xiàn)),通常會(huì)將每個(gè)字符存儲(chǔ)在一個(gè)2字節(jié)的內(nèi)存單元中。
浮點(diǎn)類(lèi)型
常見(jiàn)的浮點(diǎn)類(lèi)型有float(單精度小數(shù))、double(雙精度小數(shù))、long double。float和double的區(qū)別點(diǎn)在于,通常double類(lèi)型能夠表示的范圍更大且精度更高。體現(xiàn)為double能夠保證準(zhǔn)確的有效位更多。
算術(shù)操作符
常見(jiàn)的5種基本算術(shù)操作符分為加(+)、減(-)、乘(*)、除(/)、取余(%)。
類(lèi)型轉(zhuǎn)換
在C++ 中,一個(gè) 數(shù)據(jù)類(lèi)型 的值可以被轉(zhuǎn)換成另一種數(shù)據(jù)類(lèi)型的值,這個(gè)轉(zhuǎn)換就叫做類(lèi)型轉(zhuǎn)換。在進(jìn)行類(lèi)型轉(zhuǎn)換時(shí)需要注意的是,如果是向上轉(zhuǎn)型的轉(zhuǎn)換(例如,float轉(zhuǎn)double,int轉(zhuǎn)long)通常是安全的,但如果是向下轉(zhuǎn)型的轉(zhuǎn)換(例如,long轉(zhuǎn)int,double轉(zhuǎn)float,浮點(diǎn)數(shù)轉(zhuǎn)整數(shù))就有可能會(huì)產(chǎn)生截?cái)嗷蚓葋G失問(wèn)題。
在C++ 中,按轉(zhuǎn)換方式也可以大致劃分為兩種類(lèi)型轉(zhuǎn)換——隱式轉(zhuǎn)換和顯式轉(zhuǎn)換。
隱式轉(zhuǎn)換
由編譯器自動(dòng)完成的類(lèi)型轉(zhuǎn)換稱(chēng)為隱式轉(zhuǎn)換,也稱(chēng)為自動(dòng)轉(zhuǎn)換。
例如,在計(jì)算表達(dá)式時(shí),C++會(huì)將bool、char、unsigned char、signed char和short值轉(zhuǎn)換為int,這些轉(zhuǎn)換也被稱(chēng)為整型提升。
顯式轉(zhuǎn)換
當(dāng)用戶手動(dòng)將數(shù)據(jù)從一種類(lèi)型更改為另一種類(lèi)型時(shí),這稱(chēng)為顯式轉(zhuǎn)換,主要有以下三種方式:
-
C 樣式類(lèi)型轉(zhuǎn)換(也稱(chēng)為轉(zhuǎn)換符號(hào))
-
函數(shù)符號(hào)(也稱(chēng)為舊的 C++ 樣式類(lèi)型轉(zhuǎn)換)
-
類(lèi)型轉(zhuǎn)換運(yùn)算符(
static_cast
、dynamic_cast
、const_cast
、reinterpret_cast
)
#include <iostream>using namespace std;int main()
{int num1 = 10;short num2 = (short)num1; // 1、C風(fēng)格轉(zhuǎn)換int num3 = 10;long num4 = long(num3); // 2、舊的C++風(fēng)格轉(zhuǎn)換int num5 = 10;unsigned int num6 = static_cast<unsigned int>(num5); // 3、使用了C++的類(lèi)型轉(zhuǎn)換運(yùn)算符return 0;
}