数据类型简介

在上一篇博客中,已经结束了对于C语言最基本的了解,这篇我们来对关键字中的最为重要且最多的数据类型关键字,他们包括:int、short、long、unsigned、char、float、double、_ Bool、_ Complex、_ Imaginary。

每一个程序都离不开数据,我们把数字,字母和文字输入进电脑,希望电脑通过这些数据完成某些任务,我们要学会怎么读取数据以及如何操控数据。

C语言提供两大系列的数据类型:整数类型and浮点数类型。

Tip:以上关键字大都可以分为这两个类型 。

上述程序的功能是将体重转换为白金价值,其中,我们一改往日的变量定义,在本例中使用了浮点型的float变量,用于处理更大范围的数据,float类型可以储存带小数的数字。

变量与常量数据

在一个程序运行过程中没有发生变化的,称之为常量(constant),那么在程序运行过程中可能会被改变或者被赋值的,则称之为变量(variable)。

在上述程序中,weight就是一个变量,14.5833是一个常量。

数据类型关键字

当然不仅是变量与常量不同,不同的数据类型之间也有差异,一些数据类型表示数字,一些数据类型表示字母。如果数据是常量,编译器一般通过程序中的书写形式来识别;但是对于变量而言,我们在程序的开头就要指定它的类型,下图是C语言中的数据类型关键字:

其中,int关键字用来表示基本的整数类型,long、short、unsigned三个关键字,包括新增的signed用于提供整数类型的变式,unsigned short int等;char关键字用于指定字母和其他字符(#¥%*),char类型也可以表示较小的整数;float、double、long double表示带小数点的数;_ Bool类型表示布尔值(true or false), _ Complex 表示复数, _ Imaginary 表示虚数。

Tip:位、字节和字是指计算机数据单元或者存储单元的术语:

位(bit):可以储存0或1,是构建计算机内存的基本模块。

字节(byte):对于几乎所有机器,1字节均为8位,这是字节的标准定义。

字(word):是设计计算机时给定的自然存储单位,会随着计算机的进步而进步,现在基本都是64位。

整数和浮点数

整数:与数学的概念一样,在C语言中,整数是没有小数部分的数,我们需要做的是把十进制的数转换到计算机中的二进制,在8位字节中储存该数字,例如7在二进制中就是00000111。

浮点数:与数学中的实数概念差不多,注意,在一个值后面加上一个小数点,该值就变成一个浮点值了。所以,7是整数,7.00就是浮点数了。显而易见,书写浮点数的方式有很多种,我们主要学习e记数法。

3.16E7表示的是3.16*10^7,7是10的指数。计算机中把浮点数分成小数部分和指数部分来表示,并且分开存储。

我们主要需要理解浮点数和整数的储存方案的不同。

C语言基本数据类型

int类型

C语言中提供了许多的整数类型,为的是方便程序员针对不同的情况选择不同的类型。特别是,C语言中的整数类型可以表示不同的取值范围和正负值,一般大部分情况使用int类型即可。

int类型是有符号整型,其值必须为正负整数或零,一般而言,一个int类型需要占用一个机器字长。早期的16位IBM机一般使用16位来储存一个int值,取值范围(-32768-32767)。现在的个人计算机已经发展到了64位,不过ISO C 规定int的取值范围最小为-32768-32767。

Tip:若是占据16位,为什么不是(-65536-65535),因为一般来说,系统会用首位表示有符号整数的正负号。

声明int变量在此就不再赘述了,以上已经使用很多了。那么在定义了变量之后,就要对其提供对应的值,变量获取值的方法:第一种就是赋值,利用 = 即可;第二种途径是通过函数来获得值(scanf()等函数),最重要的就是第三种方法:初始化变量!

初始化变量就是在定义变量的同时就赋予一个初始值,在int 语句后加上一个 = 和对应的值即可。

简单来说,声明变量就是给变量创建和标记存储空间,并为其指定初始值。

int的常量就比较简单了,一般来说不带小数点的就是int型常量;之后还有long常量和long long常量。

Tip:最好在初始化时不要把初始化的变量和未初始化的变量放在同一条声明中。

printf()函数可以打印int类型的值,%d表明了在一行里打印整数的位置,%d称为转换说明,它指定了printf()应使用什么格式来显示一个值。格式化字符串中的每个%d都与待打印变量列表中相应的int值匹配。这个值可以是int类型的变量、int类型的常量或其他任何值为int类型的表达式。

八进制与十六进制

一般来说,C语言都是假定整型常量是一个十进制数。然而,由于底层是二进制作为基础,实际应用中还是使用八进制和十六进制数,因为8和16都2的幂,但是计算机是无法自行分别各个进制之间的区别的,在C语言中,用特定的前缀表示使用哪种进制。0x或0X前缀表示十六进制值,所以十进制数16表示成十六进制是0x10或0X10。与此类似,0前缀表示八进制。在之后的内容中会详细的讲述进制相关的内容。

Tip:无论使用那种进制来表示,都不会影响数据的存储方式,因为计算机内部还是二进制进行编码。

八进制与十六进制的显示:与%d用来显示十进制类似,以八进制显示数字,使用%o;以十六进制显示数字,使用%x。另外,要显示各进制数的前缀0、0x和0X,必须分别使用%#o、%#x、%#X。

**Tip:在C语言中,八进制和十六进制的常量属于无符号整型(unsigned int)。

其他整数类型

我们初学C语言时,int类型能够满足大多数程序的需求了,当然这小节内容为的是留一个印象。C语言提供3个附属关键字修饰基本整数类型:short、long和unsigned。

short int类型(或者简写为short):占用的存储空间可能比int类型少,常用于较小数值的场合以节省空间。short类型属于有符号类型。

long int类型(long):占用的存储空间可能比int多,适用于较大数值的场合。long也属于有符号类型。

long long int或long long(C99标准加入):占用的储存空间可能比long多,适用于更大数值的场合。该类型至少占64位。

unsigned int或unsigned:只用于非负值的场合。这种类型与有符号类型表示的范围不同。若是16位unsigned,取值范围则是0-65535。

声明方式:这些整数类型的声明方式与int类型并无任何不同。

Tip:八进制和十六进制常量被视为int类型。如果值太大,编译器会尝试使用unsigned int。如果还不够大,编译器会依次使用long、unsigned long、long long和unsigned long long类型。

本小节中我们值得注意的一个问题就是整数是否会溢出的问题。要对我们使用的机器的int类型的位数时刻注意。

短整型,长整型等的显示:打印unsigned int类型的值,使用%u转换说明;打印long类型的值,使用%ld转换说明。如果系统中int和long的大小相同,使用%d就行。但是,这样的程序被移植到其他系统(int和long类型的大小不同)中会无法正常工作。在x和o前面可以使用l前缀,%lx表示以十六进制格式打印long类型整数,%lo表示以八进制格式打印long类型整数。对于short类型,可以使用h前缀。%hd表示以十进制显示short类型的整数,%ho表示以八进制显示short类型的整数。h和l前缀都可以和u一起使用,用于表示无符号类型。

Tip:注意,虽然C允许使用大写或小写的常量后缀,但是在转换说明中只能用小写。在使用 printf()函数时,切记检查每个待打印值都有对应的转换说明,还要检查转换说明的类型是否与待打印值的类型相匹配。

字符:char类型

char类型用于储存字符(如,字母或标点符号),但是从技术层面看,char是整数类型。因为char类型实际上储存的是整数而不是字符。现在使用最主流的编码系统就是ASCII码,在ASCII码中,整数65代表大写字母A。因此,储存字母A实际上储存的是整数65。

C语言把1字节(8位)定义为char类型占用的位(bit)数,因此无论是16位还是32位系统,都可以使用char类型。

声明方式:char类型变量的声明方式与其他类型变量的声明方式相同。

字符常量的书写方式:在C语言中,用单引号括起来的单个字符被称为字符常量,单引号必不可少,若是双引号则是字符串。也可以使用ASCII码中的对应数字来进行赋值(最好不要这样做)。

单引号只适用于字符、数字和标点符号,浏览ASCII表会发现,有些ASCII字符打印不出来。比如像退格,换行,蜂鸣等,在C语言中提供了三种方法表示这些字符。

第一种就是利用数字代码的方式,定义蜂鸣字符的代码:

1
char beep = 7;

第二种方法是,使用特殊的符号序列表示一些特殊的字符。这些符号序列叫作转义序列,如下表:

最后两个转义序列(\0oo和\xhh)是ASCII码的特殊表示。如果要用八进制ASCII码表示一个字符,可以在编码值前面加一个反斜杠(\)并用单引号括起来。

1
beep = '\007';

上述代码等同于 \a;

十六进制就是将前缀从0改为x即可,记得带上单引号。

我们在使用数字和数字字符的时候需要注意,字符 ‘4’ 在ASCII码中是52,而不是数字4。

Tip:无论是普通字符还是转义序列,只要是双引号括起来的字符集合,就无需用单引号括起来。

字符打印方式:printf()函数用%c指明待打印的字符,如果用%d转换说明打印 char类型变量的值,打印的是一个整数。下图清楚显示了数据的显示过程:

_Bool类型

_ Bool类型,用于表示布尔值,即逻辑值true和false。因为C语言用值1表示true,值0表示false,所以_Bool类型实际上也是一种整数类型。通常来说布尔类型只占用一位存储空间,在以后会对这个类型进行展开讲解。

可移植类型:stdint.h和inttypes.h

在C99标准中新增了两个头文件stdint.h和inttypes.h,以确保C语言的类型在各系统中的功能相同。在stdint.h头
文件中,int32_t表示32位有符号整数类型,在使用32位系统中,头文件会把int32_t作为int的别名,若是在16位的系统中,int32_t会被作为long的别名,使用stdint.h的头文件编写程序是为了方便在不同的系统进行匹配。

不过我们还可能碰到计算机底层系统不能匹配int32_t的情况。这个时候一些类型名保证所表示的类型一定是至少有指定宽度的最小整数类型,这组类型集合被称为最小宽度类型。如int_least8_t是可容纳8位有符号整数值的类型中宽度最小的类型的一个别名。若是系统最小的整数类型是16位也并不妨碍int_least8_t的使用。

仅作为了解。

浮点型:float、double、long double

在C语言的标准中,float类型的必须至少能表示6位的有效数字,取值范围在10^-37~10^37。一般来说,浮点型通常要占用32位,其中8位用于指数部分的值和符号,剩余的24位是使用于非指数部分的值和符号。

另外一个浮点型double(双精度),double类型和float类型的最小取值范围相同,但是double必须能表示10位有效数字,一般情况下双精度占用的是64位,一些系统是将多余的32位均用于非指数的部分,从而达到更高的精度。

第三个浮点型long double是用于满足比double类型更高的精度要求,C语言中只保证long double和double的精度相同。

声明方式:同其他数据类型。

浮点型常量的书写方式:有符号的数字(包括小数点),后面紧跟e或E,最后是一个有符号数表示10的指数。

2.87E3,-1.56E12等

正号可以省略。可以没有小数点或者指数部分,但是不能同时省略两者,可以省略小数部分或整数部分,但是不能同时省略两者。

Tip:不要在浮点型常量中间加空格

在默认情况下,浮点型常量是double类型的精度,若是在浮点数后面加上f或F的后缀即可覆盖默认的设置,加上l或L的话就是long double的类型。

在C99标准中还有一种新的浮点型常量的格式,用十六进制表示浮点型常量,即在十六进制数前加上十六进制前缀(0x或0X),用p和P分别代替e和E,用2的幂代替10的幂。

0xa.1fp10 = 10364.0(了解)

浮点数的打印:printf()函数使用%f转换说明打印十进制记数法的float和double类型浮点数,用%e打印指数记数法的浮点数。如果系统支持十六进制格式的浮点数,可用a和A分别代替e和E。打印long double类型要使用%Lf、%Le或%La转换说明。

浮点数的上溢和下溢:上溢和整数类型的溢出原理基本类似,而下溢则是在计算过程中由于计算符导致有效数字丢失位置的情况。

下溢例子:以十进制为例,把一个有4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.0123E-10。虽然得到了结果,但是在计算过程中却损失了原末尾有效位上的数字。

复数和虚数类型

C语言有3种复数类型:float_Complex、double_Complex和long double _Complex。例如,float _Complex类型的变量应包含两个float类型的值,分别表示复数的实部和虚部。类似地, C语言的3种虚数类型float_Imaginary、double _Imaginary和long double _Imaginary。如果包含complex.h头文件,便可用complex代替_Complex,用imaginary代替_Imaginary,还可以用I代替-1的平方根。

类型大小

sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小。C99和C11提供%zd转换说明匹配sizeof的返回类型。一些不支持C99和C11的编译器可用%u或%lu代替%zd。

下图是源码展示:

以下是输出结果:

总结

以上就是对C语言中数据类型的基本学习和介绍。