前言
针对不同的数据,采取不同的存储方式和进行不同的处理。随着处理对象的复杂化,数据类型也要变得更丰富。数据类型的丰富程度直接反映了程序设计语言处理数据的能力。
C语言很重要的一个特点是它的数据类型十分丰富。因此,C语言程序数据处理功能很强。C语言丰富的数据类型可归纳如下:
一、整数类型
1.1 整型变量
整数类型数据即整型数据,整型数据没有小数部分的数值。整型数据可分为:基本型、短整型、长整型和无符号型四种。
- 基本型:以int表示。
- 短整型:以short int表示。
- 长整型:以long int表示。
- 无符号型:存储单元中全部二进位用来存放数据本身,不包括符号。无符号型中又分为无符号整型、无符号短整型和无符号长整型,分别以unsigned int,unsigned short和unsigned long表示。
要注意的是,不同的计算机体系结构中这些类型所占比特数有可能是不同的,下面列出的是32位机中整型家族各数据类型所占的比特数。
虽然int与unsigned int所占的位数一样,但int的最高位用作了符号位,而unsigned int的最高位仍为数据位,所以它们的取值范围不同。若要查看适合当前计算机的各数据类型的取值范围,可查看文件“limits.h”(通常在编译器相关的目录下),如下是“limits.h”的部分示例。
#define CHAR_BIT 8 /* number of bits in a char */
#define SCHAR_MIN (-128) /* minimum signed char value */
#define SCHAR_MAX 127 /* maximum signed char value */
#define UCHAR_MAX 0xff /* maximum unsigned char value */#ifndef _CHAR_UNSIGNED
#define CHAR_MIN SCHAR_MIN /* mimimum char value */
#define CHAR_MAX SCHAR_MAX /* maximum char value */
#else
#define CHAR_MIN 0
#define CHAR_MAX UCHAR_MAX
#endif /* _CHAR_UNSIGNED */#define MB_LEN_MAX 2 /* max. # bytes in multibyte char */
#define SHRT_MIN (-32768) /* minimum (signed) short value */
#define SHRT_MAX 32767 /* maximum (signed) short value */
#define USHRT_MAX 0xffff /* maximum unsigned short value */
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX 2147483647L /* maximum (signed) long value */
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */
在嵌入式开发中,经常需要考虑的一点就是可移植性的问题。通常,字符是否为有符号数会带来两难的境地,因此,最佳妥协方案就是把存储于int型变量的值限制在signed int和unsigned int的交集中,这可以获得最大程度上的可移植性,同时又不牺牲效率。
1.2 整型常量
C语言整型数据一般有十进制整数、八进制整数和十六进制整数三种表达形式。说明如下。
- 十进制整数的表示与数学上的表示相同,例如:256,-321,0
- 八进制整数的表示以数字0开头,例如:0234表示八进制整数(234)8,所对应的十进制数为 。2×82+3×81+4×80=156。
- 十六进制整数的表示以0x开头,例如:0×234表示十六进制整数(234)16。(应当注意的是十六进制数前导字符0x,x前面是数字(0)。
在一个整型数据后面加一个字母L或l(小写),则认为是long int型量。如342L、0L、78L等,这往往用于函数调用中。如果函数的形参为long int型,则要求实参也为long int型,此时需要用342L作实参。
二、实数(浮点)类型
2.1 实数(浮点)变量
实型变量又可分为单精度(float)、双精度(double)和长双精度(long double)3种。列出的是常见的32位机中实型家族各数据类型所占的比特数。
要注意的是,这里的有效数字是指包括整数部分+小数部分的全部数字总数。
小数部分所占的位(bit)越多,数的精度就越高;指数部分所占的位数越多,则能表示的数值范围就越大。下面程序就显示了实型变量的有效数字位数。
#include<stdio.h>
int main()
{float a;double b;a = 33333.33333;b = 33333.333333;printf(" a = %f , b = %lf \n" , a , b );return 0;
程序执行结果如下:
a=33333.332031 , b=33333.333333
可以看出,由于a为单精度类型,有效数字长度为7位,因此a的小数点后4位并不是原先的数据而由于b为双精度类型,有效数字为16位,因此b的显示结果就是实际b的数值。
2.2 实型(浮点)常量
在C语言程序设计中,实型数据有以下两种表达形式。
- 十进制数形式。由正负号、数字和小数点组成。如5.734、一0.273、0.8、一224等都是十进制数形式。
- 指数形式。如546E+3或546E3都代表546×10 3。字母E(或e)之前必须有数字,E(或e)后面的指数必须为整数。E8、4.6E+2.7、6e、e、9E7.5都是不合法的指数形式;5.74E-7、-3E+6是合法的指数形式实型常量。
三、字符类型
3.1 字符变量
字符变量可以看作是整型变量的一种,它的标识符为“char”,一般占用一个名节(8bit),它也分为有符号和无符号两种,读者完全可以把它当成一个整型变量。当它用于存储字符常量时,实际上是将该字符的ASCⅡ码值(无符号整数)存储到内存单元中。
实际上,一个整型变量也可以存储一个字符常量,而且也是将该字符的ASCH码值(无符号整数)存储到内存单元中。但由于取名上的不同,字符变量则更多地用于存储字符常量。以下一段小程序显示了字符变量与整型变量实质上是相同的。
#include<stdio.h>
int main()
{char a,b;int c,d;
/*赋给字符变量和整型变量相同的整数常量*/a=c=65;
/*赋给字符变量和整型变量相同的字符常量*/b=d='a';
/*以字符的形式打印字符变量和整型变量*/printf("char a=%c,int c = %c", a,c);
/*以整数的形式打印字符变量和整型变量*/printf("char b=%d,int d=%d\n",b,d);
return 0;
程序执行结果如下:
char a=A,int c=A;
char b=97,int d=97;
由此可见,字符变量和整型变量在内存中存储的内容实质是一样的。
3.2 字符常量
字符常量是指用单引号括起来的一个字符,如:‘a’,‘5’,‘?’ 等都是字符常量。以下是使用字符常量时容易出错的地方,请读者仔细阅读。
- 字符常量只能用单引号括起来,不能用双引号或其他括号。
- 字符常量只能是单个字符,不能是字符串。
- 字符可以是字符集中任意字符。但数字被定义为字符型之后就不能参与数值运算。如’5’和5是不同的。‘5’是字符常量,不能直接参与运算,而只能以其ASCⅡ码值(053)来参与运算。
除此之外,C语言中还存在一种特殊的字符常量——转义字符。转义字符以反斜线“\”开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。例如,在前面各例题printí函数的格式串中用到的“\n”就是一个转义字符,其意义是“回车换行”。转义字符主要用来表示那些用一般字符不便于表示的控制代码。
常见的转义字符以及它们的含义。
四、枚举类型
在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有7天,一年只有12个月,一个班每周有6门课程等。如果把这些量说明为整型、字符型或其他类型显然是不妥当的。为此,C语言提供了一种称为枚举的类型。在枚举类型的定义中列举出所有可能的取值,被定义为该枚举类型的变量取值不能超过定义的范围。
枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。
枚举类型定义的一般形式如下。
enum 枚举名
{枚举值表
};
在枚举值表中应罗列出所有可用值,这些值也称为枚举元素。
例如,定义一个枚举类型和枚举变量如下:
enum colorname{red,yellow,blue,white,black};
enum colorname color;
变量color是枚举类型enum colorname,它的值只能是red、yellow、blue、white例如
下面的赋值合法:
color=red;
color=white;
而下面的赋值则不合法:
color=green;
color=orange;
关于枚举类型有几点说明:
- enum是关键字,标识枚举类型,定义枚举类型必须以enum开头。
- 在定义枚举类型时花括号中的名字称为枚举元素或枚举常量。它们是程序设计者自己指定的,命名规则与标识符相同。这些名字并无固定的含义,只是一个符号,程序设计者仅仅是为了提高程序的可读性才使用这些名字。
- 枚举元素不是变量,不能改变其值。如下面这些赋值是不对的:
red=8;yellow=9;
但枚举元素作为常量,它们是有值的。从花括号的第一个元素开始,值分别是0、1、2、3、4,这是系统自动赋给的,可以输出。例如:
printf("%d",blue);
输出的值是2。但是定义枚举类型时不能写成:
enum colorname{0,1,2,3,4};
必须用符号red,yellow,……,或其他标识符。可以在定义类型时对枚举常量初始化:
enum colornmae{red=3,yellow,blue,white=8,black};
此时,red为3,yellow为4,blue为5,white为8,black为9。因为yellow在red之后,red为3,yellow顺序加一,同理black为9。
④枚举常量可以进行比较。例如:
if(color==red) printf("red");
if(color!=black) printf("it is not black!”);
if(color>white) printf(“it is black!”);
它们是按所代表的整数进行比较的。
⑤一个枚举变量的值只能是这几个枚举常量之一,可以将枚举常量赋给一个枚举变量。但不能将一个整数赋给它。例如:
color=black; //正确
color=5;///错误
⑥枚举常量不是字符串,不能用下面的方法输出字符串”red”。
printf("%s",red);
如果想先检查color的值,若是red,就输出字符串"red”,可以这样:
color=red;
if(color==red)
printf("red");
五、指针类型
由于指针需要篇幅过大,我们后期单独介绍。