第一讲 C与C++概述_第1页
第一讲 C与C++概述_第2页
第一讲 C与C++概述_第3页
第一讲 C与C++概述_第4页
第一讲 C与C++概述_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

面向对象程序设计C++语言基础

Tel:627684261/5/20231

60年代产生的结构化程序设计思想为使用面向过程的方法解决复杂的问题提供了有力的手段。其基本思路是:

自顶向下,逐步求精;程序结构按功能划分为若干个模块,这些模块形成一个树状结构;各模块之间关系尽可能简单,在功能上相对独立;每一模块内部均有顺序、选择和循环三种基本结构组成;其模块实现的具体工具是使用子程序。

第一讲C与C++概述程序子程序1子程序2子程序3子程序4§1.1面向过程(结构化)的程序设计方法1/5/20232程序按功能模块划分为若干基本模块(子过程),每个子过程具有一定的功能,这些过程通过参数传递数据。数据和过程是分离为相对独立的实体。如下图:结构化方法过程1过程2过程3数据1数据2数据3数据41/5/20233

结构化程序设计方法是面向过程程序设计的思想工具。它把数据和数据的处理过程分离,当数据结构改变时,所有相关的处理过程都要进行相应的修改。另外,一个好的软件应随时响应用户的任何操作,而不是请用户按照既定的步骤使用软件。

面向过程的程序设计认为,每一个程序都完成一些特定的功能。每一功能的实现是通过对数据进行一系列的加工而实现的。因而程序设计包括组织数据---设计数据结构,以及设计对数据结构进行加工的过程---设计算法两个部分。即:

程序=数据结构+算法1/5/20234结构化程序设计:总体结构——层次树状;局部组织——模块化。程序——处理数据的一系列过程;数据,过程分开存储;

“分而治之”。缺点:数据和任务分离,难理解、维护;重用性差;1/5/20235

面向对象的程序设计把世界看作是由若干对象组成的,对象是运动的,向对象发送消息,将激活对象的行为,或者说对象行为靠消息触发而激活,对象之间通过消息进行联系。

每一个对象都具有静态成员(数据)和动态成员(操作或方法)。面向对象方法强调的是结构模拟和对象化,程序是一组能相互进行通讯的对象的集合,对象之间通过消息传递进行通讯。对象将数据和操作封装在一起,对一个对象的存取或修改仅能通过其公共的接口,其内部实现细节、数据结构以及操作是不可见的。即面向对象的程序设计是以数据为中心的开发方法。§1.2面向对象的程序设计方法1/5/20236面向对象的方法数据方法对象1数据方法对象2数据方法对象3请求请求请求1/5/20237类:一种用户自定义类型,由数据成员,函数成员,常量成员,类型成员组成。是对一类具有相同属性和方法的客观对象的抽象。对象是类的实例.例:将各种各样的自行车抽象成一个自行车类,描述如下:自行车类

属性:

架子尺寸车轮尺寸颜色原材料

操作:

转弯移动修理§1.3面向对象的基本概念1/5/20238对象:就是指某个具体的事物。例如一个人、一本书、一所学校对象具有以下特性:有一个名字以区别于其他的对象;有一个状态来描述他的某些特征;有一组操作,每一个操作决定对象的一种功能或行为;对象的操作分为两类:一类是自身所承受的操作,一类是施加于其它对象的操作。有两重含义:是内存中含有某种数据类型值的邻近区域。是某种数据类型的已命名的或未命名的变量。一个拥有构造函数的类型对象在构造函数完成构造之前不能认为是一个对象,在析构函数完成析构以后也不再认为它是一个对象。1/5/20239

例如有一个学生名叫李浩,身高1.80m,体重68kg,可以修电脑,可以教计算机课,下面我们来描述这个对象:对象名:李浩对象的状态:

性别:男身高:1.80m体重:68kg对象的功能(可做的操作):

回答身高回答体重修理电脑教计算机课均属于自身所承受的操作属于施加于其它对象的操作1/5/202310抽象类:至少包含一个纯虚函数的类。抽象类不能创建对象,但可以创建指向抽象类的指针,多态机制将根据基类指针选择相应的虚函数。嵌套类:在一个类里可以定义另一个类,被嵌入类只在定义它的类的作用域里有效。局部类:在函数中定义的类。注意在函数外这个局部类是不可知的。由于局部类的说明有很多限制,所以并不常见。基类—父类:被继承的类称为基类,又称父类、超类或范化类。它是一些共有特性的集合,可以有其它类继承它,这些类只增加它们独有的特性。派生类—子类:继承的类称为派生类。派生类可以用来作为另一个派生类的基类,实现多重继承。一个派生类也可以有两个或两个以上的基类。定义时在类名后加":被继承类名"即可。1/5/202311数据成员:指类中存储数据的变量。实例化:即建立类的一个对象。构造函数:是一个类的实例的初始化函数,将在生成类的实例时被自动调用,用于完成预先的初始化工作。一个类可以有几个构造函数,以不同的参数来区别,即构造函数可以被重载,以便不同的情况下产生不同的初始化;也可以没有构造函数,此时系统将调用缺省的空构造函数。需要注意的是构造函数没有返回类型。成员初始化表:成员初始化表可用于初始化类中的任何数据成员,放在构造函数头与构造函数体之间,用":"与构造函数头分开,被初始化的数据成员的值出现在一对括弧之间,它们之间用逗号分开。1/5/202312析构函数:是一个类的实例的回收函数,将在该实例结束使用前被自动调用,用于完成资源的释放。一个类只可以有一个析构函数,当析构函数执行后,该实例将不复存在。析构函数同样没有返回值。虚析构函数:由virtual修饰的析构函数,当用基类指针释放派生类对象时可根据它所指向的派生类对象释放准确的对象。继承:面向对象的程序设计语言的特点之一。即一个对象获得另一个对象的特性的过程。如将公共属性和服务放到基类中,而它的各派生类除了有各自的特有属性和服务外还可以共享基类的公共属性和服务。这样的好处是容易建立体系,增强代码重复性。单继承:一个派生类只有一个基类,成为单继承。重继承:一个派生类拥有多个基类,成为多继承。1/5/202313虚函数:在基类中说明为virtual并在派生类中重定义的函数。重定义将忽略基类中的函数定义,指明了函数执行的实际操作。当一个基类指针指向包含虚函数的派生对象时,C++将根据指针指向的对象类型来决定调用哪一个函数,实现了运行时的多态性。这里的重定义类似于函数重载,不同的是重定义的虚函数的原型必须和基类中指定的函数原型完全匹配。构造函数不能是虚函数,而析构函数则可以是。纯虚函数:在基类中只有声明没有实现的虚函数。形式为:

virtualtypefunname(paralist)=0。这时基函数只提供派生类使用的接口,任何类要使用必须给出自己的定义。多态性:给不同类型的实体提供单一接口。虚函数通过基类接口实现动态多态性,重载函数和模板提供了静态多态性。友元类:被某类明确授权可访问其成员的类1/5/202314复制构造函数:以自身类对象为参数的构造函数,如Z::Z(constZ&)用在同类对象间进行初始化。运算符重载:C++中可以重载双目(如+,×等)和单目(如++)操作符,这样可以使用户像使用基本数据类型那样对自定义类型(类)的变量进行操作,增强了程序的可读性。当一个运算符被重载后,它将具有和某个类相关的含义,同时仍将保持原有含义。静态成员函数:成员函数通过前面加static说明为静态的,但是静态成员函数只能存取类的其他静态成员,而且没有this指针。静态成员函数可以用来在创建对象前预初始化专有的静态数据。1/5/202315静态成员变量:在成员变量之前加static关键字将使该变量称为静态成员变量,该类所有的对象将共享这个变量的同一拷贝。当对象创建时,所有静态变量只能被初始化为0。使用静态成员变量可以取代全局变量,因为全局变量是违背面向对象的程序设计的封装性的。私有成员:只能由自身类访问的成员。保护成员:只能由自身类及其派生类访问的成员。友元:被某类明确授权可访问其成员的函数和类。友元函数:在函数前加上关键字friend即说明了一个友元函数,友元函数可以存取类的所有私有和保护成员。友元在重载运算符时有时是很有用的。1/5/202316纯面向对象的:smalltalk、eiffel混合型面向对象的:c++、objectc、loops等.§1.4面向对象的程序设计语言1/5/202317§1.5C++程序的结构C++应用程序的结构简单的C++程序C++源程序的执行1/5/202318

◆C++应用程序的结构老师类学生类张三李四王萍赵英类何老师实例对象C++程序是一组相互通信的对象main主控对象C++应用程序设计:1.定义应用需要的类;2.定义主控对象,完成对象间的通信;1/5/202319

◆简单的C++程序

#include<iostream.h>voidmain(){cout<<“Hello,World\n”;}一般:公用数据和函数说明放在头文件(.h)中;实现函数功能的函数体和局部数据放在源文件(.cpp)中;

程序是由一行行符号序列表达的,空格将符号序列分为六类:

关键字:include,int,const等说明语句、数据的性质;

标识符:cin,cout,a,b等代表运算对象;

运算符:<<,+,==等表示指定运算;

常量:2.45等,不用说明,是有类型的操作数;

串:“HelloWorld”等用双引号括起来的字符序列;

特殊符号:{,},//,#,(,)等1/5/202320

◆C++程序的执行C++源程序C++预处理器预处理后的源程序C++编译程序目标程序链接程序可执行程序其它目标程序和库1/5/202321§1.6数据和运算标识符基本对象和基本类型常量导出类型运算符1/5/202322◆标识符有一定含义的名字表示数据、类型;一系列字母、数字、下划线组成,首字符必须字母或下划线;不能是关键字;大小写有区别;下列是不合法的:break,3var,afool,.name,……

"a"和'a'的差别?

◆变量和常量的区别:变量——存储单元、运行过程中可改变;常量除串外,不占存储单元,也不能改变

◆基本对象和基本类型1/5/202323

◆导出类型(构造类型、自定义类型)类型的作用:确定分配空间的大小和所能进行的操作修饰符:signed,unsigned,long,short,const

const型变量不能改变其值(一直为初值)导出数据类型数组type[]指针type*结构struct联合union枚举enum占用空间操作复杂性1/5/202324

charc1='a';运算符&和*的作用?char*p=&c1;charc2=*p;

1指针

T*变量——存放T类型对象的地址

voidmain(){inti;int*p;*p=i;//???

}错;应改为:*p=&i1/5/202325a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]2引用一个变量说明为另一变量的引用,则成为对应变量的别名。必须初始化,且初始化它的变量必须是已声明过类型的变量。两者为同一存储单元。

intcount=0;

int&refCount=count;refCount=1;count+=count;

3数组

T[size]:下标0〜size-1inta[2][3]:inta[][3]={{2,4,6},{8,10,12}};charname[7];name="string";//???数组名被作为常量不能赋值1/5/202326◆运算符

ex1.a+=1;//含义?x,n=20;x=++n;//x的值?x=n++;//x的值?在关系运算中,当指定关系成立时,关系表达式的值为1,否则为0。ex3.z=(a>b)?a:b;//含义?C:#include<stdio.h>f(char*a,floatb){printf("a:%s,b:%f\n",a,b);}main(){f("12.3",12.3);}C++:#include<iostream.h>

voidf(char*a,floatb){cout<<"a:"<<a<<","<<"b:"<<b<<endl;}

voidmain(){f("12.3",12.3);

}

4无值与函数

C++与C不同之处是声明使用原型,以保证实参和形参类型一致(编译器检查)1/5/202327

ex5.Char*pChar;pChar=newchar;char*string=newchar[25];//…

deletepChar;

delete[]string;★new和delete运算符和C中的malloc和free函数的区别:new运算符根据对象的类型,自动决定其大小,而malloc要指定分配存储空间的大小;new返回指向此类型的指针,malloc返回指向void*类型的指针。

★每种运算符只能用于特定的对象:i;

*i=10;//???

ex7.12.3%3//???12.3<<2//???

★::是作用域分辨符,用它可以访问隐藏的全局变量。(例见作用域)1/5/202328

◆程序的结构整个程序.C文件1.C文件n函数1函数k函数1函数l全局变量局部变量静态变量工程文件(.dsw,.prj):告诉编译器程序由哪些.cpp文件装成;连上哪些.obj文件;要连的标准库.lib1/5/202329

◆程序运行时的内存占用栈区(stackarea)堆区(heaparea)数据区(dataarea)代码区(codearea)存放程序的代码部分存放程序的全局数据和静态数据存放程序动态申请的数据存放程序的局部数据和参数1/5/202330#include<stdio.h>intm=80;voidF1(intw){staticintn=70;intk=60;//1m++;n++;k++;w++;//2printf("F1()---m:%dn:%dk:%dw:%d\n",m,n,k,w);}voidF2(){intm=90;m++;//4F1(m);printf("F2()---m:%d\n",m);}voidmain(){intw=20;F1(w);//3printf("下面调用F2()\n");F2();}k60w20w20未用m80F1的n70main、F1、F2代码数据区代码区栈区堆区栈顶F1maink61w21w20未用m81F1的n71main、F1、F2代码数据区代码区栈区堆区栈顶F1maink61w21w20未用m81F1的n71main、F1、F2代码数据区代码区栈区堆区main栈顶k61m91w20未用m81F1的n71main、F1、F2代码数据区代码区栈区堆区main栈顶F2k61w91m91w20未用m81F1的n71main、F1、F2代码数据区代码区栈区堆区main栈顶F2F11/5/202331§1.7

流程控制、函数和文件

1.流程控制语句(顺序、条件、循环)

◆条件语句(if-else;switch)

注意:条件表达式的值为非零表示“真”;值为零则表示“假”。C++无布尔类型;

ex1.switch(val){case1:cout<<"case1"<<endl;case2:cout<<"case2"<<endl;default:cout<<"casenotfound"<<endl;}//若val为1,输出结果?

◆循环语句(while;for;do…while)

for(表达式1;表达式2;表达式3)语句表达式1;While(表达式2){语句;表达式3;}1/5/202332C++函数作用:1、大任务化小时,表示小任务;2、定义方法。文件是编译的独立单位2.函数和文件◆作用域标识符的作用域有:块、函数、文件、全局

4种在块和函数内声明的变量——作用域是块和函数;在函数外声明的静态全局变量——作用域是定义它的文件;全局名的作用域——整个程序。

x;voidf1(){intx;x=1;{intx;x=2;}x=3;}int*p=&x;

1/5/202333◆存储分类符外层作用域不能访问内层作用域,利用::运算符可访问当前作用域所隐藏的全局名。但不能访问隐藏的局部名。作用域总是始于说明点。x=11;voidf2(intz){intz;inty=x;intx=1;::x=2;y=x;}

★外部的:多个文件共享的变量,用extern通知编译器同名同类型变量引用同一存储区。ex4.////inta=1;externinta;//声明

intf()intf();//声明(将名字与类型联系起来){voidg()//…{a=f();}}1/5/202334★静态的:分配的存储空间直到整个程序结束才收回(全局变量特性);局部于某一作用域(局部变量特性)按作用范围可分:静态局部变量,局限于特定函数,但出作用域并不释放。

静态全局变量,局限于它的源文件。

ex5.#include<iostream.h>voidf();voidmain(){for(inti=0;i<=3;i++)f();//输出结果???

}voidf(){staticinta=0;cout<<a++<<endl;}

函数也可以声明为静态的,局部于它所在的文件。ex6.//staticvoidf(char){}//staticvoidf(char){}

//若去掉static???★寄存器的:用CPU中寄存器提高频繁使用量的速度。

★自动的:函数的局部变量,出函数自动消失,一般省去auto。1/5/202335◆函数参数传递ex7.#inlcude<iostream.h>voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}voidmain(){intx=10,y=20;swap(x,y);cout<<”x:”<<x<<“y:”<<y<<endl;//结果???}

ex8.#inlcude<iostream.h>#inlcude<iostream.h>voidswap(int*x,int*y)voidswap(int&x,int&y){{inttemp;inttemp;temp=*x;temp=x;*x=*y;x=y;*y=temp;y=temp;}}voidmain()voidmain()//结果???{{intx=10,y=20;intx=10,y=20;swap(&x,&y);swap(x,y);cout<<“x:”<<x<<“y:”<<y<<endl;cout<<“x:”<<x<<“y:”<<y<<endl;

}}参数传值是参数值的拷贝,而不是参数本身。函数要改变实参变量有两种方法:传指针调用和引用调用。当形参和实参结合时,复制的是变量的地址。1/5/202336◆函数参数与默认值voidf1(inta,intb=-1);调用形式:f1(1,2);f1(2);voidf2(inta,intb=-1,intc);//???

main()是编译器预定义的函数,C++有两种形式:intmain(){/*…*/}intmain(intargc,char*argv[]){/*…*/}argv[0]~argv[argc-1]存放运行环境参数。

ex9.#inlcude<iostream.h>intmain(intargc,char*argv[]){if(argc!=2){cout<<"youforgottypeparameter"<<endl;exit(1);}cout<<argv[1]<<endl;return0;}nameprother↙otherpr↙youforgottypeparameter编译后执行结果:prname↙1/5/202337◆内联、重载和引用

★宏和内联文件包含:#include<包含文件名>//包含文件内容取代该预处理语句?条件编译:#if条件

源程序部分1#else

源程序部分2#endif

在C++中常用const变量(常量)和内联函数来代替宏和带参宏:例如:constintYES=1;//这种定义有类型信息,更安全宏定义:#define字符序列1字符序列2//预编译时,用序列2替换序列1带参宏:例如,#definepower(x)((x)*(x))使用,x=4;y=6;z=power(x+y)宏名宏体#if条件源程序部分1#elif条件

源程序部分2#else

源程序部分3#endif编译时,根据条件决定取哪部分编译1/5/202338

inlinefac(inti){returni<2?1:n*fac(n-1);}

编译器在所有调用这个函数的地方将其实际的代码装上。内联函数要出现在每一调用它的源文件中,所以一般放在头文件中。内联函数调用,编译器做类型检查,保证不传入非法类型;宏的优点是传入什么类型,返回同一类型。文件1文件2文件m……inlinefac(inti)fac(inti)fac(inti).h文件文件1文件2文件m……fac(inti)fac(inti)fac(inti).h文件inlinefac(inti)1/5/202339★重载函数同一作用域内名字相同,但参数不同的函数称为重载函数。

C中求绝对值的函数:intiabs(intI);longlabs(longl);doublefabs(doubled);C++用同一个函数名abs()实现,用函数参数来区别到底调用哪个函数。这得益于函数原型不仅给出函数名,而且指出了参数类型。为了保证编译器根据参数类型识别重载函数,必须保证重载函数的参数不同。1、同名函数,仅返回值类型不同,但参数相同;2、两同名函数,仅用const或引用使参数类型有所不同;ex

温馨提示

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

评论

0/150

提交评论