第2章 类型转换及流程控制
C++是一种通用的程序设计语言,特别适合于面向对象的程序设计。它支持数据抽象,支持面向对象的程序设计和通用性程序设计。面向对象程序设计是一种程序设计技术,是对一组问题编写出“好”程序的一种范例。本章的实例都是入门级的,如各类常量的使用例子,递增(increase)运算符(++)、递减(decrease)运算符(--)和取模运算(%)。
本章重点讲解控制结构,内容包括条件结构if选择、while循环及do-while循环、for循环、switch选择结构。初学者对这些内容应多实践,相互替换,本章还举了综合应用的实例,举一反三对提高编程能力相当重要。
2.1 类型转换
案例2-1 消失的重量
【案例描述】
变量在C++中,类型转换运算符可以就是将一种类型的数据转换为另一种类型的数据。转换中会造成数据达不到精度的情况,如浮点数转换为整数时,那么其值数据只就输出整数部分,也就是取整。本例消失的重量就是取整的结果,如图2-1所示。
图2-1 消失的重量
【实现过程】
程序从首先将输入的整数类型转换成浮点数类型,再从将输入的浮点数和双精度浮点数转换成整数输出。代码如下:
#include <iostream>
#include <iostream.h>
int main()
{
int inputnum0;
float inputnum1; //定义浮点数
double inputnum2; //定义双精度浮点数
std::cout << "输入物体重量(整数,吨):" << std::endl;
std::cin >>inputnum0;
std::cout << "转换成浮点数输出,吨:" <<(float) inputnum0<< std::endl;
std::cout << "输入物体重量(带2位小数,吨):" << std::endl;
std::cin >>inputnum1; //输入浮点数
std::cout << "转换成整数输出,吨:" <<(int) inputnum1<< std::endl;
std::cout << "输入物体重量(带3位小数,吨):" << std::endl;
std::cin >>inputnum2; //输入双精度浮点数
std::cout << "转换成整数输出,吨:" <<int(inputnum2)<< std::endl;
system("pause");
return 0;
}
【案例分析】
(1)从上面的代码可以看到,整数转换成浮点数后,值保持不变,但浮点数和双精度浮点数转换成整数后,其小数点后面的值就去掉了,这就是所谓的取整。变量类型转换运算符可以将一种类型的数据转换为另一种类型的数据。在C++中有几种方法可以实现类型转换这种操作,最常用的一种也是与C兼容的一种,是在原要转换的表达式前面加圆括号括起的新数据类型,如(int) inputnum1,这是比较简单的类型转换。
(2)以后的实例中会提到高级C++类型转换、控制类之间的转换,ANSI-C++标准定义了4种新的类型转换操作符:reinterpret_cast、static_cast、dynamic_cast和const_cast。
提示:实际编程中,经常需要进行数据类型转换。例如,上面的实例中数字类型的转换,以后会用显示显式类型转换。在编程中多实践时,要注意值在转换后与转换前的变化。
案例2-2 游泳池的容量
【案例描述】
实例2-1描述了类型转换,本例仍然是类型转换的实例。,输入的变量类型是double,然后经过计算后输出double和int两种类型,。实例中还会提到数学运算符的优先级问题,。本例效果如图2-2所示。
图2-2 游泳池的容量
【实现过程】
程序(1)定义一个结构体类型 struct Column,;
(2)提示用户输入游泳池的半径和高度;
,(3)按照数学方法计算出游泳池的容量和表面积,然后输出数据类型double和int的结果。
详细代码如下:
#include<iostream.h>
#include<iostream>
const double pi=3.1415926;
struct Column
{
double radius; //半径
double height; //高度
}myc;
void main()
{
double r,h;
double volum; //游泳池的容量
double surface; //游泳池的表面积
int volum1,surface1;
cout<<"输入游泳池的半径和高度";
cout<<endl;
cout<<"radius=";
cin>>r;
cout<<"height=";
cin>>h;
myc.radius=r; //半径和高度的值存储在myc结构
myc.height=h;
volum=pi*myc.radius*myc.radius*myc.height; //计算容量,假设是圆柱型
surface=2*pi*myc.radius*(myc.height+myc.radius); //计算表面积
volum1=pi*myc.radius*myc.radius*myc.height; //① 计算容量,假设是圆柱型
surface1=2*pi*myc.radius*(myc.height+myc.radius); //计算表面积
cout<<"游泳池的容量: "<<volum; //输出计算结果
cout<<"整输出为:"<<volum1;
cout<<"取整输出为:"<<(int)volum;
cout<<endl;
cout<<"游泳池的表面积: "<<surface;
cout<<"整输出为:"<<surface1;
cout<<"取整输出为:"<<(int)surface;
cout<<endl;
system("pause");
}
【案例分析】
(1)①处,经过计算得出结果volum1,右边的变量是double数据类型,volum1计算结果是int数据类型;(int)volum;是实例005提到的double转换成int显式类型转换。这两种计算结果是一样的,都是用浮点数计算,得出的浮点数再取整。
(2)编程中要注意计算的顺序,如2*pi*myc.radius*(myc.height+myc.radius);,先计算()中的,然后从左到右依次执行。在C++中出现的运算符都有优先级,计算顺序是从最高级到最低级。
提示:编写一个复杂的表达式时,若如果不确定表达式的执行顺序,那么就最好加上括号(),这样还可以使代码更易读懂。
案例2-3 显式转换
【案例描述】
在显式类型转换中,应特别注意从较高级别的类型转换为较低级别的类型时,容易引起数据的丢失,因为不同类型的数据表示的范围不同。本例是显式转换的例子,效果如图2-3所示。
【实现过程】
程序定义了无符号整型变量y,然后把整数500转换为unsigned char后,将转换后的值赋给y。代码如下:
#include <iostream>
using namespace std;
int main()
{
using namespace std;
unsigned int y=unsigned char (500); //显式转换
cout<<"y is "<<y<<endl; //输出显式转换后的值
system("pause");
return 0;
}
【案例分析】
(1)一般情况下,数据的类型转换通常是由编译系统自动进行的,不需要人工干预,所以被称为隐式类型转换。但如果程序要求一定要将某一种类型的数据转换为另外一种类型,则可以利用强制类型转换运算符的方式进行转换,这种强制转换过程方式称为显式转换。
(2)unsigned int y=unsigned char (500)这条语句进行了显式数据转换,会导致数据丢失。unsigned char没有符号位,因此只能表示0~255范围的整数。
提示:不加限制的显式类型转换往往会给程序带来很多安全隐患。
2.2 判断语句
案例2-4 计算年份是否为闰年(各种运算符结合)
【案例描述】
本章开始从基本的C++入门实例讲起,在上一第1章演示了很多数学运算符参与运算的实例,下面这个本实例综合使用这些运算符,要求输入任意一个年份,实现判断是否是闰年,并输出结果。本例效果如图2-4所示。
图2-4 计算年份是否为闰年(各种运算符结合)
【实现过程】
首先定义需要用到的2两个变量,然后提示输入年份,取得年份后判断是否为闰年,提示是否继续,直到输入的'n'或'N'退出程序。其代码如下:
#include <iostream>
using namespace std;
void main()
{
int iYear; //定义一个输入的年份变量
char choice; //定义一个是否继续输入的变量
do{
system("cls");
cout << "请输入年份:" << endl;
cin >> iYear;
//判断输入年份是否为闰年
if(iYear%4==0 && iYear%100!=0 || iYear%400==0)
cout << "该年份为闰年" << endl;
else
cout << "该年份不为闰年" << endl;
cout<<"是否继续?Y/N"<<endl;
cin>>choice;
if((choice=='n')||(choice=='N')) //如果输入的'n'或'N'
break;
}while(1);
system("pause");
}
【案例分析】
(1)实例中的几个算术运行符,'“%'”表示取模运算(module),取模运算是取两个整数相除的余数;'“=='”是一个判断等于的关系运算符,用来判断运算符两边的表达式是否相等;'“!='”表示不等于,功能上和判断'“=='”正好相反。
(2)代码中有格式do语句statement while(条件condition)的语句do{…}while(1);。语句中的条件condition如若一直是为真,就一直循环下去。代码中的Break;语句,该语句表示即使在结束条件没有满足的情况下,也可以跳出一个循环,用来结束一个无限循环,或强迫循环在其自然结束之前结束。
提示:数学运算符是编程的基础,要多编程熟练掌握。
案例2-5 打印ASCII码表
【案例描述】
从本实例开始学习控制结构,C++提供一些控制结构语句(control structures)来实现这些执行顺序。本实例通过要求循环打印0到127的ASCII码,效果如图2-5所示。
图2-5 打印ASCII码表
【实现过程】
程序初始化变量并且赋值,然后执行for,输入0到127的值赋给pch字符串,再执行一个for打印pch字符串的每一个ASCII码。代码如下:
#include <iostream>
using namespace std;
void main()
{
char szArr[129] = {'\0'}; //定义一个数组并初始化
char* pch = NULL; //定义一个字符串指针并初始化
int i = 0;
int nArr[10] = {0} ; //定义一个数组并初始化
int* pn = NULL;
//输入0到127的值到pch字符串中
for (i = 0, pch = szArr; pch < szArr + 128; pch++, i++)
{
*pch = i;
// cout << i<<endl;
}
//打印pch字符串中的每一个ASCII码
for (pch = szArr; pch < szArr + 128; pch++)
{
cout << *pch << "\t";
// printf("%s", szArr);
}
cout << endl;
system("pause");
}
【案例分析】
(1)for (i = 0, pch = szArr; pch < szArr + 128; pch++, i++)循环语句中变量i一直累加,字符串指针pch指向内存开始的位置,并赋值'\0',也就是一个字节长度,然后pch指针一直累加往后移动位置赋值'\0',直到127位置结束。
(2)ASCII码使用指定的7位或8位二进制数组合来表示128