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