C++的数据类型

计算机处理的对象是数据,而数据是以某种特定的形式存在的(例如整数、浮点数、字符等形式)。数据结构指的是数据的组织形式,例如,数组就是一种数据结构。

C++可以使用的数据类型如下

  • 基本类型

    • 整形

      • 短整型(short int)

      • 整形(int)

      • 长整型(long int)

    • 字符型(char)

    • 浮点型

      • 单精度型(float)

      • 双精度型(double)

      • 长双精度型(long doubel)

    • 布尔型(bool)

  • 派生类型

    • 指针类型(*)

    • 枚举类型(enum)

    • 数组类型([ ])

    • 结构体类型(struct)

    • 共用体类型(union)

    • 类类型(class)

  • 空类型(void)

C++并没有统一规定各类数据的精度、数值范围和在内存中所占的字节数,各种C++编译系统根据自己的情况做出安排。下表列出了Visual C++数值型和字符型数据的情况。

数值型和字符型数据的字节数,和数值范围

类型 类型标识符 字节数 数值范围
整形 [signed] int 4 -2147483648 ~ +2147483648
无符号整形 unsigned [int] 4 0 ~ 4294967295
短整形 short [int] 2 -32768 ~ +32767
无符号短整形 unsigned short [int] 2 0 ~ 65535
长整型 long [int] 4 -2147483648 ~ +2147483648
无符号长整形 unsigned long [int] 4 0 ~ 4294967295
字符型 [signed] char 1 -128 ~ +127
无符号字符型 unsigned char 1 0 ~ 255
单精度型 float 4 3.4 x 10^-38 ~ 3.4 x 10^38
双精度型 double 8 1.7 x 10^-308 ~ 1.7 x 10^308
长双精度型 long double 8 1.7 x 10^-308 ~ 1.7 x 10^308

常量

什么是常量

常量的值是不能改变的,一般从其字面形式即可判读其是否为常量。常量包括两大类:数值型常量(常数)和字符型常量。如70,0,-64为整形常量,6.8,-2.33为实型常量,包含在两个'之间的数为字符常量,如’a’,’b’这种从字面形式即可识别的常量称为字面常量直接常量

数值常量

数值常量就是通常所说的常数。在C++中,数值常量是区分类型的,从字面意思即可识别其类型。

整形常量(整数)的类型

一个常量怎样从字面上区分类型呢

  1. 一个整数,若其值在-32768 ~ -32768范围内,那么则认为它是short int型,它可以赋值给short int型,int型和long int型。

  2. 一个整数,若其值在-2147483648 ~ +2147483648范围内,则认为它是long int型,它可以赋值给int型或long int型。

  3. 如果某一计算机系统的C++版本确定int与long int型数据在内存中占据的长度相同,则它们能够表示的数值范围相同。若如此,一个int型的常量也同时是一个long int型常量,可以赋值给int型或long int型变量。

  4. 常量无unsigned型。但是,一个非负值的整数可以赋值给unsigned型变量,只要它的范围不超过变量的取值范围即可。例如,将50000赋给一个unsigned short int 型变量是可以的,但是70000就不行,会溢出。

一个整形常量可以用三种不同的方法表示。

  1. 十进制整数。如15674 , -564 , 0等,在一个整常量后面加一个l或L,则认定是long int型常量,例如156l,655L,0L等,这往往用于函数调用中。如果函数的形式参数为long int,则要求实际参数也为long int型,此时用123作实际参数就不行,要用123L才可以。

  2. 八进制整数。在常数的开头加上一个数字0,就表示这是一个八进制形式表示的常数,如020表示这是八进制数20,相当于十进制数16。

  3. 十六进制整数。在常数的开头加一个数字0和一个英文字母X或x,就表示这是一个十六进制表示的常数,如0x20表示这是一个十六进制数20,相当于十进制数32。

浮点数的表示方法

一个浮点数可以用两种不同的方式表示。

  1. 十进制小数形式。如54.6 , -84.6等。它一般由整数部分和小数部分组成,可以省略其中之一,比如.23 , 54. , .0,但不能二者皆省略。C++编译系统把用这种形式的表示的浮点数一律按双精度常量处理,在内存中占8字节。如果在实数的数字之后加字母F或f,表示此数为长精度数(long double)。
  2. 指数形式(即浮点形式)。一个浮点数可以写成指数形式,如3.14159可以表示为0.314159 x 10^1 , 3.14159 x 10^0 , 31.4159 x 10 ^-1 , 134.159 x 10^-2等形式。在程序中表示为0.314159e1 , 3.14159e0 , 31.4159e -1 , 314.159e -2 , 用字母e表示其后的数是以10为底的幂,如e12表示10^2。

其一般形式为

符号 数字部分 指数部分

上面各数据中的0.314159 ,3.14159,31.4159,134.159等就是其中的数字部分。可以看到,由于指数部分的存在,使得同一个浮点数可用不同的指数形式来表示,数字部分中小数点的位置是浮动的。例如当指数为1时,小数点的位置在数字3前面,指数为0时,小数点的位置在数字3后面。浮点数的名字就源于此。

在程序中不论把浮点数写成小数形式还是指数形式,在内存中都是以指数形式(即浮点形式)存储的,例如无论在程序中写成134.159或是3.14159e0 , 0.314159e1等形式,在内存中都是以规范化的指数形式存放的,如下表所示:

符号 数字部分 指数部分
+ .314159 3

数字部分必须小于1,同时,小数点后面第一个数字必须是一个非零数字,例如不能是0.0314159。因此,134.159或是3.14159e0 , 0.314159e1在内存中都表示为0.314159 x 10^3。储存单元分为两部分,一部分用来存放数字部分,另一部分用来存放指数部分。为了便于理解,上表使用十进制来表示的,实际上在存储单元内使用二进制来表示小数部分,用2的幂次来表示指数部分的。

对于以指数新式表示的数值常量,也都作为双精度常量处理。

字符常量

普通的字符常量

'括起来的一个字符就是字符常量。如’a’ , ‘#’ , ‘@’ , ‘W’这些都是合法的字符常量,在内存中占一个字节。注意:

  1. 字符常量只包括一个字符,比如’SH’就是不合法的。

  2. 字符常量是区分大小写的,比如’C’ , ‘c’两个字符常量是不一样的。

  3. '是定界符,被'包裹的内容是字符常量,'并不属于字符常量的一部分。比如:

1
cout << 'c';

输出的是一个字母“c”,并不是三个字符'c'

转义字符常量

除了上面那种字符常量以外,C++还允许用一种特殊的形式的字符常量,就是以\开头的一些字符,比如\n就代表一个换行符。cout << '\n';会输出一个换行,作用与cout << endl;相同。这种字符在屏幕上是不显示的,它们只管执行自己相应的操作,并且在程序中也不能一般的字符表示,只能用这种\开头的特殊字符来表示。

以下为常用的以\开头的特殊字符

字符形式 含义 ASCII代码
\a 响铃 7
\n 换行,将当前位置移到下一行开头 10
\t 水平制表(跳到下一个tab位置) 9
\b 退格,将当前位置移到前一列 8
\r 回车,将当前位置移到本行开头 13
\f 换页,将当前位置移到下一页开头 12
\v 竖向跳格 8
\\ 反斜杠字符\ 92
' 单引号'字符 39
" 双引号字符 34
\0 空字符 0
\ddd 1~3为八进制数所代表的字符
\xhh 1~2位十进制数所代表的字符

上表中列出的字符称为“转义字符”,意思是将\后的字符转换成另外一种意义的字符。如\n中的n不是代表字母n而是作为”换行“符。

上表中最后两行是用八进制数的ASCII码表示一个字符,例如\101代表以八进制数形式ASCII码101代表的字符,而8进制101就是十进制数65。\012代表八进制数012表示的ASCII字符,它相当于以十进制10表示的ASCII字符,用’376’代表图形字符“■”。用上表中的方法可以表示任何可输出的字母字符、专用字符、图形字符和控制字符。请注意\0\1000是代表ASCII码为0的控制字符,即“空操作”字符,它广泛用于字符串中。转义字符虽然包含两个或多个字符,但它只代表一个字符。编译系统在见到字符“\”时,会接着找它后面的字符,把它处理成一个字符,在内存中只占一个字节。

字符数据在内存中的存储形式及其使用方法

将一个字符常量存放到内存单元时,实际上并不是把该字符本身放到内存单元中去,而是将该字符相应的ASCHI代码放到存储单元中。如果字符变量c1的值为’a’,c2的值为’b’,则在变量中存放的是’a’ 的ASCII码97,’b’的ASCII码98,实际上在内存中是以二进制形式存放的。既然字符数据以ASCII码存储的,它的存储形式就与整数的存储形式类似。这样,在C ++中字符型数据和整型数据之间就可以通用。一个字符数据可以赋给一个整型变量,反之,一个整型数据也可以赋给一个字符变量。也可以对字符数据进行算术运算,此时相当于对它们的ASCII码进行算术运算。

例:将字符赋给整形变量。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
int main( )
{
int i,j; //i和j是整型变量
i = 'A'; //将一个字符常量赋给整型变量i
j = 'B'; //将一个字符常量赋给整型变量j
cout << i << '' << j << '\n'; //输出整型变量i和j的值,'\n'是换行符
return 0;
}

结果:

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。

可以看到,在一定条件下,字符型数据和整型数据是可以通用的。但是应注意字符数据只占一个字节,它只能存放0 ~ 255范围内的整数。

例:字符数据与整数进行算术运算,实现小写字母转换为大写字母。

1
2
3
4
5
6
7
8
9
10
11
12
#include < iostream >
using namespace std;
int main( )
{
char cl ,c2;
cl = 'a';
c2 = 'b';
cl = cl-32;
c2 = c2-32;
cout << c1 << '' << c2 << endl;
return 0;
}

结果:

A B

分析:

‘a’的ASCII码为97,而’A的ASCII码为65 , ‘b’为98, ‘B’为66。从ASCII代码表中可以看到每一个小写字母比它相应的大写字母的ASCI代码大32。C++字符数据与数值直接进行算术运算,’a’-32得到整数65,’b’-32得到整数66。将65和66存放在cl,c2中,由于cl,c2是字符变量,因此用cout输出cl,c2时,得到字符’A’和’B’(‘A’的ASCII码为65,’B’的ASCII码为66)。

字符串常量

用双撇号括起来的字符就是字符串常量,如,” abc” ,”Hello!” ,”a+b” ,”Li- ping”都是字符串常量。字符串常量”abc”在内存中占4个字节(而不是3个字节),见图2.5。编译系统会在字符串最后自动加一个’\0’作为字符串结束标志。但’\0’并不是字符串的一部分,它只作为字符串的结束标志。如

a b c \0
1
cout<<"abc"<<endl;

输出三个字符abc,不包括’\0’。

注意: “a”和’a’代表不同的含义,”a”是字符串常量,’a’是字符常量。前者占两个字节,后者占1个字节。请分析下面的程序片段:
char c;        //定义一个字符变量
c=’a’;           //正确
c=”a”;          //错误,c只能容纳一个字符
字符串常量要用字符数组来存放。
请思考:字符串常量” abc\n”包含几个字符?不是5个而是4个字符,其中“\n”是一个转义字符。但它在内存中占5个字节(包括一个“\0”字符)。编译系统遇到“\”时就会把它认作转义字符的标志,把它和其后的字符一起作为一个转义字符。如果“\” 后面的字符不能与“\”组成一个合法的转义字符(如” \c” ),则在编译时显示出错信息。如果希望将“\”字符也作为字符串中的一个字,则应写为

“ abc\\n”

此时字符包括5个字符:a,b,c,\,n。

符号常量

为了编程和阅读的方便,可以用一个符号名代表一个常量,称为符号常量,即以标识符形式出现的常量。

例:计算货款,使用符号常量。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std ;
#define PRICE 30 //注意这不是语句,末尾不要加分号
int main ( )
{
int num,total; // num代表购货数量, total代表总货款
num = 10;
total = num * PRICE; //PRICE 是符号常量,代表30(单价)
cout << "total=" << total << endl;
return 0;
}

结果:

total=300

分析:

程序中用预处理指令#define指定PRICE在本程序单位中代表常量30。请注意符号常量虽然有名字,但它不是变量。在进行编译预处理时,所有的PRICE都被置换为字符30,在正式进行编译时已经没有PRICE这个标识符了。显然,符号常量不能被赋值。如用赋值语句PRICE =40;给PRICE赋值是错误的。使用符号常量的好处是:

(1)含义清楚。在一个规范的程序中不提倡使用很多的直接常量,如sum=15*30*23.5*43。应尽量使用“见名知意”的变量名和符号常量。
(2)在需要改变一个常量时能做到“一改全改”。例如在程序中多处用到某物品的价格,如果价格用常数表示,则在价格调整时,就需要在程序中作多处修改,若用符号常量PRICE代表价格,只须改动第一行即可。如

#define PRICE 35

在程序中所有以PRICE代表的价格就会一律 自动改为35。
符号常量在C程序中用得较多,在C++程序中常用常变量,而较少用符号常量。


结束语

至此,这章巨多内容的第一节终于整理完毕,内容多数来自《C++程序设计(第三版)》中的第二章内容,希望可以帮助到正在阅读本片文章的你,最后,感谢你的阅读,祝你生活愉快,学习顺利