购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第2章
数据类型

学习一门编程语言,首先要掌握它的数据类型。不同的数据类型占用的内存空间不同,合理定义数据类型可以优化程序的运行。本章将介绍C++中常见的数据类型及数据的输入与输出格式。

本章知识架构及重难点如下:

2.1 第一个C++程序

先来看一个简单的C++程序,其作用是在屏幕上输出“Hello World!”。

程序输出结果如图2.1所示。

在这个简单的C++程序中,出现了包含命令、头文件、命名空间、主函数、输出流语句、字符串常量、注释等概念,一起来认识下。

图2.1 程序输出结果

1.包含命令(#include)、头文件

C++程序中,带“#”号的语句称为预编译命令,该命令会在程序编译之前先进行。include的含义是“包含”和“引用”,#include命令则为包含头文件命令,表示本程序将嵌入指定的头文件。

所谓头文件,指的是程序中用于声明函数、变量、宏等的文件,通常以.h为后缀名。使用头文件(包括系统头文件和自定义头文件)可以方便地引用已写好的代码,提高代码的复用性和可维护性,同时降低代码的耦合度,使代码更加模块化。

因此,第一行代码“#include <iostream>”表示包含C++标准输入输出流头文件iostream.h,也就是说,程序编译时会在此处将iostream.h头文件中的内容展开。

2.命名空间(namespace)

一个中大型软件往往由多名程序员共同开发,会使用大量的常量、变量、函数、结构体、枚举、类等,因此不可避免地会出现命名冲突。工程越大,名称互相冲突性的可能性越大。为了解决合作开发时的命名冲突问题,C++引入了“命名空间”的概念。在不同的命名空间里,同名变量放在一起编译不会出现问题。

因此,第二行代码“using namespace std;”表示使用C++标准库定义的std命名空间。

3.主函数main()

第3~6行为main()函数。main()函数又称为主函数,是C++程序执行的入口。程序将从main()函数的第一条指令开始执行;main函数结束,整个程序也执行结束。其中,main为函数名,“()”里可放置参数。

其中,“int main()”是main函数的函数头,表示main()函数将返回一个整型数值;大括号“{ }”中的内容是需要执行的,称为函数体。函数体中,各行代码将按照先后顺序依次执行,写在前面的先执行,写在后面的后执行。

说明

Visual C++中通常使用void main(),但DEV C++中必须使用int main(),否则会报错。

4.输出流语句

第5行代码“cout << "Hello World!\n";”表示通过数据输出流,输出英文“Hello World!”。其中,双引号" "代表该语句是字符串常量,cout表示输出流,<<表示将字符串传送到输出流中。

注意

C语言中,我们使用scanf()、printf()函数进行数据的输入输出操作。C++兼容C语言,因此这两个格式化输入输出函数仍然可以使用。但C++提供了一套全新的、更容易使用的输入输出库,即使用数据输入输出流和cout<<、cin>>进行输入、输出。

5.注释

代码中使用了多处“//”注释,对本行代码进行解释说明。编译器不会对注释部分进行编译。

C++程序中有两种注释方法:单行注释“//”和多行注释“/* */”。

“//”是单行注释,从注释符号“//”开始,到本行代码结束的内容为注释内容,一般用于对本行代码或下面的代码进行解释说明。

“/* */”是多行注释,“/*”放在注释内容前,“*/”放在注释内容后,“/*”和“*/”中间的内容为注释部分。注意,多行注释中不允许嵌套另一个多行注释。

2.2 关键字和标识符

关键字(keywords)又称为保留字,是C++中规定的具有特定意义的字符串,如表2.1所示。用户定义的常量、变量、函数等名称不能与关键字相同,否则会出现错误。

表2.1 C++保留关键字

说明

这些关键字不需要背诵。在C++开发环境中编写代码时,保留关键字会显示为特殊格式,如变成蓝色。后续学习中,我们会逐渐熟悉这些关键字的具体用法,这里不需要死记硬背。

标识符是对C++程序中常量、变量、语句标号以及用户自定义函数等名称进行标识的符号。其命名规则如下:

标识符必须由字母、数字及下画线组成,且不能以数字开头。

C++区分大小写,因此大写和小写英文字母代表的是不同的标识符。

标识符不能是系统关键字。

标识符应体现一定的功能含义,便于理解。通常采用所表述内容的英文、拼音等,力求“见名知义”,同时应受一定规范的约束。

例如,6A、ABC*、int是不合法的标识符。其中,6A以数字开头,ABC*使用了符号“*”,int是系统关键字。mingri和MingRi是不同的标识符,因为C++区分大小写。同理,int和Int含义不同,Int不再是系统关键字,而是合法的标识符。表示长方体的长、宽、高,使用length、width、height标识符远比使用a、b、c表示更易于理解。

2.3 基本数据类型

C++包括整型、浮点型、字符型、布尔型等基本数据类型,数组、结构体、共用体等构造数据类型,指针类型,以及用户自定义数据类型。C++能够实现复杂的数据结构,还可以定义类,实现面向对象编程。首先来认识下C++中的基本数据类型,如图2.2所示。

图2.2 C++基本数据类型

2.4 常量

程序运行过程中,其值不能改变的量称为常量。常量包括整型常量、浮点型常量、字符常量、字符串常量等。

例如,下面通过cout向屏幕输出4行内容。cout是输出流,可向屏幕输出不同类型的数据。2009是整数(即整型常量),2.14是小数(即浮点型常量),'a'是字符常量,"Hello World"是字符串常量。

2.4.1 整型常量

整型常量就是整型常数(没有小数部分),如123、−456、0等。编写代码时,可将整型常量表示为十进制、八进制和十六进制3种表示形式。

十进制:我们日常见到的整数都是十进制形式的,如365、75等。十进制数使用0~9来表示所有数,递进关系为逢十进一。注意,除了0本身,其他十进制数不能以0开头。

八进制:使用0~7来表示所有的数,递进关系为逢八进一。八进制常量前要加上0作为前缀,如0123、0432等。

十六进制:使用0~9和字母A~F(或a~f)来表示所有的数,递进关系为逢十六进一。十六进制常量前要加上0x或0X作为前缀,如0x123、0x3ba4。

例如,0396不是合法的八进制整数,因为9不是八进制应有的取值;0X3N不是合法的十六进制整数,因为N不是十六进制应有的取值。

整型常量不可以无限大,它的最大值是有限定的。根据CPU寄存器位数以及编译器的不同,最大的整型常量值也会不同。

注意

“合法”主要指能通过编译器编译,“非法”或“不合法”指不能通过编译器编译。

2.4.2 浮点型常量

浮点型(又称为实型)常量就是我们常见的小数,只能采用十进制形式表示。其表示方法有两种,即小数表示法和指数表示法。

1.小数表示法

小数表示法由整数部分和小数部分组成,中间用小数点分隔。例如,0.0、2.25、0.00596、5.0、536.、-5.3、-0.002均为合法的实型常量。

另外,整数部分和小数部分可以省略一处,例如,.2表示小数0.2,2.表示小数2.0。

2.指数表示法

指数表示法又称为科学记数法,指数部分以“e”或“E”开始,后跟整数。

例如,1.2e20和-2.4e-2是合法的实型常量,其中1.2e20表示1.2×10 20 ,-2.4e-2表示-2.4×10 -2 。而E5、3E2.5不是合法的实型常量,因为E5中E之前无数字,3E2.5中E后面有小数。

说明

在字母e(或E)之前的小数部分中,小数点左边应有且只有一位非零的数字,称为规范化的指数形式。

2.4.3 字符常量

使用一对单直撇引号(' ')括起来的字符就是字符常量,如'a'、'A'、'?'、'#'、'b'等。编译代码时,编译器会根据ASCII码表将字符常量转换成整型常量。其中,'a'对应的ASCII码值是97,'A'对应的ASCII码值是65,'?'对应的ASCII码值是63。' '表示空字符(NULL),有的编译器把它编译成0,有的则编译成其他值。

除了这些固定字符,ASCII码表中还有很多无法通过键盘输入的字符。例如,2.1节示例代码中的“\n”符号,输出结果中却不显示该符号,只是进行了换行操作。这种符号称为转义字符。

表2.2 常用的转义字符

下面来看一个转义字符的应用示例,代码如下:

代码运行结果如图2.3所示。

图2.3 示例运行结果

2.4.4 字符串常量

字符串常量是用一对双直撇引号(" ")括起来的字符序列。例如,"hello"、"welcome to China"都是合法的字符串常量。其中," "表示一个空字符串,此时字符串的长度为0。

字符串常量实际上是一个字符数组,可以将字符串分解成若干个字符,字符的数量是字符串的长度。字符串常量一般用来给字符数组变量赋值或是直接作为实参传递,为告知编译器字符串已经结束,一般在给字符数组赋初值时在字符串的末尾加上字符'\0',表示字符结束,如果不加字符结束标志,可能会出现意想不到的错误。

注意

字符'A'与字符串"A"含义不同。内存中,字符'A'则只包含一个字符;字符串"A"由'A'和'\0'两个字符组成,字符串的长度是2。

2.4.5 其他常量

除了整型、浮点型、字符型、字符串型常量外,还存在布尔常量、枚举常量和宏定义常量等。

布尔常量:布尔类型(bool)是表示是否、对错等真假判断的数据类型,常用在逻辑判断中。布尔类型只有true和false两个取值。true表示真,其值为1;false表示假,其值为0。

枚举常量:枚举型数据中定义的数据也都是常量。

宏定义常量:通过#define宏定义的值也是常量。例如:

#define PI 3.1415

其中PI就是常量,代表的是3.1415。编译时遇到PI,就会被自动替换为3.1415。

2.5 变量

变量是指在程序运行期间其值可以发生改变的量。每个变量都必须有一个名称作为唯一的标识,且具有一个特定的数据类型。变量使用之前,一定要先进行声明或定义。

2.5.1 变量的声明和定义

C++中,变量声明是指为变量提供一个名称,并告诉编译器这个变量将被使用,但不会为其分配内存空间。变量声明的一般形式如下:

数据类型 变量名;

其中,“数据类型”指变量的类型,如整型、浮点型、字符型等,“变量名”则是用户给变量起的名称,必须符合标识符的命名规则。

多个同一类型的变量可以在一行中声明,变量名之间用逗号隔开。例如:

int x;
int a,b,c;

定义变量时,需要为其分配一块内存空间,以存储其值。语法形式如下:

数据类型  变量名=初始值;

例如,下面定义了多个变量:

int x=10;
int a=,b=2,c=3;
注意

定义多个赋相同初值的变量时,应写成“int a=3, b=3, c=3;”形式,不能写成“int a=b=c=3;”形式。

2.5.2 整型变量

整型变量就是用来存储整型数值的变量。

根据占有的内存空间大小,整型变量可分为基本整型(int)、短整型(short)和长整型(long)3类。根据是否有符号,还可分为有符号整型(signed)和无符号整型(unsigned)两类。因此,整型变量共分为6类,如表2.3所示。其中,方括号中的关键字可以省略。

表2.3 整型变量的分类

不同的整型,其在内存中占用的字节空间不相同,因此可表述的变量数值范围也不同。以32位操作系统为例,短整型、整型、长整型变量占用的字节数和可表示的数值范围如表2.4所示。

表2.4 整型变量可表示的数值范围

例如,下面定义了一个整型变量a,为它分配了4个字节的内存空间,并设初始值为10。

int a=10;

变量赋值时,整型常量后可以加上L或l、U或u等后缀,清晰指明其类型,如1314L、520U等。

注意

根据CPU寄存器位数和编译器的不同,最大的整型数值也会不同。32位操作系统中,基本整型(简称为整型)为4字节,长整型为4字节;64位操作系统中,基本整型为4字节,长整型为8字节。

说明

C++程序中,布尔型(bool)被当作整型对待,false表示0,true表示1。因此,将布尔型赋值给整型是合法的,将整型赋值给布尔型也是合法的。例如:

2.5.3 浮点型变量

浮点型变量分为单精度(float)、双精度(double)和长双精度(long double)3类,其占用的字节数和可表示的数值范围如表2.5所示。

表2.5 实型变量可表示的数值范围

float和double相比,double类型的变量具有更高的精度,即它可以表示更多的小数位数。float保留到小数点后7位,有效数字为6~7位;double保留到小数点后16位,有效数字为15~16位。实际开发中,一般多使用double类型,尽可能地避免精度损失。

例如,下面代码声明了多个浮点型变量。

float a;
double b;
long double c;

在程序中使用浮点型数据时,需要注意以下两点。

1.浮点型数据相加

浮点型数据的有效数字是有限制的,如float的有效数字是6位或7位,如果将数字86041238.78赋值给float类型,显示的数字可能是86041240.00,个位数8被四舍五入,小数位被忽略。如果将86041238.78与5相加,输出的结果为86041245.00,而不是86041243.78。

2.浮点型数据与0进行比较

在开发程序的过程中,经常会进行两个浮点型数据的比较,此时尽量不要使用“==”或“!=”运算符,而应使用“>=”或“<=”之类的运算符。

例如,下述代码直接将浮点型变量与0进行比较,不是高质量的代码。如果程序要求的精度非常高,可能会产生未知的结果。

通常的做法是:定义0的精度,然后判断浮点数是否在该精度范围内。例如:

程序运行结果如图2.4所示。

图2.4 程序运行结果

注意

数字里可以有下画线,这些下画线不会影响数字的值,仅提供分隔作用,方便阅读。下画线不能写在数字开头或末尾,二进制和十六进制前缀字母旁,以及小数点旁。

2.5.4 变量赋值

变量的值是动态改变的,每次改变都需要进行赋值。变量赋值的形式如下:

变量名=表达式;

其中,表达式由运算符、操作数、括号等组成。最简单的表达式就是一个数。

我们在2.5.1节中已经学习过,声明变量时可以把数值赋给变量,这个过程叫变量赋初值。除此以外,还可以先声明变量,再为其赋值。例如,下面的代码先声明整型变量i,然后将常量100赋值给i。

例如,下面的代码声明了3个整型变量i、j、k,先为变量i、j赋值,再将i+j的值赋给k。

2.5.5 字符型变量

char关键字用来定义字符型变量,其在内存中占用1个字节。例如:

字符型变量在内存中存储的是字符的ASCII码,即一个无符号整数。其形式与整型变量的存储形式一样,因此字符型数据与整型数据之间可以通用。也就是说:

(1)一个字符型数据,既可以字符形式输出,也可以整数形式输出。

(2)允许对字符数据进行算术运算,即对它们的ASCII码值进行算术运算。

误区警示

给char型变量赋值时不能使用3个单引号,否则编译器会无法识别开始和结束位置。例如:

     char cChar='A'';                /*使用3个单引号为字符型赋值*/

上述代码编译时会提示“error c2001:newline in constant”错误。

【实例2.1】 字符型数据进行算术运算。 (实例位置:资源包\TM\sl\2\1)

本实例中,定义两个字符型变量并赋值,一个字符进行减32计算,另一个字符进行加32计算,最后这两个字符分别进行加10计算,并通过格式化输出函数printf()以%d和%c格式输出。代码如下:

程序运行结果如图2.5所示。

编程训练(答案位置:资源包\TM\sl\2\编程训练\)

【训练1】字符B的无中生有 程序中不出现字符“B”,试着输出字符“B”。

【训练2】预测“B+32”的结果 以字符格式%c输出“'A'+32”的结果,观察结果,猜测一下“'B'+32”的结果。

图2.5 字符型数据进行算术运算

2.6 数据的输入与输出

在用户与计算机进行交互的过程中,数据输入与输出是必不可少的操作过程。计算机需要通过输入获取用户的操作指令,并通过输出显示操作结果。本节将介绍数据输入与输出的相关内容。

2.6.1 C++中的流

C++中,数据的输入和输出发生在标准输入/输出设备(即键盘和显示器)、外部存储介质(即磁盘文件),以及内存空间之间。因此,对键盘和显示器的输入/输出简称“标准I/O”,对磁盘文件的输入/输出简称“文件I/O”,对内存空间的输入/输出简称“串I/O”。

C++把数据之间的这种传输操作称为“流”,意思是数据传输过程像水一样从一个地方流到另一个地方,实现输入的为输入流,实现输出的为输出流。流既可以表示数据从内存传送到某个载体或设备中,也可以表示数据从某个载体或设备传送到内存缓冲区中。程序用流统一对各种计算机设备和文件进行操作,使程序与设备、文件无关,提高了程序设计的通用性和灵活性。

C++定义了ios基类,以及由其派生的输入流类istream和输出流类ostream。标准I/O操作有4个类对象,分别是cin、cout、cerr和clog。其中,cin代表标准输入设备(即键盘),也称cin流或标准输入流;cout代表标准输出设备(即显示器),也称cout流或标准输出流。当进行键盘输入操作时,使用cin流;当进行显示器输出操作时,使用cout流;当进行错误信息输出操作时,使用cerr流或clog流。

C++数据流通过重载运算符“>>”和“<<”执行输入和输出操作。输出操作使用左移运算符“<<”向流中插入一个字符序列,输入操作使用右移运算符“>>”从流中提取一个字符序列。

1.cout语句

cout语句的一般格式为:

cout<<表达式1<<表达式2<<…<<表达式n;

cout代表显示器,执行cout << x操作就相当于把x的值输出到显示器。

先把x的值输出到显示器屏幕上,在当前屏幕光标位置显示出来,然后cout流恢复到等待输出的状态,以便继续通过插入操作输出下一个值。当使用插入操作向一个流输出某个值后,再输出下一个值时将被放在上一个值的后面,所以为了让流中前后两个值分开,可以在输出一个值后接着输出一个空格,或一个换行符,或其他需要的字符或字符串。

一个cout语句可以分写成若干行。例如,下面的语句:

cout<< "Hello World!" <<endl;

可以简单地写成多行:

也可写成多个cout语句:

2.cin语句

cin语句的一般格式为:

cin>>变量1>>变量2>>…>>变量n;

cin代表键盘,执行cin>>x操作就相当于把键盘输入的数据赋给变量x。

通过键盘输入数据时,只有输入完数据并按下Enter键后,系统才会把该行数据存入键盘缓冲区,供cin流顺序读取给变量。另外,从键盘上输入的每个数据之间必须用空格或Enter键分开,因为cin为一个变量读入数据时是以空格或Enter键作为其结束标志的。

当cin>>x操作中的x为字符指针类型时,则要求从键盘的输入中读取一个字符串,并把它赋值给x指向的存储空间。若x没有事先指向一个允许写入信息的存储空间,则无法完成输入操作。另外,从键盘上输入的字符串,其两边不能带有双引号定界符,若有则只作为双引号字符看待。对于输入的字符也是如此,不能带有单引号定界符。

例如,下面的代码可将用户输入的数打印出来。其中,endl用于向流的末尾部位加入换行符。

【实例2.2】 默写王之涣的《登鹳雀楼》。 (实例位置:资源包\TM\sl\2\2)

使用cout向控制台输出唐朝诗人王之涣的《登鹳雀楼》,具体代码如下:

运行程序,将向控制台屏幕输出诗句,效果如图2.6所示。

图2.6 向控制台屏幕输出诗句

2.6.2 格式化输出

1.流输出(cout)

cout是输出流类ostream的对象,通过其中的成员函数可对数据进行格式化输出,如表2.6和表2.7所示。

表2.6 ostream类的成员函数

表2.7 格式化常量

这些成员函数使用时,前面要加上cout对象名,如cout.setf(ios::left)、cout.width(5)等。另外,可以同时设置多种格式,不同格式间用“|”连接。例如,数据输出时要求左对齐且字母大写,格式应为cout.setf(ios::left|ios::uppercase)。

另外,C++标准库提供的iomanip.h头文件中包含了大量的格式控制符,如表2.8所示,可以直接使用它们进行数据格式化输出,更加简单、快捷。仔细观察,读者会发现这些格式控制符和表2.7中的格式化常量非常相似,但可设置的格式更多。

表2.8 C++格式控制符

【实例2.3】 变幻莫测的整数。 (实例位置:资源包\TM\sl\2\3)

本实例中,定义一个整型变量并赋值,利用不同形式输出整型,具体代码如下:

程序运行结果如图2.7所示。

【实例2.4】 十六进制与十进制转换。 (实例位置:资源包\TM\sl\2\4)

本实例中,定义两个整型变量,一个为十六进制整数,另一个为十进制整数。利用cout输出第一个变量的十进制、十六进制形式,第二个变量的小写十六进制和大写十六进制形式。代码如下:

程序运行结果如图2.8所示。

图2.7 整数输出

图2.8 十进制和十六进制转换

【实例2.5】 控制输出精确度。 (实例位置:资源包\TM\sl\2\5)

本实例中,定义一个整型变量并赋值,定义一个双精度变量并赋值,利用cout输出这两个不同精度的格式,具体代码如下:

程序运行结果如图2.9所示。

【实例2.6】 千变万化的小数。 (实例位置:资源包\TM\sl\2\6)

本实例中,定义两个单精度类型,用cout输出不同长度的小数,具体代码如下:

程序运行结果如图2.10所示。

图2.9 控制输出精确度

图2.10 流输出小数控制

2.printf()函数输出

C++中保留了C语言的输出函数printf(),使用它可将任意数量、类型的数据输出到屏幕中。printf()函数的声明形式如下:

printf("[控制格式]... [控制格式]...",数值列表);

其中,“数值列表”为待输出数值,可以是多个数值,相邻数值间用逗号隔开;“控制格式”表示数值输出的格式,其数量与待输出数值一致,并一一对应。

控制格式的以“%+特定字符”,形式如下:

%[*][域宽][长度]类型

其中,“*”代表可以使用占位符;“域宽”表示输出长度,如果输出内容没有域宽长,用占位符占位;如果比域宽长,按实际内容输出,以适应域宽;“长度”决定输出内容的长度。例如,%d表示以整型格式输出数据,%c表示以字符格式输出数据。

常见的格式输出类型及输出方式如表2.9所示。

表2.9 printf()函数常见格式输出类型

【实例2.7】 整数的格式控制输出。 (实例位置:资源包\TM\sl\2\7)

本实例中,使用printf()函数输出整型数,在格式控制时分别以空格和“0”为占位符。代码如下:

程序运行结果如图2.11所示。

【实例2.8】 字符串的格式控制输出。 (实例位置:资源包\TM\sl\2\8)

本实例中,定义字符型指针(这里不用理会,第7章中会详细介绍)保存字符串"helloworld",利用printf()函数输出,体会不同格式控制下的输出差异。代码如下:

程序运行结果如图2.12所示。

图2.11 整型数格式输出

图2.12 字符串格式输出

【实例2.9】 浮点数的格式控制输出。 (实例位置:资源包\TM\sl\2\9)

本实例中,定义单精度浮点数和双精度浮点数,利用printf()函数输出,体会不同格式控制下的输出差异。代码如下:

程序运行结果如图2.13所示。

【实例2.10】 科学计数法输出。 (实例位置:资源包\TM\sl\2\10)

本实例中,利用printf()函数和格式控制符%e,用科学计数法输出小数。代码如下:

程序运行结果如图2.14所示。

图2.13 浮点数格式输出

图2.14 科学计数法输出

误区警示

%x、%X、%#x、%#X的区别:%x表示输出字母小写形式,%X表示输出字母大写形式,#表示输出标准十六进制形式。建议添加“#”,否则当输出的十六进制正好没有字母时,会被误认为是一个十进制数。

编程训练(答案位置:资源包\TM\sl\2\编程训练\)

【训练3】控制台输出汉字 使用cout向控制台输出汉字“明日科技”。

【训练4】地球的年龄有多大 地球的年龄约为45.5亿年,用科学计数法输出地球的年龄。

2.7 实践与练习

答案位置:(资源包\TM\sl\2\实践与练习\)

综合练习 1:输出狙击枪形状 利用字符串常量输出狙击枪形状,输出形状如下。(提示:利用搜狗特殊符号。)

综合练习 2:模拟超市结账 某人在超市挑选的商品价格分别为56.75元、72.91元、88.50元、26.37元和68.51元,计算他应支付的总金额。运行结果如下:

实际应付313.04元

综合练习 3:模拟缴纳电费 编写一个程序,先模拟输出电费账单,然后要求用户输入缴费金额(大于574元),输出当前账户的电费余额,输出结果如图2.15所示。

图2.15 实现效果

综合练习 4:数字与字母 输出整型数65对应的字母,再输出整型数97所对应的字母,最后根据二者的差值,推导大字母和小写字母的关系。 hrhx23l0AQ2kWhh2XYPxvFdEoFnn0CA4XJG67DlF3Xdp4U8rpUBzuxG3z3splHow

点击中间区域
呼出菜单
上一章
目录
下一章
×