《C Primer Plus》学习笔记之 C数据的属性(一)数据类型

来源:互联网 发布:tensorflow有趣的项目 编辑:程序博客网 时间:2024/05/13 18:01

基本数据类型

按照数据在计算机中的存储方式,数据类型可划分为两个大类:整数(interger)类型浮点数(floating-point)类型
对于人,整数和浮点数的区别在于书写方式,对于计算机,区别在于存储方式

整数类型

整数就是没有小数部分的数,在计算机中以二进制编码存储。

int类型-基本型

有符号整数,取值范围依赖于计算机系统,一般存储于计算机的一个字中,ANSI C规定int类型至少有16位长

声明和初始化

int ten = 10;       //定义声明并初始化

其他整数类型

  • short (int):可能占用比int类型更少的内存,C规定short类型至少有16位长
  • long (int):可能占用比int类型更多的内存,C规定long类型至少有32位长
  • long long (int):可能占用比long类型更多的内存,C规定long long了恶性至少有64位长
  • unsigned (int):值为非负数,可以表示比有符号数更大的数值。
  • unsigned long (int):值为非负数,可以表示比有符号数更大的数值。
  • unsigned long long (int):值为非负数,可以表示比有符号数更大的数值。
    各种整数类型的区别在于所提供数值的范围以及数值是否可以取负值。一般的,short为16位long为32位long long为64位int为16位或32位(由机器的自然字大小决定)。

字符类型

char类型用于存储字母、数字和标点符号之类的字符。

  • 实际上,在计算机中,char类型是以整数类型存储的,计算机用数字编码来处理字符,即用特定的整数表示特定的字符。常用的编码是ASCII码,标准ASCII码使用7位存储单元,范围从0到127;扩展ASCII使用8位存储单元;有的C实现把char当做有符号类型,即-128到127;另一些C实现把char当做无符号类型,即0到255。
  • C保证char类型足够大,以存储其实现所在的系统上的基本字符集;以Unicod字符集等能够表示更多字符的字符集作为基本字符集的平台,应该使用16位甚至32位的char表示方法。C把一个字节(byte)定义为char类型使用的位(bit)数。所以在上述系统中,一个字节是16位或32位,而不是8位。
  • char类型除了用来表示字符以外,还可以用来表示8位小整数。一般用char定义字符,用signed char定义有符号8位整数(-128到127),用unsigned char定义无符号8位整数(0到255)

声明和初始化

/*正确的示例*/char grade = 'A';   //推荐的字符变量声明和初始化方式char grade = 65;    //字符采用ASCII编码,也可以直接初始化位对应的数值,但这是不好的编程风格/*错误的示例*/char grade = A;     //不可以!把A看做一个变量char grade = "A";   //不可以!把"A"看做一个字符串而非字符

字符常量:C将字符常量(例如’A’)视为int型而非char型。
例如在一个int位32位、char为8位的ASCII系统中,代码char grade = 'A'表示’A’作为数值65存储在一个32位单元中,而grade则把65存储在一个8位单元中。
利用这一特性,可以定义一个字符常量’FATE’这将把4个独立的8位ASCII码存储在一个32位单元中。但是,如果把该字符常量赋给一个char变量,那么只有低8位会起作用,因此变量的值为’E’。

转义序列(Escape Sequence)
用单引号表示字符常量只适用于字母、数字和标点符号,而对于一些非打印字符,ASCII使用转义序列来表示。作为字符常量,需要加单引号,若是在双引号中字符串的一部分,则无需加单引号。
'\n':换行符,将活动位置移到下一行的开始处
'\r':回车符,将活动位置移到当前行的开始处

_Bool类型

  • C99引入,用于表示布尔值,即逻辑truefalse
  • C用值1表示true,值0表示false,所以_Bool类型实际上也是一种整数类型,只是原则上它只需要1位来进行存储。

可移植类型 inttypes.h

基本类型的名字不够明确,并不能描述该类型有多少位,除非查看系统文档。为解决该问题,C99提供了一个可选的类型名集合,以确切地描述类型的位数信息。在inttypes.h头文件中,用typedef创建了新的类型名字,要使用这些新的类型名,必须包含该头文件。

  • 确切长度类型(exact width type):名字给出所表示类型的位数
    int16_t,uint32_t(可能为unsigned int,也可能为unsigned long,由编译器来提供同所在系统相一致的头文件,比如ARM Cortex-M3内核的类型定义文件在MDK的安装目录下\Keil\ARM\ARMCC\include\Stdint.h文件中)
  • 最小长度类型(minimum width type):保证所表示类型至少大于指定长度的最小类型
    int_least8_t
  • 最快最小长度类型(fastest minimum width type):一组计算最快的类型集合
    int_fast8_t(定义为系统中对8位有符号数而言计算最快的整数类型的别名)
  • 最大长度类型( maximum width type):系统最大的可能整数类型
    intmax_t,uintmax_t(最大的有符号、无符号整数类型)

整数溢出

C规定无符号整数类型达到最大值时,继续增大将溢出到起始点,即uint8_t类型的整数达到255时,再加1将变成0。
C并没有规定有符号整数类型溢出的规则,因此可能溢出到起始点,即127溢出到-128,也可能出现别的结果。

浮点数类型

浮点数就是有小数部分的数,差不多可以和数学中的实数(real number)相对应。在计算机中将一个浮点数分为小数部分和指数部分分别存储,小数部分用二进制编码,指数部分用2的幂而非10的幂存储。

  • 浮点数可以表示比整数范围大得多的数
  • 对于一些算术运算(比如两个很大的数相减),使用浮点数会损失更多精度
  • 浮点数不能表示所有的实数,只是实际值的近似,因此存在浮点数精度问题
  • 浮点数运算通常比整数运算慢,除非处理器带有专门的浮点运算单元(FPU)

浮点数表示法

类似于科学计数法,称为指数计数法(或e-计数法):1.6e-19(其中e后面是10的指数)
C规定,
float类型至少能表示6位有效数字,取值范围至少为10^-37到10^+37,
通常,系统使用32位存储float类型,其中8位用于表示指数及其符号,24位用于表示尾数(或称为有效数字)及其符号。
double类型至少能表示10位有效数字,取值范围至少为10^-37到10^+37,
通常,系统使用64位存储double类型,
一些系统将多出的32位全部用于尾数部分,这样增加了数值的精度并减小了舍入误差
另一些系统将多出的32位其中一些位分配给指数部分,以容纳更大的指数,从而增加了可以表示的数的范围,
每种分配方法都使得数值至少有13位有效数字,超出C规定的最小标准。
long double类型至少同double类型一样精确。

浮点常量:默认情况下,编译器将浮点常量当作double类型

float some ;some = 4.0 * 2.0;

4.0和2.0被存储为double类型,通常使用64位进行存储,乘积运算使用双精度,结果被截位正常的float长度。这样做能保证计算精度,但是会损失速度。
可以通过f/F后缀使编译器把浮点常量当作float类型,l/L后缀使编译器把浮点常量当作long double类型

浮点数的上溢和下溢

上溢(overflow)

float toobig = 3.4E38 * 100.0f;printf("%e\n",toobig)

C要求为溢出的变量赋予一个代表无穷大的特殊值。
下溢(underflow)
有这样一个数,它具有最小的指数,并且仍具有可以由全部可用位进行表示的最小尾数值。这是能用对浮点值可用的全部精度进行表示的最小数字。现在把此数除以2,通常这个操作将使指数部分减小,但是指数已经达到了最小值,所以计算机只好将尾数部分的位进行右移,空出首位,并丢弃最后一位,这样就损失了一位有效数字,此过程称为下溢。
C将损失了类型精度的浮点数称为低于正常的(subnormal)。
所以把最小的正浮点数除以2将得到一个低于正常的值,如果除以一个足够大的值,将使所有的位都为0。
现在C库提供了用于检查计算是否会产生低于正常的值的函数。
特殊的浮点值NaN(Not-a-Number)
例如asin()函数返回正弦值,但是正弦值不能大于1,所以asin()函数的输入参数不能大于1,否则函数返回NaN值。

浮点数舍入误差

2.0E20加1,并不能得到正确运算,因为2.0E20位2后面20个0,对它加1变化的是第21位,要正确计算至少需要存储21位有效数字,而float型只有6、7位有效数字,因此这个计算注定是不正确的。

类型准换

C对类型不匹配现象比较宽容,当对某个类型的变量赋值时使用了其他类型的值,C会自动对该值进行类型转换以便和变量类型相匹配,这意味着可能会丢失一部分数据。

int cost = 12.99;       //把12赋给cost,将浮点数转换为整数时,C采取结尾的方式,而非四舍五入。float pi = 3.141592653; //把3.14159赋给pi,损失精度,因为float只能保证6位有效数字
0 0
原创粉丝点击