17. 基本數據類型:布爾型(_Bool type)
_Bool 型是 C99 添加的,用於表示布爾值,亦即是表示邏輯真(true)和邏輯假(false)。因為 C 用 1 表示 true ,0 表示 false ,所以 _Bool 實際上是整數類型。理論上 _Bool 只需要 1 bit 存儲單元,因為1 bit 就足以表示 0 和 1 。事實上,_Bool 是無符號整型,一般占用 1 字節。例如: _Bool flag = 1;flag = 0; 包含標准頭文件 stdbool.h 後,我們可以用 bool 代替 _Bool ,true 代替 1 ,false 代替 0 。例如: bool flag = true;flag = false; 這麼做是為了和 C++ 兼容。 注意:stdbool.h 是 C99 添加的。18. 基本數據類型:浮點類型
1. float, double, 以及 long double 前面所說的數據類型只能用於處理整數。如果我們需要使用小數,就要使用浮點類型(floating-point)。C 提供了三種浮點類型:float, double以及 long double。, C 標准要求 float 類型至少要能精確表示到小數點後6位,並且整數部分的表示范圍至少要達到 10-37 -- 10+37。float 一般是 32 位的。 C 標准規定double 類型的整數部分的最小表示范圍和 float 一樣,都是 10-37 到 10+37,但是它要求 double 類型的小數部分至少要能精確到小數點後 10 位。double 通常是 64 位的。 C 還提供了 long double 類型,目的是提供一種比 double 更加精確的類型。然而,C 標准僅僅規定 long double 至少要和 double 一樣精確。 2. 聲明浮點型變量 浮點型變量的聲明和初始化與整型變量一樣。例如: float f_1, f_2;double d_1;float f_3 = 6.63;long double ld_1; 3. 浮點型常量 浮點型常量有多種寫法。其基本形式為:首先寫整數部分(可以帶符號),接著寫小數部分,然後寫 e 或者 E,最後再寫一個有符號整數。例如: +1.2E+5
1.5e-9
-5.0e10 其中 e 或 E 被稱為階碼標志,e 或 E 後面的有符號整數被稱為階碼。階碼代表 10 的階碼次方。例如:+1.2E+5 的值是 1.2 * 105。假設 A 為 e 前面的部分,N 是 e 後面的部分,則 AeN 等於 A * 10N。此外,正號可以省略不寫。小數部分也不是必需的,也就是說,5e3 也是正確的。階碼標志和階碼也可以不寫,如:13.5。小數點後面,階碼標志之前的那部分整數可以不寫(9.E5),小數點之前的整數也可以不寫(.96e-8),但是不能同時都不寫。例如: 56.
.5
3.14
3e6
.6E-8 注意:浮點型常量中不能有空格!例如: 3.21e -12 /* 有空格,錯! */3.14 e5 /* 有空格,錯! */ 浮點型常量默認是 double 類型的。假設 var_f 是 float 類型的變量,如果有以下語句: var_f = 9.0 * 3.0; 那麼 9.0 和 3.0 都是 double 類型的常量。它們的乘積也是 double 型的。在進行賦值的時候,這個乘積被轉化成 float 類型,然後再賦值給 var_f。 當然,我們也可以指定浮點型常量的類型。在浮點型常量後面添上 f 或者 F,編譯器就會用 float 類型來處理這個常量。例如:1.5f,2.1e6F。在後面添上 l 或者 L 的話,編譯器會用 long double 類型來處理這個常量。例如:4.1l,50.2E5L。最好用大寫 L,因為小寫 l 容易和數字 1 混淆。 C99 新增了一種表示浮點型常量的格式:使用十六進制前綴(0x 或 0X,0 是數字 0,不是字母 o ),用 p 或 P 代替前面所說的 e 或 E,而且階碼代表的是 2 的階碼次方。例如: 0xb.1ep5 其中 b 等於十進制中的 11, .1e等於 1/16 加 14/256, p5 等於 25,也就是 512。這個浮點型常量轉換成十進制就是:(11 + 1/16 + 14/256)*25 = 5692 注意:並非所有編譯器都支持 C99 新增的這種格式! 4. 輸出浮點數 格式限定符 %f 命令 printf 函數以十進制形式輸出 float 和 double 類型的浮點數;%e 命令 printf 函數以指數形式輸出float 和 double 類型的浮點數;%a 或 %A 命令 printf 函數以 C99 新增的那種十六進制格式輸出,但是並非所有編譯器都支持。如果您要輸出 long double 類型的浮點數,請用 %Lf, %Le,%La,或者 %LA。例如: /* showfloat.c – 用兩種形式表示浮點數 */ #include <stdio.h> int main(void){ float var_f = 5.0; double var_df = 3.14e2; long double var_ld = 6.51e-5; printf("%f is equal to %e\n", var_f, var_f); printf("%f is equal to %e\n", var_df, var_df); printf("%Lf is equal to %Le\n", var_ld, var_ld); return 0;} 輸出如下: 5.000000 is equal to 5.000000e+00314.000000 is equal to 3.140000e+020.000065 is equal to 6.510000e-05 注意:以上是我在 Suse Linux 10 下使用 gcc 4.02 編譯運行得到的輸出。如果使用 Dev-C++ 4.9.9.2 編譯運行本程序,則不能正常輸出 var_ld。大概是因為 Dev-C++ 使用的編譯器 gcc 中,long double 是 96 位的,而它使用函數庫中的 printf 函數卻把 long double 當作 64 位的來處理。 5. 浮點數上溢(Overflow)和下溢(Underflow) 假設您的編譯器中,float 最大只能達到 3.4e38,如果有以下語句: float toobig = 3.4E38 * 100.0f;printf("%e\n", toobig); 這必然導致上溢!因為 toobig 無法表示 3.4E38 和 100.0f 的乘積。上溢的後果過去是沒有定義的,不過現在 C 規定如果發生上溢,則產生一個表示無窮大的特殊值。因此,toobig 的值最終會變成一個表示無窮大的特殊值。進而,printf 函數會輸出類似 inf 或者 infinity 的字眼。 對一個絕對值非常小的浮點數進行除法,並且導致這個浮點數的精度降低,稱之為下溢。打個比方,假設 3.1415e-10 除以 10 後,變成 0.3141e-10,這就是下溢。