C 语言基础教程(我的C之旅开始了)[七]

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+37float 一般是 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.5f2.1e6F。在后面添上 l 或者 L 的话,编译器会用 long double 类型来处理这个常量。例如:4.1l50.2E5L。最好用大写 L,因为小写 l 容易和数字 1 混淆。

C99 新增了一种表示浮点型常量的格式:使用十六进制前缀(0x 或 0X,0 是数字 0,不是字母 o ),用 pP 代替前面所说的 e 或 E,而且阶码代表的是 2 的阶码次方。例如:

0xb.1ep5

其中 b 等于十进制中的 11, .1e等于 1/1614/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+00

314.000000 is equal to 3.140000e+02

0.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,这就是下溢。

(0)

相关推荐

  • C 语言基础教程(我的C之旅开始了)[七]

    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 后,我

  • C 语言基础教程(我的C之旅开始了)[八]

    19. 基本数据类型:复数类型和虚数类型 C99 新增了复数类型(_Complex)和虚数类型(_Imaginary).简单来说,C99 提供了三种复数类型:float _Complex,double _Complex,和 long double _Complex.对于 float _Complex 类型的变量来说,它包含两个 float 类型的值,一个用于表示复数的实部(real part),另一个用于表示虚部(imaginary part).类似地,double _Complex 包含两个

  • C 语言基础教程(我的C之旅开始了)[十]

    27. 表达式(Expression) 表达式由运算符和操作数组成.单独一个操作数是最简单的表达式.请看以下例子: 9                    -4                    +5                 3 + 6       a * ( b/c - d )             e = 9 / 3           f = ++e % 3 表达式中的表达式称为子表达式.例如:b/c 是 a * ( b/c - d ) 的子表达式. 每个表达式都有一个值,

  • C 语言基础教程(我的C之旅开始了)[六]

    14. 基本数据类型:字符型(上) 1.字符型(char)简介 字符型(char)用于储存字符(character),如英文字母或标点.严格来说,char 其实也是整数类型(integer type),因为 char 类型储存的实际上是整数,而不是字符.计算机使用特定的整数编码来表示特定的字符.美国普遍使用的编码是 ASCII(American    Standard    Code   for    Information   Interchange  美国信息交换标准编码).例如:ASCII

  • C 语言基础教程(我的C之旅开始了)[五]

    12. 基本数据类型:整型(下) 1. 输出各种整数类型的变量 输出不同类型的整数,需要使用不用的格式限定符.输出 unsigned int 类型的整数,要用 %u .输出 long ,要用 %ld:如果要以十六进制或者八进制形式输出,那就用 %lx(或者%lX)或者 %lo.注意:虽然整数常量的后缀使用大写或者小写英文字母都没关系,但是它们格式限定符必须使用小写!如果我们要输出 short 类型的整数,可以在 %d 中间加上前缀 h,也就是%hd:同理,%ho 和 %hx(或者 %hX )分别

  • C 语言基础教程(我的C之旅开始了)[四]

    10. 基本数据类型:整型(上) 1. 整型 int C 语言提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的大小,以及是否可以为负.int 是整型之一,一般被称为整型.    int 代表有符号整数,也就是说,用 int 声明的变量可以是正数,可以是负数,也可以是零,但是只能是整数.标准规定 int 的最小取值范围是 -32767 到 32767.int 的取值范围因机器而异,但是一定要大于或者等于-32767到 32767.一般来说,int 占用一个字的内存空间.因此,字长为

  • C 语言基础教程(我的C之旅开始了)[三]

    7. 第三个 C 程序 首先请看下面这个小程序,试着自己编译运行一下.如果不懂怎么编译,请点击下面的超链接:      编译器使用方法    编译器Dev-C++下载&使用教程 /* circle.c  --  计算圆的面积 */ #include <stdio.h> int main( void )      {          float radius;    /* 圆的半径 */ printf( "Please enter the radius: " ); 

  • C 语言基础教程(我的C之旅开始了)[二]

    3. C 程序的结构 C 程序由一个以上的函数组成,而且必须有 main 函数.此外,C 程序一般还有一些预处理指令.例如 #include 指令.当然并不是必须要有 #include 指令.函数由函数头和函数体组成.函数头由返回值.函数名以及参数列表(可以是void)组成.函数体从 { 开始,以 } 结束.函数体里可以有一系列的语句,每个语句以分号(;)结束.例如: 预处理指令     --〉   #include <stdio.h> 函数头         --〉  int main( v

  • C 语言基础教程(我的C之旅开始了)[九]

    24. +.-.*./.= 的优先级 1. 优先级 和数学一样,C 语言规定先乘除后加减.也就是说,乘法运算符和除法运算符的优先级(Precedence)比加法运算符和减法运算符高.同时,C 语言也规定,如果两个运算符的优先级相同,并且它们之间没有被优先级比它们高或者低的运算符隔开,则它们的运算顺序根据它们在语句中出现的先后而定.大多数运算符都是从左向右进行运算的,不过也有从右向左进行运算的(例如赋值运算符).乘法运算符和除法运算符的优先级相同,加法运算符和减法运算符的优先级相同.因此,以下语句

  • C 语言基础教程(一)颜色加亮

    首先请看下面这个简单的 C 程序,猜猜它会做些什么.猜不出来也没关系,后面会有详细的解说.         #include <stdio.h> int main( void )            /* 一个简单的程序 */         {             int num;                  /* 定义一个名叫 num 的变量 */             num = 1;                  /* 将 1 赋值给 num         */ p

随机推荐