C++语言基础介绍_第1页
C++语言基础介绍_第2页
C++语言基础介绍_第3页
C++语言基础介绍_第4页
C++语言基础介绍_第5页
已阅读5页,还剩236页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

工程软件

武汉理工大学机电学院徐东亮第二章编程根底介绍工程软件武汉理工大学机电学院徐东亮本章知识要点计算机的组成

计算机的工作模式

程序、编程语言、编译器算法和流程图存储器、变量结构化程序设计实现模块化编程2.1根本概念计算机的组成计算机硬件系统由3种类型的组件组成:(1)输入设备:将数据输入到计算机中。(2)中央处理器〔CPU〕:负责处理数据。(3)输出设备:显示或记录最终结果。计算机的工作模式背景:以宽带数据公司的客户效劳管理系统为例,当想要得到某一个客户的详细资料时,可以键入客户代码到计算机中,计算机进行相应的处理后,在屏幕上会显示出有关该客户的详细信息。为了理解在把客户代码键入到计算机时所发生的事,可以把整个的活动分成三个步骤:1)输入:把客户代码键入计算机系统。

2)处理:计算机处理此客户代码信息,检查是否有此客户存在。3)输出:结果显示在计算机屏幕上,列出客户的详细资料。程序任何计算机系统都有两个重要组成局部——硬件和软件。硬件是计算机的设备装置,对计算机而言,更重要的是指令〔软件〕。告诉计算机怎么做的指令集合称为软件,或者是程序。可以说程序是计算机的灵魂,离开了计算机程序,计算机将一事无成。设计程序并不依赖于对计算机的非常复杂结构知识的了解。编程语言大体上,程序设计语言分为以下几类:(1)

机器语言(2)汇编语言(3)高级语言从对客观系统的描述角度,可以将高级语言分为以下两类:(1)面向过程语言〔例:C语言、Pascal、FORTRAN〕数据结构+算法(2)面向对象语言〔例:Delphi、VisualBasic、Java、C++、C#〕对象+消息编译器编译器是一个特殊的程序,它处理用一种特定的编程语言编写的程序,并将其转换成机器语言。

输入高级语言输出机器语言编译过程对于每种编程语言,都有不同的编译器。转换处理2.2编译、链接、运行编译、链接、运行编写一个C++程序到完成运行,一般要经过以下四个步骤:1.将程序录入计算机——编辑;2.编译;3.链接;4.运行程序.2.3算法和流程图算法算法是一套完成某一任务或解决某一问题的规那么或指令。算法是一系列承上启下的指令,其中每个后续的步骤是由上一步骤的结果来决定的。下面是计算机查询客户资料的算法描述:1〕接收客户代码。2〕检查此客户是否存在。3〕如果客户存在,那么显示此客户的详细信息〔客户姓名、性别、地址、、邮箱、身份证号码〕,否那么停止。对于计算机编程来说,算法常常是使用被称为流程图的框图来设计的。流程图流程图是一种图形化工具,使用流程图将使得逻辑的沟通和表达变得更容易。流程图是算法的图形表示形式。流程图包含一系列符号。每个符号表示算法中描述的一个特定活动。流程图中常用的符号表示如下:如何画一个流程图制作咖啡的流程图之一:加入水、咖啡粉、糖和牛奶煮沸混合物咖啡准备好了开始结束制作咖啡的流程图之二:煮沸混合物结束加入糖加入牛奶搅拌混合物咖啡准备好加入水和咖啡粉开始计算一个数平方的流程图:StartInputanumberComputesquareStopPrinttheresult存储分为两类:1〕内部存储器:临时、电维持、读写速度快2〕外部存储器:永久存储、读写速度慢在程序运行之前,必须将程序的指令装入内存中。如果需要屡次使用一个程序,那么需要在一些稳定的介质〔外存储器〕上将程序保存下来。存储器命名和使用变量计算机内存由数百万个存储数据的可编址存储单元组成。程序一般通过变量来引用内存单元。一个变量对应一个内存单元,内存单元的内容在程序运行期间是可以改变的。每个编程语言都有自己的变量命名规那么。常量就像一个变量一样对应内存的一个单元,不同的是,在程序中,常量是不会改变的。数据类型计算机可以处理两种根本数据类型:1〕数值型数值常量和数值变量2〕字符型字符常量和字符变量2.4结构化程序设计顺序结构使用顺序结构,程序可以依次执行每一个动作。AB选择结构现实生活中的大多数问题需要根据条件做出选择。运用选择结构,程序将根据条件选择两者之一的动作执行。以下图分别表示:二元选择和一元选择QuestionBAQuestionAYesNoYesNo例如:某公司员工的根本工作量是每周40小时,薪金是每小时50元,每周工作超过40小时认为是超工作量,对于超工作量公司将支付2倍的酬劳。以下图的流程图片段说明这个分支结构。hoursWorked>40?totalPay=hoursWorked*50totalPay=40*50+(hoursWored-40)*2*50TrueFalse如果员工有缺席现象,那么每周总的薪水将减少100元。假设员工全勤,那么不执行此过程。absence=‘Y’?totalPay=totalPay-100NoYes计算一个正数的平方的流程图calculatedAnswer=inputNumber*inputNumberStartInputinputNumberOutputcalculatedAnswerStopInputNumber>0?TrueFalse比较两个数,输出较小数的流程图

StartInputnNum1StopInputnNum2nNum1=nNum2?nNum1<nNum2?Display“Thenumbersareequal”DisplaynNum1DisplaynNum2TrueFalseTrueFalse循环结构计算机的一个重要特性就是能够重复地执行一串指令。循环是一种周而复始的逻辑结构。它使一系列的步骤不断重复。

有两类循环:固定的循环〔循环次数〕和可变的循环〔循环次数未知〕QuestionATrueFalse例子:公司某个员工的月收入,计算他的年收入。在这个过程中有些事件是被重复执行的,为了求解此问题,可以使用循环的概念。StartStopInputmonthPaycounter=0yearPay=0yearPay=yearPay+monthPaycounter=counter+1counter<12PrintyearPayTrueFalse前面讨论的例子是循环次数的情形。为了解决循环次数未知的情形,增加一个存储用户选择的变量,通过检查此循环变量中的值,来决定是否循环继续进行。声名一个字符类型的变量choice,并初始化为“Y”。choice=‘Y’?choice=‘Y’TrueFalse例如,接收和显示客户的详细资料。在这里客户的数目是未知的。

StartInputname,sex,address,email,phone,identityStopchoice=‘Y’?choice=‘Y’InputchoicePrintname,sex,address,email,phone,identityDisplay“Anymoreemployees(Y/N)”

No

Yes2.5模块化编程思想模块程序员将一个程序分解成许多合理的单元,然后再组合成一个完整的程序。这些合理的单元成为模块,有时也称子程序、过程、函数或者方法。

模块化编程的思想是将一个大的应用程序分解为很多小模块。主程序可以调用每个模块,在子模块中又可以调用其他的模块。

在某一特定模块执行结束后,控制转回到调用处的下一条指令。模块化的优点模块化程序更有助于程序员理解程序逻辑结构,让程序设计者把注意力集中在改善整体性能上。模块化的一个好处在于支持并行工作。使用模块化的思想编写程序的另一个好处是支持软件重用。模块化设计使用模块化的思想设计的流程图叫模块化流程图。模块化流程图包含控制模块〔或主模块〕和一系列子模块。控制模块描述程序的总体结构并包含程序的Start和Stop终止符。每个子模块较为详细地描述了由条状过程符号指明的过程。例如,要接收两个数并显示它们的平均值。

StopStartInputnum1,num2,avgAveragePrintavgAverageavg=(num1+num2)/2Return2.6C++语言根底介绍

2.6.1对象什么是对象我们可以把飞机、汽车等等划分成假设干个零部件,然后将各个零部件装配成整体,那么,一台复杂的飞机或汽车就完成了。同样,软件也可以这样开发。先把系统分解为假设干个组成对象,它们彼此交互,最后用这些对象“装配出”整个系统软件。这就是构造软件的面向对象〔Object-Oriented〕方法。在物理实体中,把对象定义为:“可以看得见,摸得着的实体。”同理,“人为的概念,或者是任何有明确边界与意义的东西,也是对象”。它们都有着同一的特征:拥有状态和行为。状态是对象的一个或多个属性的描述,“灯是亮着的”,这是它的状态。行为是对象为了改变自身的状态而发生的作用和反作用,“把灯关了”,这是它的行为。“软件中的对象是封装了数据结构及可以施加在这些数据结构中的操作的封装体,这个封装体有可以惟一地标识它的名字,而且向外界提供一组效劳〔即操作〕。”应用“对象”的概念来分析现实世界“666”2.6.2C++程序、变量及根本数据类型最简单的C++程序一个最简单的C++程序一般由以下两局部组成:头文件、main()函数:编译、运行上面的程序,结果是在屏幕上显示“Hello,world!”几个字符。〔1〕头文件#include<头文件>:此语句称为文件包含命令。预处理时,把头文件包含的代码引入到源程序中,然后再进行编译。〔2〕main函数对于每个C++程序,必须定义一个称作main()的函数,也称为主函数,它是C++程序开始执行时第一个调用的函数,所以,也可以把main()函数称为“程序的入口”。变量及数据类型〔1〕为什么需要变量?变量为我们提供了一个有名字的内存存储区,可以通过程序对其进行读写和处理。定义了变量之后,计算机就可以暂时地把用户输入的信息保存到变量中,直到程序运行结束,并把结果显示到屏幕上。〔2〕如何给变量命名语法规那么、习惯取向。〔3〕为什么需要数据类型在C++中,每一个变量都与一个特定的数据类型相关联,这个类型决定了相关内存的大小、布局,以及能够存储在该内存区的值的范围。打个比方,成人与小孩穿的衣服,无论是款式还是大小都是不同的。〔4〕C++中根本的数据类型BYTEWORDDWORD例如:分别为C++内置的根本数据类型各定义一个变量,并初始化变量。intm_age=20;BOOLbLButtonDown;bLButtonDown=TRUE;2.6.3C++根本运算符C++的根本运算操作〔1〕赋值运算符赋值运算符"="的作用就是把右操作数的值复制一份给左操作数,注意,总是从右向左赋值的。举例说明如下:y=3//把3赋给变量y,变量y以后的值就是3了;y=x;//把x的值赋给y;y=x=3;//也可以把值同时赋给多个变量,这里,先对x赋值,然后对y赋值。C++的根本运算操作〔2〕双元算术运算符C++语言中有5个双元算术运算符,可以使用它们来进行加、减、乘、除、求模等运算。例如:算术表达式:z=x+y。它的作用就是将变量x、y的值相加,并把结果赋值给变量z。注意a.两个整数相除的结果是整数,如果商含有小数局部,将被截掉;b.当把不同类型的表达式赋值给一个变量时,编译器会试着隐式地将右操作数的类型转换成被赋值变量的类型;〔3〕自反算术赋值运算符为了简洁,C++还提供了一种压缩方式的运算符,把算术运算符与赋值运算符压缩在起来,称之为自反算术赋值运算符。x+=(y=3);x*=Count;〔4〕单目运算符在自反算术赋值运算符中,有两种更特殊的情况,即:x+=1和x-=1我们称之为单目运算符:增量和减量运算符。注意:自加和自减运算符有两种使用方式:前缀和后缀表示法。前缀表示法:++x;或--x;后缀表示法:x++;或x--;前缀表示法,是“先增值后引用”;而使用后缀表示法,那么是“先引用后增值”。这两种表示法导致的结果会截然不同。〔5〕关系运算符在C++语言中,用关系运算符来指出两个值之间的大小关系的。关系运算符计算的结果只能是0或1,1代表true,0代表false。〔6〕逻辑运算符C++语言中有3个逻辑运算符,它们分别是:“与”、“或”、“非”。与关系运算符一样,逻辑运算符计算的结果也是0或1,1代表true,0代表false。〔7〕条件运算符条件运算符只有一个,就是:expr1?expr2:expr3条件expr1的计算结果不是true就是false,如果它是true那么返回的结果是表达式expr2;否那么返回的结果是表达式expr3。举例如下:z=(x==y?1:0);提出问题:当旅客乘坐飞机的时候,他所携带的物品为20公斤,那么航空公司将对他收取多少费用呢?请编写程序计算。分析问题:超过15公斤,但小于25公斤时,收费标准为:前15公斤的货物不收费;15公斤以后的货物,按每公斤12元收费;计算公式:charge=0;charge=charge+(weight-15)*12;选述解决问题:#include<iostream.h>voidmain(){

cout<<"Thisiscargo-chargeprogram!"<<endl;floatweight=20; floatcharge=0;//初始化变量charge的值为0;

//计算重量在15公斤到25公斤之间的货物的费用;

charge=charge+(weight-15)*12;

cout<<"Theweightis:"<<weight<<endl;

cout<<"Thechargeis:"<<charge<<endl;}-VC输入输出采用交互窗口界面2.6.4普通函数

什么是函数函数可以被看作是一组由用户定义的操作。

例如:我们要模仿倒车的警示动作,在屏幕上显示信息“Danger,backingacar!”几个字符,于是就要编写如下函数:voidback(){

cout<<"Danger,backingacar!";}函数的构成函数定义包括了以下局部:函数返回类型、函数名、参数表和函数体。函数声明与函数调用函数声明描述了函数的接口〔interface〕,它描述了函数必须接收的信息类型〔参数表〕,以及它返回的信息类型〔返回类型〕;--》函数原型在声明函数之后,就可以进行函数调用了,我们可以理解为“使用函数”。当函数名后面紧跟着调用操作符“()”时,这个函数就被执行了。调用时,参数传递方式如以下图〔假设输入的两个数为3和4〕:整个程序的执行调用过程如以下图:函数声明是对所用到的函数的特征进行必要的声明,以确保调用的实参和函数的形参能正确传递参数,所以,参数的个数、类型和排列顺序都是有严格要求的。当然,如果函数不需要接收参数,那么,函数名后紧跟着操作符()就可以了。2.6.5传值调用、引用调用传值调用当采用“传值调用”进行函数调用时,在调用过程中,首先把实参的值复制一份到被调用函数的形参中,调用函数时,不改变程序中原先变量的值,如例:传值调用#include<iostream.h>voidswapcall(inta,intb){ cout<<"Intheswapcallfunction,a=:"<<a<<endl; cout<<"Intheswapcallfunction,b=:"<<b<<endl;inttemp;//交换变量a、b的值; temp=a; a=b; b=temp; cout<<"After,Intheswapcallfunction,a=:"<<a<<endl;cout<<"After,Intheswapcallfunction,b=:"<<b<<endl;}voidmain(){ intx,y; x=1; y=2; cout<<"Inthemainfunction,x=:"<<x<<endl;cout<<"Inthemainfunction,y=:"<<y<<endl; voidswapcall(int,int); swapcall(x,y);//传值调用 cout<<"After,Inthemainfunction,x=:"<<x<<endl;cout<<"After,Inthemainfunction,y=:"<<y<<endl;}使用别名的引用调用变量的实质就是我们给的一块有名字的特定大小的内存空间。就像我们人可以有多个名字一样,比方说,张三先生,在公司里同事叫他“张三”,在家里,他的夫人叫他“阿三”,他的父母可能叫他“铁蛋”。虽然名字不同,但是指的都是同一个人。对于一块内存空间,我们也可以为其取多个名字。为了给一块内存取多个名字,我们要用到一个特殊的符号“&”,通过这个特殊的符号定义的变量称为“引用变量”。如以下的程序所示:voidalias(){ intcount; count=10; cout<<"countis:"<<count<<endl; //变量a是count的别名 int&a=count; a++;//由于a与count变量都是指向同一块内存空间,所以变量a加1,实质上就是count被加1; cout<<"ais:"<<a<<endl; cout<<"countis:"<<count<<endl;}引用提供了变量的别名,在函数调用中,我们也可以使用别名来进行函数的参数传递,即使用别名的引用调用,例如:voidswapcall(int&a,int&b)//在形参前加上了“&”符号,表示形参是实参的别名;{//交换变量a、b的值;

temp=a; a=b; b=temp;}voidmain(){ voidswapcall(int&,int&);//函数声明;

swapcall(x,y);//使用别名的引用调用;}2.7C++的流程控制语句if条件判断语句

if语句的动机:判断指定的表达式是否为true,然后有条件地执行一条语句或语句块。if语句的语法如下:

if(表达式){

语句1;}else{

语句2;}框图如下:提出问题:我们刚学习了条件判断语句,那么,如何利用它来实现对货物进行分段收费呢?分析问题:航空公司对货物超重的旅客实行分段收费,收费标准为:在旅客所携带的物品的重量不超过15公斤时,可免费携带;

floatcharge=0; if(weight<=15) { charge=charge; }超过15公斤,但小于25公斤时,收费标准为:〔1〕前15公斤的货物不收费;〔2〕15公斤以后的货物,按每公斤12元收费; floatcharge=0; if(weight>15&&weight<=25) { charge=charge+(weight-15)*12; }超过25公斤,但小于45公斤时,收费标准为:〔1〕前15公斤的货物不收费;〔2〕15~25公斤之间的货物,按每公斤12元收费;〔3〕25公斤以后的货物,按每公斤15元收费; floatcharge=0; if(weight>25&&weight<=45) { charge=charge+(25-15)*12+(weight-25)*15; }超过45公斤,但小于80公斤时,收费标准为:〔1〕前15公斤的货物不收费;〔2〕15~25公斤之间的货物,按每公斤12元收费;〔3〕25~45公斤之间的货物,按每公斤15元收费;〔4〕45公斤以后的货物,按每公斤20元收费; floatcharge=0; if(weight>45&&weight<=80) { charge=charge+(25-15)*12+(45-25)*15+(weight-45)*20; }超过80公斤时,收费标准为:〔1〕前15公斤的货物不收费;〔2〕15~25公斤之间的货物,按每公斤12元收费;〔3〕25~45公斤之间的货物,按每公斤15元收费;〔4〕45~80公斤之间的货物,按每公斤20元收费;〔5〕80公斤以后的货物,按每公斤30元收费; floatcharge=0; if(weight>80) { charge=charge+(25-15)*12+(45-25)*15+(80-45)*20+(weight-80)*30; }解决问题:通过判断,程序就可以知道旅客携带货物的重量所在的收费段,然后调用相应的收费公式进行计算,完整的程序见教材。switch多分支语句switch语句的语法如下:switch(条件表达式){case常量表达式1:语句1;break;case常量表达式2:语句2;break;……case常量表达式n:语句n;break;default:语句n+1;}当执行switch语句时,条件表达式的值与常量表达式的值比较,如果那一个case后面的常量表达式的值与条件表达式的值相等,那么程序将执行这个case后面紧跟的语句,直到遇到break跳出switch语句。如果没有一个常量表达式的值与条件表达式的值相等,那么程序那么执行default后面紧跟的语句,如果连default语句也没有,那么程序什么也不执行。注意switch语句中,程序是以匹配的case语句作为入口,相对应的break语句作为出口的。如果漏掉了其中一个break语句,那么程序将会一直执行,直到遇到下一个break语句或执行完default语句。循环语句循环就是在某个条件保持为真时重复地执行一组语句,直到条件不再符合。在C++中,又可以分为while循环语句、do…while循环语句、for循环语句三种。〔1〕while循环语句while语句的语法如下:while(表达式){语句1;}框图如下:break语句:break语句用于把程序流程退出循环体,如:while循环、for循环等。举例说明如下:#include<iostream.h>voidmain(){ charc;while(c!='q') {

cout<<"\nEnteraletter,please:";

cin>>c;if(c=='b')break;//当按下b,退出循环体

cout<<"Theletteris:"<<c; }}continue语句:continue语句用于跳过循环体中continue语句之后的任何语句,返回到while循环的开始,再次判断条件表达式,继续执行循环体。continue语句同样可以用于for循环。举例说明如下:

#include<iostream.h>voidmain(){ charc;while(c!='q') {

cout<<"\nEnteraletter,please:";

cin>>c;if(c=='c')continue;//当按下c,返回到循环体的开始处

cout<<"Theletteris:"<<c; }}〔2〕do…while循环语句do…while循环类似于while循环,它的差异是:do…while循环体至少也要执行一次,然后才判断表达式的值是否为真。注意,不要忘了while语句后带的分号。do…while语句的语法如下:do{语句1;}while(表达式);框图如下:〔3〕for循环语句for循环语句提供了控制循环重复一定次数的方式,for循环最普遍的用法是遍历一个定长的数据结构,如,数组等。for循环语句的语法如下:for(初始化语句;条件语句;表达式){语句1;}框图如下:举例说明:求数字1到10的平方的和〔12+22+…+102〕。#include<iostream.h>voidmain(){ for(inti=1,sum=0;i<=10;i++) { sum=sum+i*i; } cout<<"Thesumis:"<<sum;}选述提出问题:请为“航空货物托运费用计算程序”编写一菜单,以方便工作人员的操作。分析问题:要实现程序可以重复操作,那么就需要用到条件永为真的循环语句了:

while(true){…………return;}要能够让工作人员操作,那么就要给出选择,然后工作人员选择相应的操作:cin>>c;switch(c){ case'a': …… break; case'c': …… break; case'd': …… break; case'q': return;//返回,退出程序;

default:

cout<<"\nYourenteriserror,selectagain!";}解决问题:voidmain(){ charc; while(true){……

cin>>c; switch(c) { case'a': break; case'c': break; case'd': break; case'q': return;//返回,退出程序;

default:

cout<<"\nYourenteriserror,selectagain!"; } }}2.8变量的作用范围及块程序结构重要变量的作用范围根据变量的作用范围,变量可分为:a.局部变量;b.全局变量;〔1〕局部变量局部变量就是定义在函数体内或if、while、for等控制结构内的变量。局部变量不可在该函数或该控制结构之外被访问,否那么,变量将失效。voidcall1(){charl_c='l';//定义了局部变量l_ccout<<"\nIcansee"<<l_c<<"here!";}voidcall2(){ cout<<"\nIcan'tsee"<<l_c<<"here?";//出错:'l_c':undeclaredidentifier}〔2〕全局变量全局变量〔extern〕就是被定义在所有函数之外的变量,处于程序最外层的范围。全局变量在整个程序文件内都是可访问的,它的作用范围最大。假设要定义一个全局变量,只需在所有函数之外定义该变量即可。同时,关键字extern为声明〔不是定义〕一个全局变量提供了方法,实际上,它有点类似于函数声明,承诺了该变量会在其他地方被定义。例如:externinti;对程序来说是一个“保证”,表示在其他某个地方存在一个如下所示的定义:inti;举例说明:考察以下文件3-2-1.cc给出的代码。inti=0;//定义了全局变量ivoidmain(){ voidex_example();

cout<<"\nTheiin3-2-1.ccis:"<<i<<endl;ex_example();}再考察另一文件3-2-2.cc给出的代码,我们把变量i声明为全局变量。externinti;//声明这是全局变量ivoidex_example(){

cout<<"\nTheiin3-2-1.ccis:"<<i<<endl; i=1;

cout<<"\nTheiin3-2-2.ccis:"<<i<<endl;}程序块结构考察以下程序,注意变量的作用范围。#include<iostream.h>voidmain(){ intx=0;cout<<"\nHere,Icanseex="<<x;{cout<<"\nHere,Icanalsoseex="<<x;inty=1; cout<<"\nHere,Icanseey="<<y; }//cout<<"\nButhere,Ican'tseey="<<y;//如果参加这句代码,编译会出错:error:'y':undeclaredidentifier}函数中,被一对花括号包含着的代码段,被称为程序块。程序块内可以访问程序块外定义的变量,但是,在程序块外却不能访问程序块内定义的变量。程序块内称为“小范围”,程序块外函数体内,称为“大范围”,访问原那么是:大范围包含小范围。如果大范围与小范围都定义了同名的变量,那么,进入了小范围后,大范围定义的变量将会被忽略。在小范围内,从变量定义开始,到小范围作用域结束,一直使用的都是小范围定义的那个变量。但是,回到了大范围之后,大范围定义的变量将再次显身。我们可以知道,在大、小范围内定义的同名变量,在各自的作用范围内互不干扰。2.9类型转换隐式类型转换考察以下赋值:intx=0;x=3.541+3;最终结果:x的值为6。C++定义了一组类型对象之间的标准转换,在必要时,它们被编译器隐式地应用到对象上。隐式类型转换发生在以下这些典型的情况下:(1)在混合类型的算术表达式中。在这种情况下,最宽的数据类型成为目标转换类型,这也被称为算术转换。(2)用一种类型的表达式赋值给另一种类型的对象。在这种情况下,目标转换类型是被赋值对象的类型。而且,这些转换并不是四舍五入的,而是直接截取。(3)把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同。在这种情况下,目标转换类型是形式参数的类型。(4)从一个函数返回一个表达式,表达式的类型与返回类型不相同。在这种情况下,目标转换类型是函数的返回类型。显式类型转换显式类型转换语法如下:强制类型转换符<目标类型>(表达式)static_cast<int>(dval)在引入强制类型转换符之前,显式强制转换由一对括号来完成,标准C++仍然支持这种旧式的强制转换,例如:

intx; doubley=3.14; x=(int)y;//旧式的强制转换2.10数组定义和初始化数组要定义一个数组,就必须要告诉编译器,数组的数据类型和大小〔即数组中元素的个数〕,以便分配内存。数组的定义:<数据类型><数组名>[<元素个数>];举例如下:intage[4];表示定义了一个age数组,它包含4个元素,每个元素都是整型的,因此,age是一个整型数组。当计算机为数组分配内存的时候,数组元素在内存中的位置是相邻存放的,以下是数组元素在内存中位置的逻辑图示:age是数组的名字,它代表的是数组在内存中的起始地址。数组包含的元素是age[0]、age[1]、age[2]和age[3],用于存储4个人的年龄。0、1、2、3就是元素的下标。定义数组后,数组的每个元素就可以通过它的下标来访问了。请注意,数组的第一个元素的下标是0,最后一个元素的下标是数组的元素个数减一,而且,数组内所有的元素都必须具有同一样的数据类型。数组的初始化有两种方式:

a.数组在定义的时候同时初始化,如下所示:

intage[4]={12,23,29,33};b.在定义之后,一个一个地初始化数组元素,如下所示:

intage[4];age[0]=12;age[1]=23;age[2]=29;age[3]=33;数组age初始化后的逻辑图示为:字符串所谓“字符串”是指假设干有效字符的序列,它可以包括字母、数字、其他字符等等,例如,“IamVIC.”,字符串要用双引号括起来。但是,在程序设计中,字符串实在太重要了,C++语言的设计者给了它一种特殊的定义,字符串是一个以空操作终止符〔“\0”〕结束的字符数组。字符串的定义和初始化也有两种方式:a.最常用的方式就是在初始化时直接赋值,如下:charstr[]=“hello”;b.在定义之后,一个一个地初始化数组元素,如下所示:charstr[6];str[0]=‘h’;str[1]=‘e’;str[2]=‘l’;str[3]=‘l’;str[4]=‘o’;str[5]=‘\0’;注意不要忘记在字符数组结束处加上空操作终止符“\0”。该数组位置逻辑图示如下:举例,定义两个字符串数组,分别用于保存某个学生的姓名和选修的课程名称。#include<iostream.h>voidmain(){ charname[15];//定义了一个字符串数组,大小为15,用于

//保存学生名;

charcourse[30];//定义了一个字符串数组,大小为30,用于

//保存课程名;

cout<<"Enteryourname,please:\t";

cin>>name;

cout<<"Enterthecoursethatyouselect,please:\t";

cin>>course;

cout<<endl<<"Yournameis:"<<name;

cout<<endl<<"Thecoursethatyouselectis:"<<course<<endl;}虽然字符数组很好用,但它有一定的限制,我们迫切需要有一种对象能代替我们完成这些细节。标准的C++库中的string类就是设计用来处理〔并隐藏〕对字符数组的低级操作的,为了使用string类,我们需要包含C++头文件string.h。string类提供了许多函数用来对字符串进行查找、连接等操作,以便我们使用。1.串长度intstrlen(char*s);返回字符串的长度;2.串拷贝char*strcpy(char*s1,char*s2);把字符串s2拷贝到字符串s1中;3.串连接char*strcat(char*s1,char*s2);把字符串s2连接到字符串s1后面;4.串比较intstrcmp(char*s1,char*s2);如果字符串s1等于字符串s2,那么返回的值为0;5.串定位char*strchr(char*s,intc);在字符串s中定位,并返回定位后的内容。案例:用数组来表示“航空货物托运费用计算程序”中的收费标准提出问题:在第3章中,编写出的“航空货物托运费用计算程序”还不够完善。因为它只能保存一个旅客的信息;在一个旅客中,它只能保存旅客的代号,没方法保存旅客完整的名字。分析问题:为了简化问题,我们假设一天里,需要托运货物的旅客不超过10个人,为了保存每一个旅客的信息,每个变量我们都要定义十个元素的数组,下标为0的数组元素保存第一个旅客的信息、下标为1的数组元素保存第二个旅客的信息,依次类推。charowner[10];floatweight[10];floatcharge[10];因为旅客的名字不可能只有一个字符,所以必须每个旅客都定义一个大小为15的字符串数组,用于保存旅客的名字,所以要用到二维数组,如下:

charowner[10][15];为了简化计费判断,以及方便以后的扩展,我们用两个数组,分别保存重量分段列表、收费分段列表,如下:floatweightRange[MAXITEM]={15.0,25.0,45.0,80.0,500.0};//重量分段列表floatchargeRange[MAXITEM]={0.0,12.0,15.0,20.0,30.0};//收费分段列表floatcalculate(floatweight)//单个旅客的计费过程;{inti; floattw=weight; floatc=0.0; floatrc=0.0; floatpw=0.0; for(i=0;i<MAXITEM;i++) { if(tw>(weightRange[i]-pw)) { rc=rc+(weightRange[i]-pw)*chargeRange[i]; tw=weight-weightRange[i]; pw=weightRange[i]; } else { rc=rc+tw*chargeRange[i]; c=rc; returnc; } } c=rc+tw*chargeRange[MAXITEM-1]; returnc;}解决问题:见教材单元练习1.理解“冒泡排序”算法的思路;2.理解“斐波纳契数列(Fibonacci)”算法的思路;2.11指针计算机内存及内存地址的根本概念定义变量,其本质就是要求计算机,根据我们定义的变量的类型,在计算机的现有空闲内存中分配指定数目的空间,并把这些得到的空间分别命名为我们给定的变量的名字,以此方便我们对这些内存的访问〔读写〕。现在,假设在程序中定义了一个变量:intcount;计算机就会在空闲内存中为变量count分配4个字节的空间,如下图:所谓指针变量就是一个存放计算机内存的地址、或者存放任何其他变量的地址的变量。假设在程序中定义了一个变量:

intcount;然后,定义一个指针变量:

int*p;让指针变量p中存放count变量的地址,可用下面的语句:

p=&count;定义及使用指针变量(1)指针变量的定义定义指针变量的一般形式是:数据类型*指针变量名;数据类型:可以是任何合法的数据类型,包括C++中根本的数据类型以及第5章要学到的类,但必须要与指针变量所指向的变量的数据类型一致;*:定义一个指针变量必须用符号“*”,它说明其后的变量是指针变量;指针变量名:可以是任何合法的C++变量名;例如如下:int*p;这表示定义了一个指针变量p,它指向一个整型变量。换句话说,p当中存放一个整型变量的地址。事件模型(2)指针变量的操作指针变量有三个根本的操作符号:“*”、“&”及“->”:*:指针运算符,“*”与指针变量配合使用,表示要访问这个指针所指向的内存的内容,内存中的数据的形式由定义该指针变量时所指明的“数据类型”来确定;&:取址运算符,“&”与一个变量配合使用,表示取出这个变量在内存中所占用的内存空间的首地址;->:C++的“->”运算符来访问类指针的成员。注意:在使用一个指针变量以前,必须首先对指针变量进行初始化,即让指针变量指向一个合法的内存地址。同时,C++编译器无法检测出指针的操作是否越界。(3)指针变量的初始化对指针变量的初始化,有如下两种方式:第一种是直接地址赋值,如下:intcount=0;int*p;p=&count;当对指针p进行初始化后“p=&count;”,指针p就跟变量count联系在一起了,p保存变量count的地址,形象地说,就是p指向变量count,以后对*p的操作实际就是对变量count的操作。另一种初始化指针变量的方式是“动态申请内存”,采用C++的new运算符来动态申请空间,如下:new运算符的语法是:<指针变量名>=new<数据类型>;或者<指针变量名>=new<数据类型>[<元素个数>];指针变量名:任何合法的指针变量名;数据类型:任何合法的C++根本类型或自己定义的类;元素个数:可以使用new运算符一次申请多个指定数据类型的空间;举例如下:intmax;cout<<”Enterthetotalnumberofpassengerintoday:”;cin>>max;float*weight;weight=newfloat[max];这样,不管是旅游淡季还是旅游旺季,每天记录的旅客数都可以根据实际的情况来预定,防止了不够用或内存浪费的情况。采用C++的delete运算符释放内存:delete运算符的语法是:delete<指针变量>;//释放单个指针变量的内存;delete[]<指针变量>;//释放指针数组的内存;指针变量:就是在使用new运算符动态申请的内存空间时的指针变量例如:deletep;//使用delete运算符释放单个指针变量的内存delete[]weight;//使用delete运算符释放指针数组的内存(4)指针与数组的关系

在前面已经学习过数组,其实,一个数组名就代表了它的起始地址。我们除了可以采用数组下标的方式来访问这些单元,同样可以使用指针来访问这些内存单元。如下例所示:charary[]="hello";char*p;p=ary;数组名ary其实就是一个指针,指针p同样指向数组ary的起始地址。可以用数组的下标来取得数组的值,如ary[0]、ary[1]等;同样,也可以用*p、*〔p+1〕来取得数组的值。甚至,可以省略中介指针p,直接用数组名*ary、*〔ary+1〕来取得数组的值。为了引用一个数组元素,可以使用如下的两种方法,两者输出的结果是一样的:ary[i]——下标法;*〔ary+i〕——地址法;例如: cout<<ary[i]; cout<<*(p+i); cout<<*(ary+i);使用指针的引用调用voidswap(int*ptr1,int*ptr2)//使用指针的引用调用;{ inttemp; cout<<*ptr1<<""<<*ptr2<<endl;//交互两个变量的值; temp=*ptr1; *ptr1=*ptr2; *ptr2=temp; cout<<*ptr1<<""<<*ptr2<<endl;;}voidmain(){ intnumber1=10,number2=20; cout<<number1<<""<<number2<<endl; voidswap(int*,int*);//函数声明;swap(&number1,&number2);//函数调用; cout<<number1<<""<<number2<<endl;}单元练习:1.设intx[]={1,3,5,7,9,11,13},*p=x;那么以下不能正确引用数组元素的表达式是:A.*〔p--〕B.*(--p)C.*(p++)D.*(++p)2.执行语句“chara[10]={“abcd”},*p=a;”后,*(p+4)的值是:A.“abcd”B.‘d’C.‘\0’D.不能确定2.12.1类和对象现实世界的复杂性软件系统的复杂性是不可能摆脱的,怎么样来简化软件系统的复杂性呢?利用面向对象方法,先把系统分解为假设干个组成对象,它们彼此交互,最后用这些对象“装配出”整个系统软件。打个比方,一个大集团的运作是相当复杂的,但是如果将它分解为各个部门,各个层次,它们之间互相联系,各自负责相应的工作,那么整个集团的运作就会变得一目了然了。世界是由对象构成的有机体在物理实体中,我们把对象定义为:“可以看得见,摸得着的实体。”同理,“人为的概念,或者是任何有明确边界与意义的东西,也是对象”。它们都有着同一的特征:拥有状态和行为。状态是对象的一个或多个属性的描述。行为是对象为了改变自身的状态而发生的作用和反作用。简单来说,在软件中,对象就是一组变量和相关方法的集合,其中变量说明对象的状态,方法说明对象所具有的行为,即我们所学过的函数。当然,我们可以将现实世界中的对象经过抽象,映射为软件中的对象。对象在软件中是通过一种抽象数据类型来描述的,这种抽象数据类型称为类〔Class〕;用更严谨的话来表述,“对象是封装了数据结构及可以施加在这些数据结构中的操作的封装体,这个封装体有可以唯一地标识它的名字,而且向外界提供一组效劳〔即操作〕。”概括地说,面相对象方法具有下述四个要点:①

认为客观世界是由各种对象组成的,任何事物都是对象,复杂的对象可以由比较简单的对象以某种方式组合而成;②

把所有对象都划分成各种对象类〔简称为类,Class〕,每个对象类都定义了一组数据和一组方法;③

按照子类与父类的关系,把假设干个对象类组成一个层次结构的系统;④对象彼此之间仅能通过传递消息互相联系;2.12.2抽象、封装与类什么是抽象、封装由于不能应付对象的复杂性,人们就选择了这样的方法:抛弃非本质的细节,集中于我们最关心的材料。“抽象是指区别于所有其它种类对象的‘对象的本质特征’,因此,相对于观察者来看,它提供了清晰的、有定义的概念边界。”用相关的方法把变量包围起来与外界隔离,称为封装。封装后的对象外界不能直接访问其内部数据,各对象间必须通过消息来通信。换一句话来说,封装实际上就是使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。什么是类“类”就是对具有相同数据和相同操作的一组相似对象的定义,也就是说,类是对具有相同特性和行为的一个或多个对象的描述。有了类这个概念之后,我们就可以实现面向对象编程4个关键的组成局部:抽象、继承、封装和多态了。举例:classCar软件中的类{intcolor;intnumber;变量intspeed;

voidbrake(){…}voidspeedUp(){…}方法voidslowDown(){…}}什么是对象与类对应的就是实例,实例就是由某个特定的类所描述的一个具体的对象。打个比方,我们所说的“人类”,它是一个概念,是对人的一个定义,人类里有一个具体的人,他的名字叫“张三”,“张三”就是一个具体的对象了,他是实实在在的存在着的。那么,“人类”就好比类,“张三”就好比实例了。“对象是类的实例,类是有公共特性的对象的抽象。”比方:GarbageTruckg;g.brake();g.LoadGarbage();一个类可以定义出无数个对象,各个对象之间相互独立,互不影响。用C++描述、识别类用C++识别类:① 用英语写出需求的陈述;② 用把名词标识出来;〔名词代表了一个实体〕选择有用的名词作为类名;决定要将哪些有用的名词作为类。2.12.3面向对象的C++程序的典型结构第一个面向对象的C++程序一个典型的C++程序一般由以下几局部组成:头文件、类〔类中包含数据成员、成员函数〕和main()函数。例:#include<iostream.h>//头文件classCar//类{public://访问限定符 voidback()//成员函数{ cout<<"Danger,backingacar!";}};intmain()//主函数{Carc1;//创立对象c1.back();return0;}〔1〕头文件文件包含命令:#include<头文件>,放在C++程序的开头。〔2〕类类是对具有相同特性和行为的一个或多个对象的描述。①类的定义类定义包含两局部:类头〔classhead〕、类体〔classbody〕,类定义后面必须接一个分号。②数据成员类数据成员的声明方式跟变量声明相同,如:③成员函数C++中,对象的函数被称为成员函数,如:④创立对象类是对具有相同特性和行为的一个或多个对象的描述,类的定义〔如类Car〕不会引起内存分配,只有当创立了一个类的对象时,系统才会分配内存。对象是类的实例,是具体存在着的。例如:classCar{……};intmain(){Carc1,c2;//创立了c1,c2两个对象}只有创立了类Car的对象时,才分配一块足够包含Car类的数据成员的存储区,名字c1引用到这块存储区。每个类对象都有自己的类数据成员的拷贝,修改c1的数据成员不会改变任何其他Car对象的数据成员,例如不会修改c2。创立了类的对象之后,就可以用成员访问操作符来访问类对象的数据成员或成员函数了,成员访问操作符——点“.”或箭头“->”,例如:Carc1;c1.number=888;c1.back();〔3〕main〔〕函数对于每个C++程序,都必须定义一个称作main()的函数,它是C++程序开始执行时第一个调用的函数。当main()函数执行完毕〔也就是整个程序执行完毕〕时,它需要通知操作系统它已经执行完毕了。return0;意味着程序执行完毕且没有错误。如果返回给操作系统的是任何非0的数,这意味着程序执行时出现了某种错误。作用域分解运算符为了能够很快地了解一个类中具体包括哪些属性和方法,使我们编写的C++程序有更好的可读性,C++允许将类中的方法的具体实现放置在类定义的外面;为了做到这一点,必须使用C++中提供的作用域分解运算符“::”来定义这些方法。classCargo{public:floatweight;//成员函数的原型说明,决不可以省略;

voidinit();};//利用作用域分解符将类的成员函数放在类定义之外;voidCargo::init(){ weight=0.0;}关于类的this指针当类的函数的形参与这个类的数据成员同名时,在C++中,用this关键字指向于当前正在执行的类对象,采用this关键字来告诉C++编译器到底要访问哪个变量。例如:classCargo{public:floatweight;//成员函数的原型说明,决不可以省略;

voidinit();};voidCargo::init(floatweight,floatcharge){ this->weight=weight; this->charge=charge;}单元练习:定义一个类Video,它表示录像带租赁店中的录像带。试考虑在录像带租赁管理程序中,为使录像带类运行良好,必须设计的属性和方法,请包含一个能显示录像带信息的print〔〕成员函数。2.12.4访问限定符public访问限定符公有成员〔publicmember〕在程序的任何地方都可以被访问。举例如下:classSerApp{public: charname[30];//公有成员};intmain(){SerAppc;cin>>;//访问namereturn0;}private访问限定符私有成员〔privatemember〕只能被该类的成员函数和类的友元访问〔友元将在后面讲述〕,不能被其他类对象或函数访问〔子类也不行〕。这样就实现了信息隐藏,信息隐藏可以使数据不受外部变动的影响。举例如下:classSerApp{private://私有成员 floatimprest;voidwarning() { cout<<"BEEP!Ifyouisnotthepeopleonmyownside,youcanseethisnew!"; }public://公有成员 voidaccept() {cin>>imprest; }};intmain(){SerAppc;c.accept();}错误代码:cin>>c.imprest;或c.warning();//提示出错:error:cannotaccessprivatememberprotected访问限定符被保护成员〔protectedmember〕对派生类〔子类〕就像public成员一样,对其他程序那么表现得像private成员一样。protected访问限定符有意义的用法是在实现继承时用到。三种访问限定符的类成员的可见性:单元练习:创立一个类,具有public、private和protected数据成员和成员函数。在main()函数中,创立该类的一个对象,看看当试图存取所有的类成员时会得到一些什么编译信息。2.12.5静态变量和静态函数选述静态变量在类体中的变量声明前面加上关键字static,就使该变量成为静态的。对于非静态变量,每个类对象都有自己的拷贝;而静态变量对每个类只有一个拷贝,静态变量可被该类的所有对象共享访问。还有,静态变量即使在它所属于的函数执行完后还是保存他们的值,这意味着:静态变量在整个程序内一直保存着它的值。静态变量必须在其类体内声明,但不能在类体内初始化,只能在成员函数或类定义之外〔类体外〕被初始化。静态变量的声明和初始化,举例:classSExample{public:staticintsvar;//静态变量声明……}intSExample::svar=0;//静态变量初始化①在类的成员函数中可以直接访问该类的静态变量而不必使用成员访问操作符:SExample::cout(){svar=svar+1;cout<<”Now,Thetotalis:”<<svar;}②但是,在非成员函数中我们必须以以下两种方式之一访问静态变量:a.可以使用成员访问操作符:intSExample::svar=0;intmain(){SExamples1;s1.svar=1;}b.因为类静态变量只有一个拷贝,所以不一定要通过对象或指针来访问,访问静态变量的另一种方法是用被类名限定修饰的名字直接访问它:intSExample::svar=0;intmain(){SExample::svar=1;}当不通过类的成员访问操作符访问静态变量时,必须指定类名以及紧跟其后的域操作符“::”。静态函数静态函数的声明就是在类体中的函数声明前加上关键字static。因为静态成员在对象创立之前就已经存在了,所以,静态函数只能访问静态变量,不能够访问非静态变量。静态函数声明举例:classSExample{public: staticintsvar;staticvoiddisplay()//静态函数声明 { cout<<"Thestaticvariableis:"<<svar; }};intSExample::svar=0;与静态变量同理,也有两种方式访问静态函数。a.可以用成员访问操作符——点“.”和箭头“->”,为一个类对象或指向类对象的指针调用静态函数。b.也可以用类限定修饰名直接访问或调用静态函数,而无需声明类对象。举例:

SExample::display();//访问方式a

SExamples; s.display();//访问方式b案例提出问题:改善我们的“航空货物托运费用计算程序”,航空公司能根据旅客的数量随意增加输入的信息,并能随时显示当前的旅客数量。而且,分段收费要留有接口,以便以后增加更多、更细的收费标准。分析问题:使用静态变量存储当前旅客数量使用静态变量存储分段收费标准使用静态函数显示当前的旅客数量编写代码编译程序检验程序执行解决问题:见书本单元练习:创立一个类Monitor,它能知道它的成员函数incident〔〕被调用了多少次,增加一个成员函数print〔〕显示incident〔〕被调用的次数。2.12.6友元函数和友元类选述友元函数在某些情况下,允许某个特殊函数而不是整个程序可以访问类的私有成员,这样做会比较方便。于是,友元〔friend〕机制允许一个类授权其他的函数访问它的非公有成员。友元函数的声明以关键字friend开头,它只能出现在类的声明中,它不受类体中声明的public、private和protected区的影响。任何非成员函数都可以由类声明为friend〔友元函数〕,那么,该函数就可以直接访问此类对象的非public成员了。例如:classFExample{friendvoidcall1();//说明“call1()函数是朋友,它可以用x了”;

private:

intx;}voidcall1(){

FExamplef;f.x=0;//运行通过,因为声明了友元函数call1();}voidcall2(){

FExamplef;f.x=0;//错误,因为call2()函数并没有被声明为友元函数;}友元类在使一个类成为友元时,友元类的所有成员函数都被给予了访问“授权友谊的类的非公有成员”的权力。举例如下:classFExample{friendclassFClass1;//说明“FClass1类是朋友,它可以用x了”;

private:

intx;};classFClass1{public://“FClass1类是FExample类的朋友”,

voidcall()//FClass1类的所有成员函数都可以访问FExample类的非公有成员;

{

FExamplef;

cin>>f.x;//声明了友元类,可以访问私有成员x }};单元练习:创立三个类,第一个类包含private数据,并且第二个类和第三个类所有的成员函数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论