计算机处理的对象是数据,而数据是以某种特定的情势存在的(例如整数、浮点数、字符等情势)。不同的数据之间常常还存在某些联系(例如由若干个整数组成1个整数数组)。数据结构指的是数据的组织情势。例如,数组就是1种数据结构。不同的计算机语言所允许使用的数据结构是不同的。处理同1类问题,如果数据结构不同,算法也会不同。例如,对10个整数排序和对包括10个元素的整型数组排序的算法是不同的。
图1.1 C++可使用的数据类型
C++的数据包括常量与变量,常量与变量都具有类型。由以上这些数据类型还可以构成更复杂的数据结构。例如利用指针和结构体类型可以构成表、树、栈等复杂的数据结构。
表1.1 数值型和字符型数据的字节数和数值范围
C++并没有统1规定各类数据的精度、数值范围和在内存中所占的字节数,各C++编译系统根据自己的情况作出安排。表1.1列出了Visual C++数值型和字符型数据的情况。
几点说明:
1) 整型数据分为长整型(long int)、1般整型(int)和短整型(short int)。在int前面加long和short分别表示长整型和短整型。
2) 整型数据的存储方式为按2进制数情势存储,例如10进制整数85的2进制情势为1010101,则在内存中的存储情势以下图所示。
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
3) 在整型符号int和字符型符号char的前面,可以加修饰符signed(表示“有符号”)或unsigned(表示“无符号”)。如果指定为signed,则数值以补码情势寄存,存储单元中的最高位(bit)用来表示数值的符号。如果指定为unsigned,则数值没有符号,全部2进制位都用来表示数值本身。例如短整型数据占两个字节 ,见图2.2。
图1.2
有符号时,能存储的最大值为215⑴,即32767,最小值为⑶2768。无符号时,能存储的最大值为216⑴,即65535,最小值为0。有些数据是没有负值的,可使用unsigned,它存储正数的范围比用signed时要大1倍。
4) 浮点型(又称实型)数据分为单精度(float)、双精度(double)和长双精度(long double)3种,在Visual C++ 6.0中,对float提供6位有效数字,对double提供15位有效数字,并且float和double的数值范围不同。对float分配4个字节,对double和long double分配8个字节。
5) 表中类型标识符1栏中,方括号[ ]包括的部份可以省写,如short和short int等效,unsigned int和unsigned等效。
常量的值是不能改变的,1般从其字面情势便可辨别是不是为常量。常量包括两大类,即数值型常量(即常数)和字符型常量。如12, 0, ⑶为整型常量,4.6, ⑴.23为实型常量,包括在两个单撇号之间的字符为字符常量,如′a′, ′x′。这类从字面情势便可辨认的常量称为“字面常量”或“直接常量”。
数值常量
数值常量就是通常所说的常数。在C++中,数值常量是辨别类型的,从字面情势便可辨认其类型。
整型常量(整数)的类型
在上1节中已知道:整型数据可分为int, short int,long int和unsigned int, unsigned short, unsigned long等种别。整型常量也分为以上种别。为何将数值常量辨别为不同的种别呢?由于在进行赋值或函数的参数虚实结合时要求数据类型匹配。
那末,1个整型常量怎样从字面上辨别为以上的种别呢?
- 1个整数,如果其值在⑶2768~+32767范围内,认为它是short int型,它可以赋值给short int型?int型和long int型变量。
- 1个整数,如果其值超过了上述范围,而在⑵147483648~+2147483647范围内,则认为它是long int型,可以将它赋值给1个int或long int型变量。
- 如果某1计算机系统的C++版本(例如Visual C++)肯定int与long int型数据在内存中占据的长度相同,则它们能够表示的数值的范围相同。因此,1个int型的常量也同时是1个long int型常量,可以赋给int型或long int型变量。
- 常量无unsigned型。但1个非负值的整数可以赋值给unsigned整型变量,只要它的范围不超过变量的取值范围便可。
1个整型常量可以用3种不同的方式表示:
- 10进制整数。如1357, ⑷32, 0等。在1个整型常量后面加1个字母l或L,则认为是long int型常量。例如123L, 421L, 0L等,这常常用于函数调用中。如果函数的形参为long int,则要求实参也为long int型,此时用123作实参不行,而要用123L作实参。
- 8进制整数。在常数的开头加1个数字0,就表示这是以8进制数情势表示的常数。如020表示这是8进制数20,即(20)8,它相当于10进制数16。
- 106进制整数。在常数的开头加1个数字0和1个英文字母X(或x),就表示这是以106进制数情势表示的常数。如0X20表示这是106进制数20,即(20)16,它相当于10进制数32。
浮点数的表示方法
1个浮点数可以用两种不同的方式表示:
1) 10进制小数情势。如21.456, ⑺.98等。它1般由整数部份和小数部份组成,可以省略其中之1(如78.或.06, .0),但不能2者皆省略。C++编译系统把用这类情势表示的浮点数1律按双精度常量处理,在内存中占8个字节。如果在实数的数字以后加字母F或f,表示此数为单精度浮点数,如1234F, ⑷3f,占4个字节。如果加字母L或l,表示此数为长双精度数(long double),在GCC中占12个字节,在Visual C++ 6.0中占8个字节。
2) 指数情势(即浮点情势)。1个浮点数可以写成指数情势,如3.14159可以表示为0.314159×101, 3.14159×100, 31.4159×10⑴, 314.159×10⑵等情势。在程序中应表示为:0.314159e1, 3.14159e0, 31.4159e⑴, 314.159e⑵,用字母e表示其后的数是以10为底的幂,如e12表示1012。其1般情势为:
数符 数字部份 指数部份
上面各数据中的0.314159, 3.14159, 31.4159, 314.159 等就是其中的数字部份。可以看到:由于指数部份的存在,使得同1个浮点数可以用不同的指数情势来表示,数字部份中小数点的位置是浮动的。例如:
a=0.314159e1;
a=3.14159e0;
a=31.4159e⑴;
a=314.159e⑵;
以上4个赋值语句中,用了不同情势的浮点数,但其作用是相同的。
在程序中不论把浮点数写成小数情势还是指数情势,在内存中都是以指数情势(即浮点情势)存储的。例如不论在程序中写成314.159或314.159e0, 31.4159e1, 3.14159e2, 0.314159e3等情势,在内存中都是以规范化的指数情势寄存,如图2.3所示。
图 1.3
数字部份必须小于1,同时,小数点后面第1个数字必须是1个非0数字,例如不能是0.0314159。因此314.159和314.159e0, 31.4159e1, 3.14159e2, 0.314159e3在内存中表示成0.314159×103。存储单元分为两部份,1部份用来寄存数字部份,1部份用来寄存指数部份。为便于理解,在图2.3中是用10进制表示的,实际上在存储单元中是用2进制数来表示小数部份,用2的幂次来表示指数部份的。
对以指数情势表示的数值常量,也都作为双精度常量处理。
字符常量
1) 普通的字符常量
用单撇号括起来的1个字符就是字符型常量。如'a', '#', '%', 'D'都是合法的字符常量,在内存中占1个字节。注意:
- 字符常量只能包括1个字符,如'AB' 是不合法的。
- 字符常量辨别大小写字母,如'A'和'a'是两个不同的字符常量。
- 撇号(')是定界符,而不属于字符常量的1部份。如cout<<'a';输出的是1个字母"a",而不是3个字符"'a' "。
2) 转义字符常量
除以上情势的字符常量外,C++还允许用1种特殊情势的字符常量,就是以 ""开头的字符序列。例如,' '代表1个"换行"符。"cout<<' '; " 将输出1个换行,其作用与"cout<<endl; "="" 相同。这类"控制字符",在屏幕上是不能显示的。在程序中也没法用1个1般情势的字符表示,只能采取特殊情势来表示。
3) 字符数据在内存中的存储情势及其使用方法
将1个字符常量寄存到内存单元时,实际上其实不是把该字符本身放到内存单元中去,而是将该字符相应的ASCII代码放到存储单元中。如果字符变量c1的值为'a',c2的值为'b',则在变量中寄存的是'a'的ASCII码97,'b' 的ASCII码98,如图2.4(a)所示,实际上在内存中是以2进制情势寄存的,如图2.4(b)所示。
图 1.4
既然字符数据是以ASCII码存储的,它的存储情势就与整数的存储情势类似。这样,在C++中字符型数据和整型数据之间就能够通用。1个字符数据可以赋给1个整型变量,反之,1个整型数据也能够赋给1个字符变量。也能够对字符数据进行算术运算,此时相当于对它们的ASCII码进行算术运算。
【例1.1】将字符赋给整型变量。
#include using namespace std; int main( ) { int i, j; //i和j是整型变量 i='A'; //将1个字符常量赋给整型变量i j='B'; //将1个字符常量赋给整型变量j cout<履行时输出
65 66
i和j被指定为整型变量。但在第5和第6行中,将字符'A'和'B'分别赋给i和j,它的作用相当于以下两个赋值语句:
i=65;j=66;
由于'A'和'B'的ASCII码为65和66。在程序的第5和第6行是把65和66直接寄存到i和j的内存单元中。因此输出65和66。
可以看到:在1定条件下,字符型数据和整型数据是可以通用的。但是应注意字符数据只占1个字节,它只能寄存0~255范围内的整数。
【例1.2】字符数据与整数进行算术运算。下面程序的作用是将小写字母转换为大写字母。
#include using namespace std; int main( ) { char c1,c2; c1='a'; c2='b'; c1=c1⑶2; c2=c2⑶2; cout<
运行结果为
A B
'a'的ASCII码为97,而'A'的ASCII码为65,'b'为98,'B'为66。从ASCII代码表中可以看到每个小写字母比它相应的大写字母的ASCII代码大32。C++符数据与数值直接进行算术运算,'a'⑶2得到整数65,'b'⑶2得到整数66。将65和66寄存在c1,c2中,由于c1,c2是字符变量,因此用cout输出c1,c2时,得到字符A和B(A的ASCII码为65,B的ASCII码为66)。
字符串常量
用双撇号括起来的部份就是字符串常量,如"abc","Hello!","a+b","Li ping"都是字符串常量。