【C/C++基础】03_C/C++语言数据类型

对变量的定义可以包括四个方面:

·数据类型

·存储类型

·作用域

·存储期

在本节中,我们只介绍数据类型的说明,其它说明在以后各节中陆续介绍。所谓数据类型是按被定义变量的性质,表示形式,占据存储空间的多少,构造特点来划分的。在C++语言中,数据类型可分为:基本数据类型,派生数据类型和空类型三大类。

【C/C++基础】03_C/C++语言数据类型

1. 常量与变量概述

对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。在程序执行过程中,其值不发生改变的量称为常量,其值可变的量称为变量。它们可与数据类型结合起来分类。例如,可分为整型常量、整型变量、浮点常量、浮点变量、字符常量、字符变量、枚举常量、枚举变量。在程序中,常量是可以不经说明而直接引用的,而变量则必须先定义后使用。整型量包括整型常量、整型变量。

在程序执行过程中,其值不发生改变的量称为常量。包括:

(1)直接常量(字面常量)

 整型常量:120-3

 实型常量:4.6-1.23

 字符常量:‘a’、‘b’。

(2)标识符:用来标识变量名、符号常量名、函数名、数组名、类型名、文件名的有效字符序列。

(3) 符号常量:用标示符代表一个常量。在C语言中,可以用一个标识符来表示一个常量,称之为符号常量。

符号常量在使用之前必须先定义,其一般形式为:

#define 标识符常量

其中#define也是一条预处理命令(预处理命令都以"#"开头),称为宏定义命令,其功能是把该标识符定义为其后的常量值。一经定义,以后在程序中所有出现该标识符的地方均代之以该常量值。习惯上符号常量的标识符用大写字母,变量标识符用小写字母,以示区别。

【例3.1】符号常量的使用。

#define PRICE 30

main()

{

  int num,total;

num=10;

total=num* PRICE;

printf(“total=%d”,total);

}

用标识符代表一个常量,称为符号常量。 符号常量与变量不同,它的值在其作用域内不能改变,也不能再被赋值。 使用符号常量的好处是:含义清楚;能做到“一改全改”。

变量:其值可以改变的量称为变量。一个变量应该有一个名字,在内存中占据一定的存储单元。变量定义必须放在变量使用之前。一般放在函数体的开头部分。要区分变量名和变量值是两个不同的概念。

2. 常量类型

2.1 整型常量

整型常量就是整常数。在C/C++语言中,使用的整常数有八进制、十六进制和十进制三种。

(1) 十进制整常数:十进制整常数没有前缀。其数码为09

以下各数是合法的十进制整常数:

237-568655351627

以下各数不是合法的十进制整常数:

023 (不能有前导0)23D (含有非十进制数码)

在程序中是根据前缀来区分各种进制数的。因此在书写常数时不要把前缀弄错造成结果不正确。

(2) 八进制整常数:八进制整常数必须以0开头,即以0作为八进制数的前缀。数码取值为07。八进制数通常是无符号数。

以下各数是合法的八进制数:

015(十进制为13)0101(十进制为65)0177777(十进制为65535)

以下各数不是合法的八进制数:

256(无前缀0)03A2(包含了非八进制数码)-0127(出现了负号)

(3) 十六进制整常数:十六进制整常数的前缀为0X0x。其数码取值为0~9A~Fa~f

以下各数是合法的十六进制整常数:

0X2A(十进制为42)0XA0(十进制为160)0XFFFF (十进制为65535)

以下各数不是合法的十六进制整常数:

5A (无前缀0X)0X3H (含有非十六进制数码)

(4)  整型常数的后缀:在16位字长的机器上,基本整型的长度也为16位,因此表示的数的范围也是有限定的。十进制无符号整常数的范围为065535,有符号数为-32768+32767。八进制无符号数的表示范围为00177777。十六进制无符号数的表示范围为0X00XFFFF0x00xFFFF。如果使用的数超过了上述范围,就必须用长整型数来表示。长整型数是用后缀“L”或“l”来表示的。

例如:

十进制长整常数:

158L (十进制为158)358000L (十进制为358000)

八进制长整常数:

012L (十进制为10)077L (十进制为63)0200000L (十进制为65536)

十六进制长整常数:

0X15L(十进制为21)0XA5L (十进制为165)0X10000L (十进制为65536)

长整数158L和基本整常数158在数值上并无区别。但对158L,因为是长整型量,C编译系统将为它分配4个字节存储空间。而对158为是基本整型,只分配2 个字节的存储空间。因此在运算和输出格式上要予以注意,避免出错。

无符号数也可用后缀表示,整型常数的无符号数的后缀为“U”或“u”。

例如:

358u,0x38Au,235Lu均为无符号数。

前缀,后缀可同时使用以表示各种类型的数。如0XA5Lu表示十六进制无符号长整数A5,其十进制为165

2.2 浮点型常量

实型也称为浮点型。实型常量也称为实数或者浮点数。在C语言中,实数只采用十进制。它有二种形式:十进制小数形式,指数形式。

(1)十进制数形式:由数码0~ 9和小数点组成。

例如:

0.025.05.7890.135.0300.-267.8230

等均为合法的实数。注意,必须有小数点。

(2)指数形式:由十进制数,加阶码标志“e”或“E”以及阶码(只能为整数,可以带符号)组成。

其一般形式为:

a E na为十进制数,n为十进制整数)

其值为a*10n

如:

2.1E5 (等于2.1*105)

3.7E-2 (等于3.7*10-2)

0.5E7 (等于0.5*107)

-2.8E-2 (等于-2.8*10-2)

以下不是合法的实数:

345 (无小数点)

E7 (阶码标志E之前无数字)

-5 (无阶码标志)

53.-E3 (负号位置不对)

2.7E  (无阶码)

标准C允许浮点数使用后缀。后缀为“f”或“F”即表示该数为浮点数。如356f356.是等价的。

2.3 字符常量

(1)普通的字符常量:

字符常量是用单引号括起来的一个字符。例如:'a'、'b'、'='、'+'、'?'都是合法字符常量。

在C语言中,字符常量有以下特点:

1) 字符常量只能用单引号括起来,不能用双引号或其它括号。

2)  字符常量只能是单个字符,不能是字符串。

3)  字符可以是字符集中任意字符。但数字被定义为字符型之后就不能参与数值运算。如'5'和5 是不同的。'5'是字符常量,不能参与运算。

(2)转义字符:

 转义字符是一种特殊的字符常量。转义字符以反斜线"\"开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。例如,在前面各例题printf函数的格式串中用到的“\n”就是一个转义字符,其意义是“回车换行”。转义字符主要用来表示那些用一般字符不便于表示的控制代码。

常用的转义字符及其含义

转义字符

转义字符的意义

ASCII代码

       \n

回车换行

10

       \t

横向跳到下一制表位置

9

       \b

退格

8

       \r

回车

13

       \f

走纸换页

12

       \\

反斜线符"\"

92

       \'

单引号符

39

       \”

双引号符

34

       \a

鸣铃

7

       \ddd

13位八进制数所代表的字符

 

       \xhh

12位十六进制数所代表的字符

 

广义地讲,C语言字符集中的任何一个字符均可用转义字符来表示。表中的\ddd和\xhh正是为此而提出的。ddd和hh分别为八进制和十六进制的ASCII代码。如\101表示字母"A" ,\102表示字母"B",\134表示反斜线,\XOA表示换行等。

【例3.2】转义字符的使用。

main()

{

  int a,b,c;

  a=5; b=6; c=7;

  printf(“ ab  c\tde\rf\n”);

printf(“hijk\tL\bM\n”);

}

2.4 字符串常量

字符串常量是由一对双引号括起的字符序列。例如: "CHINA" , “C program” ,"$12.5" 等都是合法的字符串常量。

字符串常量和字符常量是不同的量。它们之间主要有以下区别:

1) 字符常量由单引号括起来,字符串常量由双引号括起来。

2) 字符常量只能是单个字符,字符串常量则可以含一个或多个字符。

3) 可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋予一个字符变量。在C语言中没有相应的字符串变量。这是与BASIC 语言不同的。但是可以用一个字符数组来存放一个字符串常量。在数组一章内予以介绍。

4) 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符"\0" (ASCII码为0)。这是字符串结束的标志。

例如:

字符串 "Cprogram" 在内存中所占的字节为:

C

 

p

r

o

g

r

a

m

\0

字符常量'a'和字符串常量"a"虽然都只有一个字符,但在内存中的情况是不同的。

'a'在内存中占一个字节,可表示为:

a

"a"在内存中占二个字节,可表示为

a \0   

3. 变量类型

3.1 整型变量

3.1.1  整型数据在内存中的存放形式

如果定义了一个整型变量i

int i;

i=10;

 

0

0

0

0

0

0

0

0

0

0

0

0

1

0

1

0 

数值是以补码表示的:

正数的补码和原码相同;

负数的补码:将该数的绝对值的二进制形式按位取反再加1

例如:

-10的补码:

10的原码:

0

0

0

0

0

0

0

0

0

0

0

0

1

0

1

0

 取反:

1

1

1

1

1

1

1

1

1

1

1

1

0

1

0

1

再加1,得-10的补码:

1

1

1

1

1

1

1

1

1

1

1

1

0

1

1

0

由此可知,左面的第一位是表示符号的。

3.1.2 整型变量的分类

1)       基本型:类型说明符为int,在内存中占4个字节。

2)       短整量:类型说明符为short intshort在内存中占2个字节。

3)       长整型:类型说明符为long intlong,在内存中占8个字节。

4)       无符号型:类型说明符为unsigned

无符号型又可与上述三种类型匹配而构成:

无符号基本型:类型说明符为unsigned intunsigned

无符号短整型:类型说明符为unsigned short

无符号长整型:类型说明符为unsigned long

    下表列出了TurboC中各类整型量所分配的内存字节数及数的表示范围。

类型说明符

数的范围

字节数

int

-2147483648~2147483647            -231~231-1

4

unsigned int

0~4294967295              0~232-1

4

short int

-32768~32767           -215~215-1

2

unsigned short int

0~65535              0~216-1

2

long int

-2147483648~2147483647-231~231-1

4

unsigned long

0~4294967295         0~232-1

4

13为例(假设在16位计算机上):

int型:

00

00

00

00

00

00

11

01

short int型:

00

00

00

00

00

00

11

01

long int型:

00

00

00

00

00

00

00

00

00

00

00

00

00

00

11

01

unsigned int型:

00

00

00

00

00

00

11

01

unsigned short int型:

00

00

00

00

00

00

11

01

unsigned long int型:

00

00

00

00

00

00

00

00

00

00

00

00

00

00

11

01

3.1.3.      整型变量的定义

变量定义的一般形式为:

类型说明符  变量名标识符,变量名标识符,...

例如:

    int a,b,c; (a,b,c为整型变量)

    long x,y; (x,y为长整型变量)

unsigned p,q; (p,q为无符号整型变量)

在书写变量定义时,应注意以下几点:

允许在一个类型说明符后,定义多个相同类型的变量。各变量名之间用逗号间隔。类型说明符与变量名之间至少用一个空格间隔。

最后一个变量名之后必须以“;”号结尾。

变量定义必须放在变量使用之前。一般放在函数体的开头部分。

【例3.3】整型变量的定义与使用。

main()

{

int a,b,c,d;

unsigned u;

a=12;b=-24;u=10;

c=a+u;d=b+u;

printf(“a+u=%d,b+u=%d\n”,c,d);

}

【例3.4】整型数据的溢出。

main()

{

  int a,b;

  a=32767;

  b=a+1;

  printf("%d,%d\n",a,b);

 }

32767:

0

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

-32768

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

【例3.5

main(){

  long x,y;

  int a,b,c,d;

  x=5;

  y=6;

  a=7;

  b=8;

  c=x+a;

  d=y+b;

  printf("c=x+a=%d,d=y+b=%d\n",c,d);

 }

从程序中可以看到:x, y是长整型变量,a, b是基本整型变量。它们之间允许进行运算,运算结果为长整型。但cd被定义为基本整型,因此最后结果为基本整型。本例说明,不同类型的量可以参与运算并相互赋值。其中的类型转换是由编译系统自动完成的。

3.2 实型变量

3.2.1 实型数据在内存中的存放形式

实型数据一般占4个字节(32位)内存空间。按指数形式存储。实数3.14159在内存中的存放形式如下:

+

.314159

1

          数符           小数部分                    指数

 小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高。

 指数部分占的位数愈多,则能表示的数值范围愈大。

3.2.2 实型变量的分类

实型变量分为:单精度(float型)、双精度(double型)和长双精度(long double型)三类。

Turbo C中单精度型占4个字节(32位)内存空间,其数值范围为3.4E-383.4E+38,只能提供七位有效数字。双精度型占8 个字节(64位)内存空间,其数值范围为1.7E-3081.7E+308,可提供16位有效数字。

类型说明符

比特数(字节数)

有效数字

数的范围

float

324

6~7

10-37~1038         

double

64(8)

15~16

10-307~10308

long double

128(16)

18~19

10-4931~104932

实型变量定义的格式和书写规则与整型相同。

例如:

    floatx,y; (x,y为单精度实型量)

double a,b,c; (a,b,c为双精度实型量)

3.3.3  实型数据的舍入误差

由于实型变量是由有限的存储单元组成的,因此能提供的有效数字总是有限的。如下例。

【例3.6】实型数据的舍入误差。

main()

{float a,b;

 a=123456.789e5;

 b=a+20

printf("%f\n",a);

printf("%f\n",b);

}

注意:1.0/3*3的结果并不等于1

3.3 字符型变量

字符变量用来存储字符常量,即单个字符。

字符变量的类型说明符是char。字符变量类型定义的格式和书写规则都与整型变量相同。例如:

 char a,b;

每个字符变量被分配一个字节的内存空间,因此只能存放一个字符。字符值是以ASCII码的形式存放在变量的内存单元之中的。

如x的十进制ASCII码是120,y的十进制ASCII码是121。对字符变量a,b赋予'x'和'y'值:

a='x';

 b='y';

实际上是在a,b两个单元内存放120和121的二进制代码:

a:

0

1

1

1

1

0

0

0

b:

0

1

1

1

1

0

0

1

所以也可以把它们看成是整型量。C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。在输出时,允许把字符变量按整型量输出,也允许把整型量按字符量输出。

整型量为二字节量,字符量为单字节量,当整型量按字符型量处理时,只有低八位字节参与处理。

【例3.7】向字符变量赋以整数。

main()

{

  char a,b;

  a=120;

  b=121;

  printf("%c,%c\n",a,b);

printf("%d,%d\n",a,b);

}

本程序中定义a,b为字符型,但在赋值语句中赋以整型值。从结果看,a,b值的输出形式取决于printf函数格式串中的格式符,当格式符为"c"时,对应输出的变量值为字符,当格式符为"d"时,对应输出的变量值为整数。

【例3.8】

main()

{

  char a,b;

  a='a';

  b='b';

  a=a-32;

  b=b-32;

  printf("%c,%c\n%d,%d\n",a,b,a,b);

 }

本例中,a,b被说明为字符变量并赋予字符值,C语言允许字符变量参与数值运算,即用字符的ASCII 码参与运算。由于大小写字母的ASCII 码相差32,因此运算后把小写字母换成大写字母。然后分别以整型和字符型输出。

3.4 常变量

在定义变量时,加上关键字const,则变量的值在程序运行期间不能改变,这种变量称为常变量。例如:

const in a=1;

常变量的意义在于:在变量的基础上加上限制条件:存储单元中的值不允许变化,常变量又称为只读变量。

注意常变量与#define指令定义的符号常量的区别。符号常量只是用一个符号代替一个字符串,在预编译时把所有的符号常量替换为所指定的字符串。

4. 数据类型转换

变量的数据类型是可以转换的。转换的方法有两种,一种是自动转换,一种是强制转换。自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。

(1)自动转换:在不同类型数据的混合运算中,由系统自动实现转换,由少字节类型向多字节类型转换。不同类型的量相互赋值时也由系统自动进行转换,把赋值号右边的类型转换为左边的类型。自动转换遵循以下规则:

1)      若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2)      转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。

3)      所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4)      char型和short型参与运算时,必须先转换成int型。

5)      在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。

(2)强制转换:由强制转换运算符完成转换。