在C++中,数据具有不同的类型,类型定义了变量可存储的数值范围以及可进行的操作变量是用于内存中保存数据的,每个变量都必须有确定的数据类型,C++语言的数据类型如图2-1所示。 在图2-1中,把数据类型划分为基本的数据类型和复合的数据类型,我们也可把数据类型分为内置的类型和用户定义的类型两大类,用户定义的类型在使用以前,必须先定义,包括:结构、类、枚举和联合类型;内置的类型是指直接被C++提供的类型,也就是说,是除用户定义的类型以外的其它类型。
图2-1 C++数据类型 |
 |
从语法上来说,void类型也是基本的类型,但是,它不是一个完整的类型,只能作为更复杂类型的一部分。没有void类型的变量,它或者用于指定一个函数(在第五章介绍)没有返回值,或者作为指针(在第七章介绍)类型,表示该指针指向未知类型的变量,例如: void x; //错误,没有void变量 void f( ); //函数f不返回值 void *pv; //指针pv指向未知类型的变量 布尔型、字符型、整型和浮点型也称为算术类型;枚举、指针、数组、引用、结构、联合和类称之为复合数据类型,它们能通过其它数据类型进行构造。 在基本的数据类型char、 int前可以添加修饰符,以改变基本类型的意义,可用的修饰符有long、short、signed和unsigned四种,另外,双精度型前可以加long修饰符。基本的数据类型及其表示范围,可参见表2-3。
表2-3 基本的数据类型及其表示范围 |
类型名 |
类型 |
字节 |
表示范围 |
char |
字符型 |
1 |
-128 ~127 |
unsigned char |
无符号字符型 |
1 |
0 ~255 |
signed char |
有符号字符型(与字符型相同) |
1 |
-128 ~127 |
int |
整型 |
* |
与机器有关 |
unsigned int |
无符号整型 |
* |
与机器有关 |
signed int |
有符号整型(与整型相同) |
* |
与机器有关 |
short int |
短整型 |
2 |
-32,768~ 32,767 |
unsigned short int |
无符号短整型 |
2 |
0~65,535 |
signed short int |
有符号短整型(与短整型相同) |
2 |
-32,768~ 32,767 |
long int |
长整型 |
4 |
-2,147,483,648 ~2,147,483,647 |
signed long int |
有符号长整型(与长整型相同) |
4 |
-2,147,483,648 ~ 2,147,483,647 |
unsigned long int |
无符号长整型 |
4 |
0~4,294,967,295 |
float |
浮点型 |
4 |
3.4E +/- 38 (7位有效数字) |
double |
双精度型 |
8 |
1.7E +/- 308 (15位有效数字) |
long double |
长双精度型 |
10 |
1.2E +/- 4932 (19位有效数字) | | unsigned和signed只用于修饰char和int,且signed修饰词可以省略。当用unsigned修饰词时,后面的类型说明符可以省略。例如: signed int n; //与"int n;"等价 signed char ch; //与"char ch;"等价 unsigned int n; //与"unsigned n;"等价 unsigned char ch; //与"unsigned ch;"等价 short只用于修饰int,且用short修饰时,int可以省略,即: short int n; //与"short n;"等价 long只能修饰int和double。当用long修饰int时,int可以省略,即: long int n; //与"long n;"等价 int和unsigned int类型占用一个机器一个字(word)的字节。在16位操作系统上,它们占用2个字节;在32位操作系统上,它们占用4个字节。 各种数据类型精度由低到高排列如图2-2:
如果一个双目运算符两边的操作数类型不同,先要将它们转换为相同的类型,即较低类型转换为较高类型,然后再参加运算。所谓类型的高低,跟所占的存储空间大小有直接关系,所占存储空间越大的类型,级别越高。 图中横向的箭头表示必须的转换,如两个float型数参加运算,虽然它们类型相同,但仍要先转换成double型再进行运算,结果亦为double型。纵向箭头表示当运算符两边的操作数为不同类型时的转换,如一个long型数据与一个int型数据一起运算,需要先将int型数据转换为long型,然后两者再进行运算,结果为long型。所有这些转换都是由系统自动进行的,使用时只需了解结果的类型即可。
 |
程序2-2 |
|
#include <iostream.h> void main(void) { char a = 'x'; int b = 3,f = 2; float c = 2.5678; double d = 5.2345 long e = 32L; cout<<a - b + d / c - e * f<<endl; } | 下面我们来分析一下这段程序: (1) 进行d / c运算时,要将c转换成double型,运算的中间结果为double型; (2) 进行e * f运算时,将f转换为long型,运算的中间结果为long型; (3) 进行a - b运算时,将a转换为int型(数值为ASCⅡ码值120),运算的中间结果为int型; (4) 当(3)的中间结果与(1)的中间结果运算时,将(3)的中间结果转换为double型,运算的中间结果为double型; (5) 当(4)的中间结果与(2)的中间结果运算时,将(2)的中间结果转换为double型,得出最后结果。 于是,程序最后的运行结果为55.038515。
如果数据是从较高类型转换成较低类型,这意味着类型的精度或表示范围降低,可能造成数据丢失。下面两个表分别列出了有符号数之间和无符号数之间的转换:
1. 有符号数的转换 有符号数的转换中,如果从较低类型转换到较高类型,将进行符号扩展,例如一个值从short int(16位)转换到long类型,如果这个数是正数,则最高位为0,从16位扩展到32位时,扩展的高16位用0填充,即将符号位0进行扩展,这样扩展后的32位整数和原来的整数值是一样的。如果该数为负数,则最高位为1,从16位扩展到32位时,扩展的高16位用1填充,即将符号位1进行扩展,这样扩展后的32位整数和原来的整数值是也是一样的。 如果从较高类型转换到较低类型,将抛弃高位,直接将低位复制过来,例如一个值从int(假定为32位)转换到short int型(16位),系统将抛弃高16位,取低16位的值作为转换后的值。 浮点数类型和整数类型转换比较复杂,因为它们的内部表示方式不同,转换时它们不是简单的符号位扩展或者高位截断,它们首先需要进行内部表示方式的转换。左表是有符号数类型转换的所有情况。
 |
表2-4 |
|
从 |
到 |
方法 |
char |
short |
符号位扩展 |
char |
long |
符号位扩展 |
char |
unsigned char |
最高位失去符号位意义,变为数据位 |
char |
unsigned short |
符号位扩展到short;然后从short转到 unsigned short |
char |
unsigned long |
符号位扩展到long; 然后从long 转到unsigned long |
char |
float |
符号位扩展到long; 然后从long 转到float |
char |
double |
符号位扩展到long; 然后从long 转到double |
char |
long double |
符号位扩展到long; 然后从long 转到long double |
short |
char |
保留低位字节 |
short |
long |
符号位扩展 |
short |
unsigned char |
保留低位字节 |
short |
unsigned short |
最高位失去符号位意义,变为数据位 |
short |
unsigned long |
符号位扩展到long; 然后从long转到unsigned double |
short |
float |
符号位扩展到long; 然后从long 转到float |
short |
double |
符号位扩展到long; 然后从long 转到double |
short |
long double |
符号位扩展到long; 然后从long 转到double |
long |
char |
保留低位字节 |
long |
short |
保留低位字节 |
long |
unsigned char |
保留低位字节 |
long |
unsigned short |
保留低位字节 |
long |
unsigned long |
最高位失去符号位意义,变为数据位 |
long |
Float |
使用单精度浮点数表示。可能丢失精度。 |
long |
double |
使用双精度浮点数表示。可能丢失精度。 |
long |
long double |
使用双精度浮点数表示。可能丢失精度。 | |
2. 无符号数的转换 无符号数转换相对简单一些,它没有符号位,当低级类型向高级类型转换时,只需要将高位补0,高级类型向低级类型转换同有符号数。左表是无符号数类型转换的所有情况。
 |
表2-5 |
|
从 |
到 |
方法 |
unsigned char |
char |
最高位作为符号位 |
unsigned char |
short |
0扩展 |
unsigned char |
long |
0扩展 |
unsigned char |
unsigned short |
0扩展 |
unsigned char |
unsigned long |
0扩展 |
unsigned char |
float |
转换到long; 再从 long 转换到float |
unsigned char |
double |
转换到long; 再从 long 转换到double |
unsigned char |
long double |
转换到long; 再从 long 转换到double |
unsigned short |
char |
保留低位字节 |
unsigned short |
short |
最高位作为符号位 |
unsigned short |
long |
0扩展 |
unsigned short |
unsigned char |
保留低位字节 |
unsigned short |
unsigned long |
0扩展 |
unsigned short |
float |
转换到long; 再从 long 转换到float |
unsigned short |
double |
转换到long; 再从 long 转换到double |
unsigned short |
long double |
转换到long; 再从 long 转换到double |
unsigned long |
char |
保留低位字节 |
unsigned long |
short |
保留低位字节 |
unsigned long |
long |
最高位作为符号位 |
unsigned long |
unsigned char |
保留低位字节 |
unsigned long |
unsigned short |
保留低位字节 |
unsigned long |
float |
转换到long; 再从 long 转换到float |
unsigned long |
double |
Convert directly to double |
unsigned long |
long double |
转换到long; 再从 long 转换到double | |
变量就是机器一个内存位置的符号名,在该内存位置可以保存数据,并可通过符号名进行访问。变量有三个特征: ◇ 每一个变量有一个名字,其命名规则与标识符相同。 ◇ 每一个变量有一个类型。 ◇ 每一个变量保存一个值。如果需要变量保存某一个值,就把该值赋给变量。 为了提高程序的可读性,给变量命名时,应该注意使用有意义的名字,以帮助描述变量所保存的值。最好是一开始就坚持使用小写字母。例如:要用一个变量保存工资总额,可以使用total_payroll,也可以使用XYZ34作变量名,它们都是合法的名字。但使用前者比使用后者就更好,因为从变量名,就能大致知道它保存了什么样的值,便于记忆。 在使用一个变量之前,必须先定义。变量的定义的一般格式如下:
数据类型 变量名1[= 初始值1], 变量名2[= 初始值2], ...; "数据类型"是指C++有效的数据类型,如int、double、long等。方括号中的内容是可选的,它是在变量定义时,给变量赋初值。下面是几个变量定义的实例: long n; //定义了一个长整型变量n,未赋初值 double a, b = 0.5; //定义双精度型变量a、b,a未赋初值,b的初值为0.5
下面是一个使用变量的程序实例:
 |
程序2-3: |
|
#include <iostream.h> int main (void) { 1. int workDays = 5; 2. float workHours, payRate, weeklyPay; 3. workHours = 7.5; payRate = 38.55; 4. weeklyPay = workDays * workHours * payRate; 5. cout << "Weekly Pay = " << weeklyPay << '\n'; } | 第一行定义了一个整型变量workDays,并初始化为5,表示一周的工作天数。 第二行定义了三个实型变量,分别表示每天工作的小时数、每小时应支付的薪水及每周应支付的薪水。 第三行是两个赋值语句。7.5 赋给变量workHours,38.55赋给变量payRate。 第四行是计算每周的工资,即三个变量workDays、workHours、payRate的积,*是乘运算符,结果保存在变量weeklyPay变量中。 第五行输出字符串"Weekly Pay = "、变量weeklyPay 的值和换行符。 本程序的运行结果如下: Weekly Pay = 1445.625 如果我们定义一个变量时,没有给它赋初值,它的值是不定的。例如,在上面的第四行执行前,weeklyPay的值是不定的。 变量第一次赋值称之为初始化,变量在使用之前应当先初始化。
|