這個(gè)練習(xí)是C語言中所有可用的數(shù)據(jù)類型和控制結(jié)構(gòu)的摘要。它也可以作為一份參考在補(bǔ)完你的知識,并且不含有任何代碼。我會通過創(chuàng)建教學(xué)卡片的方式,讓你記住一些信息,所以你會在腦子里記住所有重要的概念。
這個(gè)練習(xí)非常有用,你應(yīng)該花至少一周的時(shí)間來鞏固內(nèi)容并且補(bǔ)全這里所沒有的元素。你應(yīng)學(xué)出每個(gè)元素是什么意思,以及編寫程序來驗(yàn)證你得出的結(jié)論。
int
儲存普通的整數(shù),默認(rèn)為32位大小。
譯者注:
int在32或64位環(huán)境下為32位,但它不應(yīng)該被看作平臺無關(guān)的。如果需要用到平臺無關(guān)的定長整數(shù),請使用int(n)_t。
double
儲存稍大的浮點(diǎn)數(shù)。
float
儲存稍小的浮點(diǎn)數(shù)。
char
儲存單字節(jié)字符。
void
表示“無類型”,用于聲明不返回任何東西的函數(shù),或者所指類型不明的指針,例如void *thing。
enum
枚舉類型,類似于整數(shù),也可轉(zhuǎn)換為整數(shù),但是通過符號化的名稱訪問或設(shè)置。當(dāng)switch語句中沒有覆蓋到所有枚舉的元素時(shí),一些編譯器會發(fā)出警告。
unsigned
修改類型,使它不包含任何負(fù)數(shù),同時(shí)上界變高。
signed
可以儲存正數(shù)和負(fù)數(shù),但是上界會變?yōu)椋ù蠹s)一半,下界變?yōu)楹蜕辖纾ù蠹s)等長。
譯者注:符號修飾符只對
char和*** int有效。*** int默認(rèn)為signed,而char根據(jù)具體實(shí)現(xiàn),可以默認(rèn)為signed,也可以為unsigned。
long
對該類型使用較大的空間,使它能存下更大的數(shù),通常使當(dāng)前大小加倍。
short
對該類型使用較小的空間,使它儲存能力變小,但是占據(jù)空間也變成一半。
const
表示變量在初始化后不能改變。
volatile
表示會做最壞的打算,編譯器不會對它做任何優(yōu)化。通常僅在對變量做一些奇怪的事情時(shí),才會用到它。
register
強(qiáng)制讓編譯器將這個(gè)變量保存在寄存器中,并且也可以無視它。目前的編譯器更善于處理在哪里存放變量,所以應(yīng)該只在確定這樣會提升性能時(shí)使用它。
C使用了一種“階梯形類型提升”的機(jī)制,它會觀察運(yùn)算符兩邊的變量,并且在運(yùn)算之前將較小邊的變量轉(zhuǎn)換為較大邊。這個(gè)過程按照如下順序:
譯者注:
short和char會在運(yùn)算之前轉(zhuǎn)換成int。同種類型的unsigned和signed運(yùn)算,signed保持字節(jié)不變轉(zhuǎn)換成unsigned。
stdint.h為定長的整數(shù)類型定義了一些typedef,同時(shí)也有一些用于這些類型的宏。這比老的limits.h更加易于使用,因?yàn)樗遣蛔兊摹_@些類型如下:
int8_t
8位符號整數(shù)。
uint8_t
8位無符號整數(shù)。
int16_t
16位符號整數(shù)。
uint16_t
16位無符號整數(shù)。
int32_t
32位符號整數(shù)。
uint32_t
32位無符號整數(shù)。
int64_t
64位符號整數(shù)。
uint64_t
64位無符號整數(shù)。
譯者注:當(dāng)用于對類型大小有要求的特定平臺時(shí),可以使用這些類型。如果你怕麻煩,不想處理平臺相關(guān)類型的今后潛在的擴(kuò)展的話,也可以使用這些類型。
下面的模式串為(u)int(BITS)_t,其中前面的u代表unsigned,BITS是所占位數(shù)的大小。這些模式串返回了這些類型的最大(或最?。┲怠?/p>
INT(N)_MAX
N位符號整數(shù)的最大正值,例如INT16_MAX。
INT(N)_MIN
N位符號整數(shù)的最小負(fù)值。
UINT(N)_MAX
N位無符號整數(shù)的最大正值。為什么不定義其最小值,是因?yàn)樽钚≈凳?,不可能出現(xiàn)負(fù)值。
警告
要注意,不要從字面上在任何頭文件中去找
INT(N)_MAX的定義。這里的N應(yīng)該為特定整數(shù),比如8、16、32、64,甚至可能是128。我在這個(gè)練習(xí)中使用了這個(gè)記法,就不需要顯式寫出每一個(gè)不同的組合了。
在stdint.h中,對于size_t類型和足夠存放指針的整數(shù)也有一些宏定義,以及其它便捷類型的宏定義。編譯器至少要保證它們?yōu)槟骋淮笮?,并允許它們?yōu)楦蟮拇笮 ?/p>
int_least(N)_t
至少N位的整數(shù)。
uint_least(N)_t
至少N位的無符號整數(shù)。
INT_LEAST(N)_MAX
int_least(N)_t類型的最大值。
INT_LEAST(N)_MIN
int_least(N)_t類型的最小值。
UINT_LEAST(N)_MAX
uint_least(N)_t的最大值。
int_fast(N)_t
與int_least(N)_t相似,但是是至少N位的“最快”整數(shù)。
uint_fast(N)_t
至少N位的“最快”無符號整數(shù)。
INT_FAST(N)_MAX
int_fast(N)_t的最大值。
INT_FAST(N)_MIN
int_fast(N)_t的最小值。
UINT_FAST(N)_MAX
uint_fast(N)_t的最大值。
intptr_t
足夠存放指針的符號整數(shù)。
uintptr_t
足夠存放指針的無符號整數(shù)。
INTPTR_MAX
intptr_t的最大值。
INTPTR_MIN
intptr_t的最小值。
UINTPTR_MAX
uintptr_t的最大值。
intmax_t
系統(tǒng)中可能的最大尺寸的整數(shù)類型。
uintmax_t
系統(tǒng)中可能的最大尺寸的無符號整數(shù)類型。
INTMAX_MAX
intmax_t的最大值。
INTMAX_MIN
intmax_t的最小值。
UINTMAX_MAX
uintmax_t的最大值。
PTRDIFF_MIN
ptrdiff_t的最小值。
PTRDIFF_MAX
ptrdiff_t的最大值。
SIZE_MAX
size_t的最大值。
這是一個(gè)全面的列表,關(guān)于你可以在C中使用的全部運(yùn)算符。這個(gè)列表中我會標(biāo)明一些東西:
二元
該運(yùn)算符有左右兩個(gè)操作數(shù):X + Y。
一元
該運(yùn)算符作用于操作數(shù)本身-X。
前綴
該運(yùn)算符出現(xiàn)在操作數(shù)之前:++X。
后綴
通常和前綴版本相似,但是出現(xiàn)在操作數(shù)之后,并且意義不同:X++。
三元
只有一個(gè)三元運(yùn)算符,意思是“三個(gè)操作數(shù)”:X ? Y : Z。
下面是基本的算數(shù)運(yùn)算符,我將函數(shù)調(diào)用()放入其中因?yàn)樗咏八銛?shù)”運(yùn)算。
()
函數(shù)調(diào)用。
二元 *
乘法。
/
除法。
二元 +
加法。
一元 +
無變化。
后綴 ++
讀取變量然后自增。
前綴 ++
自增變量然后讀取。
后綴 --
讀取變量然后自減。
前綴 --
自減變量然后讀取。
二元 -
減法。
一元 -
取反,可用于表示負(fù)數(shù)。
它們用于以不同方式和形式訪問數(shù)據(jù)。
->
結(jié)構(gòu)體指針的成員訪問。一元*和.運(yùn)算符的復(fù)合。
.
結(jié)構(gòu)體值的成員訪問。
[]
取數(shù)組下標(biāo)。二元+和一元*運(yùn)算符的復(fù)合。
sizeof
取類型或變量大小。
一元 &
取地址。
一元 *
取值(提領(lǐng)地址)。
它們用于測試變量的等性和不等性。
!=
不等于。
<
小于。
<=
小于等于。
==
等于(并不是賦值)。
>
大于。
>=
大于等于。
它們更加高級,用于修改整數(shù)的原始位。
二元 &
位與。
<<
左移。
>>
右移。
^
位異或。
|
位或。
~
取補(bǔ)(翻轉(zhuǎn)所有位)。
用于真值測試,仔細(xì)學(xué)習(xí)三元運(yùn)算符,它非常有用。
!
取非。
&&
與。
||
或。
?:
三元真值測試,X ? Y : Z讀作“若X則Y否則Z”。
復(fù)合賦值運(yùn)算符在賦值同時(shí)執(zhí)行運(yùn)算。大多數(shù)上面的運(yùn)算符都可以組成復(fù)合賦值運(yùn)算符。
=
賦值。
%=
取余賦值。
&=
位與賦值。
*=
乘法賦值。
+=
加法賦值。
-=
減法賦值。
/=
除法賦值。
<<=
左移賦值。
>>=
右移賦值。
^=
位異或賦值。
|=
位或賦值。
下面是一些你沒有接觸過的控制結(jié)構(gòu):
do-while
do { ... } while(X);首先執(zhí)行花括號中的代碼,之后再跳出前測試X表達(dá)式。
break
放在循環(huán)中用于跳出循環(huán)。
continue
跳到循環(huán)尾。
goto
跳到你已經(jīng)放置label的位置,你已經(jīng)在dbg.h中看到它了,用于跳到error標(biāo)簽。
stdint.h或它的描述,寫出所有可能出現(xiàn)的大小定義。