首页 C 基础课程讲义

C 基础课程讲义

举报
开通vip

C 基础课程讲义1C++课程讲义1、C++对C的扩展1简单的C++程序1.1求圆的周长和面积数据描述:半径,周长,面积均用实型数表示数据处理:输入半径r;计算周长=2*π*r;计算面积=π*r2;输出半径,周长,面积;方法1:用结构化方法编程,求圆的周长和面积//countthegirthandareaofcircle#include<iostream.h>usingnamestd;voidmain(){doubler,girth,area;constdoublePI=3.1415;cout<<...

C  基础课程讲义
1C++课程讲义1、C++对C的扩展1简单的C++程序1.1求圆的周长和面积数据描述:半径,周长,面积均用实型数表示数据处理:输入半径r;计算周长=2*π*r;计算面积=π*r2;输出半径,周长,面积;方法1:用结构化方法编程,求圆的周长和面积//countthegirthandareaofcircle#include<iostream.h>usingnamestd;voidmain(){doubler,girth,area;constdoublePI=3.1415;cout<<"Pleaseinputradius:\n";//操作符重载cin>>r;//输入girth=2*PI*r;area=PI*r*r;cout<<"radius="<<r<<endl;cout<<"girth="<<girth<<endl;cout<<"area="<<area<<endl;}方法2:用面向对象方法编程,求圆的周长和面积2#include<iostream.h>usingnamestd;classCircle{doubleradius;//成员变量public://类的访问控制voidSet_Radius(doubler){radius=r;}//成员函数doubleGet_Radius(){returnradius;}//通过成员函数设置成员变量doubleGet_Girth(){return2*3.14f*radius;}//通过成员函数获取成员变量doubleGet_Area(){return3.14f*radius*radius;}};voidmain(){CircleA,B;//用类定义对象A.Set_Radius(6.23);//类的调用cout<<"A.Radius="<<A.Get_Radius()<<endl;3cout<<"A.Girth="<<A.Get_Girth()<<endl;cout<<"A.Area="<<A.Get_Area()<<endl;B.Set_Radius(10.5);cout<<"B.radius="<<B.Get_Radius()<<endl;cout<<"B.Girth="<<B.Get_Girth()<<endl;cout<<"B.Area="<<B.Get_Area()<<endl;} 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf :建立类、对象、成员变量、成员函数,输入输入流基本概念。1.2初学者易犯错误模型//demo02_circle_err.cpp#include<iostream>usingnamespacestd;//c++的命名空间classcircle{public:doubler;doublepi=3.1415926;doublearea=pi*r*r;};intmain(){circlepi;cout<<"请输入area"<<endl;cin>>pi.r;cout<<pi.area<<endl;//乱码system("pause");return0;}总结:从内存四区的角度,解释为什么会出现乱码理解为什么需要成员函数42程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 方法的发展历程面向过程的结构化程序设计方法设计思路–自顶向下、逐步求精。采用模块分解与功能抽象,自顶向下、分而治之。程序结构:–按功能划分为若干个基本模块,形成一个树状结构。–各模块间的关系尽可能简单,功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成。–其模块化实现的具体方法是使用子程序。优点:有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。缺点:可重用性差、数据安全性差、难以开发大型软件和图形界面的应用软件–把数据和处理数据的过程分离为相互独立的实体。–当数据结构改变时,所有相关的处理过程都要进行相应的修改。–每一种相对于老问题的新方法都要带来额外的开销。–图形用户界面的应用程序,很难用过程来描述和实现,开发和维护也都很困难。面向对象的方法将数据及对数据的操作方法封装在一起,作为一个相互依存、不可分离的整体——对象。对同类型对象抽象出其共性,形成类。类通过一个简单的外部接口,与外界发生关系。对象与对象之间通过消息进行通信。面向对象的基本概念对象一般意义上的对象:–是现实世界中一个实际存在的事物。–可以是有形的(比如一辆汽车),也可以是无形的(比如一项计划)。–是构成世界的一个独立单位,具有静态特征:可以用某种数据来描述动态特征:对象所表现的行为或具有的功能面向对象方法中的对象:–是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。对象由一组属性和一组行为构成。–属性:用来描述对象静态特征的数据项。–行为:用来描述对象动态特征的操作序列。类分类——人类通常的思维方法分类所依据的原则——抽象–忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出5事物的共性,把具有共同性质的事物划分为一类,得出一个抽象的概念。–例如,石头、树木、汽车、房屋等都是人们在长期的生产和生活实践中抽象出的概念。面向对象方法中的"类"–具有相同属性和服务的一组对象的集合–为属于该类的全部对象提供了抽象的描述,包括属性和行为两个主要部分。–类与对象的关系:犹如模具与铸件之间的关系,一个属于某类的对象称为该类的一个实例。封装也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。把对象的属性和服务结合成一个独立的系统单元。尽可能隐蔽对象的内部细节。对外形成一个边界(或者说一道屏障),只保留有限的对外接口使之与外部发生联系。继承对于软件复用有着重要意义,是面向对象技术能够提高软件开发效率的重要原因之一。定义:特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。例如:将轮船作为一个一般类,客轮便是一个特殊类。多态多态是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个特殊类中具有不同的语义。面向对象的软件工程面向对象的软件工程是面向对象方法在软件工程领域的全面应用。它包括:–面向对象的分析(OOA)–面向对象的设计(OOD)–面向对象的编程(OOP)–面向对象的测试(OOT)–面向对象的软件维护(OOSM)总结:面向过程程序设计:数据结构+算法主要解决科学计算问题,用户需求简单而固定特点:分析解决问题所需要的步骤利用函数实现各个步骤依次调用函数解决问题问题:软件可重用性差软件可维护性差构建的软件无法满足用户需求面向对象程序设计:由现实世界建立软件模型将现实世界中的事物直接映射到程序中,可直接满足用户需求6特点:直接分析用户需求中涉及的各个实体在代码中描述现实世界中的实体在代码中关联各个实体协同工作解决问题优势:构建的软件能够适应用户需求的不断变化直接利用面向过程方法的优势而避开其劣势3C语言和C++语言关系C语言是在实践的过程中逐步完善起来的没有深思熟虑的设计过程使用时存在很多“灰色地带”残留量过多低级语言的特征直接利用指针进行内存操作C语言的目标是高效最终程序执行效率的高效当面向过程方法论暴露越来越多的缺陷的时候,业界开始考虑在工程项目中引入面向对象的设计方法,而第一个需要解决的问题就是:高效的面向对象语言,并且能够兼容已经存在的代码。C语言+面向对象方法论===》ObjectiveC/C++C语言和C++并不是对立的竞争关系C++是C语言的加强,是一种更好的C语言C++是以C语言为基础的,并且完全兼容C语言的特性学习C++并不会影响原有的C语言知识,相反会根据加深对C的认知;学习C++可以接触到更多的软件设计方法,并带来更多的机会。1)C++是一种更强大的C,通过学习C++能够掌握更多的软件设计方法2)C++是Java/C#/D等现代开发语言的基础,学习C++后能够快速掌握这些语言3)C++是各大知名软件企业挑选人才的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 之一74C++对C的加强4.1namespace命名空间1C++命名空间基本常识所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。一:<iostream>和<iostream.h>格式不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。因此,1)当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;2)当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespacestd;这样才能正确使用cout。二:由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:std::cout<<std::hex<<3.4<<std::endl;2、使用using关键字。usingstd::cout;usingstd::endl;usingstd::cin;以上程序可以写成cout<<std::hex<<3.4<<endl;3、最方便的就是使用usingnamespacestd;例如:usingnamespacestd;这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句8可以如下写:cout<<hex<<3.4<<endl;因为标准库非常的庞大,所以程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"2C++命名空间定义及使用语法/*在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。*//*std是c++标准命名空间,c++标准程序库中的所有标识符都被定义在std中,比如标准库中的类iostream、vector等都定义在该命名空间中,使用时要加上using声明(usingnamespacestd)或using指示(如std::string、std::vector<int>).*//*C中的命名空间在C语言中只有一个全局作用域C语言中所有的全局标识符共享同一个作用域标识符之间可能发生冲突C++中提出了命名空间的概念命名空间将全局作用域分成不同的部分不同命名空间中的标识符可以同名而不会发生冲突命名空间可以相互嵌套全局作用域也叫默认命名空间*//*C++命名空间的定义:namespacename{…}*//*C++命名空间的使用:使用整个命名空间:usingnamespacename;使用命名空间中的变量:usingname::variable;9使用默认命名空间中的变量:::variable默认情况下可以直接使用默认命名空间中的所有标识符*/3C++命名空间编程实践namespaceNameSpaceA{inta=0;}namespaceNameSpaceB{inta=1;namespaceNameSpaceC{structTeacher{charname[10];intage;};}}intmain(){usingnamespaceNameSpaceA;usingNameSpaceB::NameSpaceC::Teacher;printf("a=%d\n",a);printf("a=%d\n",NameSpaceB::a);NameSpaceB::NameSpaceC::Teachert2Teachert1={"aaa",3};printf("t1.name=%s\n",t1.name);printf("t1.age=%d\n",t1.age);system("pause");return0;}104结论1)当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespacestd;这样才能正确使用cout。若不引入usingnamespacestd,需要这样做。std::cout。2)c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。3)C++命名空间的定义:namespacename{…}4)usingnamespaceNameSpaceA;5)namespce定义可嵌套。4.2“实用性”增加#include"iostream"usingnamespacestd;//C语言中的变量都必须在作用域开始的位置定义!!//C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。intmain11(){inti=0;printf("ddd");intk;system("pause");return0;}4.3register关键字增强//register关键字请求编译器让变量a直接放在寄存器里面,速度快//在c语言中register修饰的变量不能取地址,但是在c++里面做了内容/*//1register关键字的变化register关键字请求“编译器”将局部变量存储于寄存器中C语言中无法取得register变量地址在C++中依然支持register关键字C++编译器有自己的优化方式,不使用register也可能做优化C++中可以取得register变量的地址11//2C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。//3早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充。*/intmain22(){registerinta=0;printf("&a=%x\n",&a);system("pause");return0;}其他补充:请阅读《register关键字常识课外阅读.docx》4.4变量检测增强/*在C语言中,重复定义多个同名的全局变量是合法的在C++中,不允许定义多个同名的全局变量C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上intg_var;intg_var=1;C++直接拒绝这种二义性的做法。*/intmain(intargc,char*argv[]){printf("g_var=%d\n",g_var);return0;}4.5struct类型加强struct类型的加强:C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型C++中的struct是一个新类型的定义声明structStudent12{charname[100];intage;};intmain(intargc,char*argv[]){Students1={"wang",1};Students2={"wang2",2};return0;}4.6C++中所有的变量和函数都必须有类型/*C++中所有的变量和函数都必须有类型C语言中的默认类型在C++中是不合法的函数f的返回值是什么类型,参数又是什么类型?函数g可以接受多少个参数?*///更换成.cpp试试f(i){printf("i=%d\n",i);}g(){return5;}intmain(intargc,char*argv[]){f(10);printf("g()=%d\n",g(1,2,3,4,5));13getchar();return0;}总结:/*在C语言中intf();表示返回值为int,接受任意参数的函数intf(void);表示返回值为int的无参函数在C++中intf();和intf(void)具有相同的意义,都表示返回值为int的无参函数*/C++更加强调类型,任意的程序元素都必须显示指明类型4.2-4.6属于语法级别的增强。4.7新增Bool类型关键字/*C++中的布尔类型C++在C语言的基本类型系统之上增加了boolC++中的bool可取的值只有true和false理论上bool只占用一个字节,如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现true代表真值,编译器内部用1来表示false代表非真值,编译器内部用0来表示bool类型只有true(非0)和false(0)两个值C++编译器会在赋值时将非0值转换为true,0值转换为false*/intmain(intargc,char*argv[]){inta;boolb=true;printf("b=%d,sizeof(b)=%d\n",b,sizeof(b));b=4;a=b;printf("a=%d,b=%d\n",a,b);14b=-4;a=b;printf("a=%d,b=%d\n",a,b);a=10;b=a;printf("a=%d,b=%d\n",a,b);b=0;printf("b=%d\n",b);system("pause");return0;}4.8三目运算符功能增强1三目运算符在C和C++编译器的表现intmain(){inta=10;intb=20;//返回一个最小数并且给最小数赋值成3//三目运算符是一个表达式,表达式不可能做左值(a<b?a:b)=30;printf("a=%d,b=%d\n",a,b);system("pause");return0;}2结论1)C语言返回变量的值C++语言是返回变量本身C语言中的三目运算符返回的是变量值,不能作为左值使用C++中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方2)注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用15(a<b?1:b)=30;3)C语言如何支持类似C++的特性呢?====>当左值的条件:要有内存空间;C++编译器帮助程序员取了一个地址而已思考:如何让C中的三目运算法当左值呢?5C/C++中的const1const基础知识(用法、含义、好处)intmain(){constinta;intconstb;constint*c;int*constd;constint*conste;return0;}Intfunc1(const)初级理解:const是定义常量==》const意味着只读含义://第一个第二个意思一样代表一个常整形数//第三个c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)//第四个d常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)//第五个e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)Const好处//合理的利用const,//1指针做函数参数,可以有效的提高代码可读性,减少bug;//2清楚的分清参数的输入和输出特性intsetTeacher_err(constTeacher*p)Const修改形参的时候,在利用形参不能修改指针所向的内存空间2C中“冒牌货”intmain(){constinta=10;16int*p=(int*)&a;printf("a===>%d\n",a);*p=11;printf("a===>%d\n",a);printf("Hello......\n");return0;}解释:C++编译器对const常量的处理当碰见常量声明时,在符号表中放入常量=问题:那有如何解释取地址编译过程中若发现使用常量则直接以符号表中的值替换编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)?联想:int&a=1(err)&constint&a=10(ok)?C++中const符号表原理图注意:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。结论:C语言中的const变量C语言中const变量是只读变量,有自己的存储空间C++中的const常量可能分配存储空间,也可能不分配存储空间当const常量为全局,并且需要在其它文件中使用当使用&操作符取const常量的地址3const和#define相同之处//练习解释为什么//#defineN10intmain(){constinta=1;constintb=2;17intarray[a+b]={0};inti=0;for(i=0;i<(a+b);i++){printf("array[%d]=%d\n",i,array[i]);}getchar();return0;}C++中的const修饰的,是一个真正的常量,而不是C中变量(只读)。在const修饰的常量编译期间,就已经确定下来了。4const和#define的区别对比加深C++中的const常量类似于宏定义constintc=5;≈#definec5C++中的const常量与宏定义不同const常量是由编译器处理的,提供类型检查和作用域检查宏定义由预处理器处理,单纯的文本替换//在func1定义a,在func2中能使用吗?//在func1中定义的b,在func2中能使用吗?练习voidfun1(){#definea10constintb=20;//#undefa#undef}voidfun2(){printf("a=%d\n",a);//printf("b=%d\n",b);}intmain(){fun1();18fun2();return0;}5结论C语言中的const变量C语言中const变量是只读变量,有自己的存储空间C++中的const常量可能分配存储空间,也可能不分配存储空间当const常量为全局,并且需要在其它文件中使用,会分配存储空间当使用&操作符,取const常量的地址时,会分配存储空间当constint&a=10;const修饰引用时,也会分配存储空间6引用专题讲座1引用(普通引用)变量名回顾变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)程序中通过变量来申请并命名内存空间通过变量的名字可以使用存储空间问题1:对一段连续的内存空间只能取一个别名吗?1引用概念a)在C++中新增加了引用的概念b)引用可以看作一个已定义变量的别名c)引用的语法:Type&name=var;d)引用做函数参数那?(引用作为函数参数声明时不进行初始化)voidmain01(){inta=10;//c编译器分配4个字节内存。。。a内存空间的别名int&b=a;//b就是a的别名。。。a=11;//直接赋值{int*p=&a;*p=12;19printf("a%d\n",a);}b=14;printf("a:%db:%d",a,b);system("pause");}2引用是C++的概念属于C++编译器对C的扩展问题:C中可以编译通过吗?intmain(){inta=0;int&b=a;//int*constb=&ab=11;//*b=11;return0;}结论:请不要用C的语法考虑b=113引用做函数参数普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化//05复杂数据类型的引用structTeacher{charname[64];intage;};voidprintfT(Teacher*pT){cout<<pT->age<<endl;}//pT是t1的别名,相当于修改了t1voidprintfT2(Teacher&pT){//cout<<pT.age<<endl;pT.age=33;20}//pT和t1的是两个不同的变量voidprintfT3(TeacherpT){cout<<pT.age<<endl;pT.age=45;//只会修改pT变量,不会修改t1变量}voidmain(){Teachert1;t1.age=35;printfT(&t1);printfT2(t1);//pT是t1的别名printf("t1.age:%d\n",t1.age);//33printfT3(t1);//pT是形参,t1copy一份数据给pT//--->pT=t1printf("t1.age:%d\n",t1.age);//35cout<<"hello..."<<endl;system("pause");return;}4引用的意义1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针2)引用相对于指针来说具有更好的可读性和实用性215引用本质思考思考1:C++编译器背后做了什么工作?intmain(){inta=10;int&b=a;//b是a的别名,请问c++编译器后面做了什么工作?b=11;cout<<"b--->"<<a<<endl;printf("a:%d\n",a);printf("b:%d\n",b);printf("&a:%d\n",&a);printf("&b:%d\n",&b);//请思考:对同一内存空间可以取好几个名字吗?system("pause");return0;}单独定义的引用时,必须初始化;说明很像一个常量思考2:普通引用有自己的空间吗?structTeacer{int&a;int&b;};intmain(){printf("sizeof(Teacher)%d\n",sizeof(Teacer));system("pause");return0;}引用是一个有地址,引用是常量。。。。。char*constp6引用的本质1)引用在C++中的内部实现是一个常指针Type&nameType*constname2)C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。3)从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏22Intmain(){intx=10;func(x);}4)请仔细对比间接赋值成立的三个条件1定义两个变量(一个实参一个形参)2建立关联实参取地址传给形参3*p形参去间接的修改实参的值7引用结论1)引用在实现上,只不过是把:间接赋值成立的三个条件的后两步和二为一//当实参传给形参引用的时候,只不过是c++编译器帮我们程序员手工取了一个实参地址,传给了形参引用(常量指针)2)当我们使用引用语法的时,我们不去关心编译器引用是怎么做的当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的8函数返回值是引用(引用当左值)C++引用使用时的难点:当函数返回值为引用时若返回栈变量不能成为其它引用的初始值不能作为左值使用若返回静态变量或全局变量可以成为其他引用的初始值即可作为右值使用,也可作为左值使用C++链式编程中,经常用到引用,运算符重载专题返回值是基础类型,当引用intgetAA1(){inta;a=10;returna;}23//基础类型a返回的时候,也会有一个副本int&getAA2(){inta;a=10;returna;}int*getAA3(){inta;a=10;return&a;}返回值是static变量,当引用//static修饰变量的时候,变量是一个状态变量intj(){staticinta=10;a++;printf("a:%d\n",a);returna;}int&j1(){staticinta=10;a++;printf("a:%d\n",a);returna;}int*j2(){staticinta=10;a++;printf("a:%d\n",a);return&a;}voidmain22()24{//j()的运算结果是一个数值,没有内存地址,不能当左值。。。。。//11=100;//*(a>b?&a:&b)=111;//当被调用的函数当左值的时候,必须返回一个引用。。。。。j1()=100;//编译器帮我们打造了环境j1();*(j2())=200;//相当于我们程序员手工的打造做左值的条件j2();system("pause");}返回值是形参,当引用intg1(int*p){*p=100;return*p;}int&g2(int*p)//{*p=100;return*p;}//当我们使用引用语法的时候,我们不去关心编译器引用是怎么做的//当我们分析乱码这种现象的时候,我们才去考虑c++编译器是怎么做的。。。。voidmain23(){inta1=10;a1=g2(&a1);int&a2=g2(&a1);//用引用去接受函数的返回值,是不是乱码,关键是看返回的内存空间是不是被编译器回收了。。。。printf("a1:%d\n",a1);printf("a2:%d\n",a2);system("pause");}25返回值非基础类型structTeachar{charname[64];intage;};//如果返回引用不是基础类型,是一个类,那么情况非常赋值。。涉及到copy构造函数和=操作重载,抛砖。。。。structTeachar{charname[64];intage;};//如果返回引用不是基础类型,是一个类,那么情况非常赋值。。涉及到copy构造函数和=操作重载,抛砖。。。。structTeachar&OpTeacher(structTeachar&t1){}9指针引用#include"iostream"usingnamespacestd;structTeacher{charname[64];intage;};intgetTe(Teacher**myp){Teacher*p=(Teacher*)malloc(sizeof(Teacher));if(p==NULL){return-1;}memset(p,0,sizeof(Teacher));p->age=33;26*myp=p;//return0;}//指针的引用而已intgetTe2(Teacher*&myp){myp=(Teacher*)malloc(sizeof(Teacher));myp->age=34;return0;}voidmain333(){Teacher*p=NULL;//getTe(&p);getTe2(p);printf("age:%d\n",p->age);system("pause");}2常引用下面开始进入const引用难点1使用变量初始化const引用思考costint&a=bPKconstint&a=10;????问题:const引用,在C++中可以声明const引用constType&name=var;const引用让变量拥有只读属性案例1:intmain(){inta=10;constint&b=a;//int*p=(int*)&b;b=11;//err//*p=11;//只能用指针来改变了27cout<<"b--->"<<a<<endl;printf("a:%d\n",a);printf("b:%d\n",b);printf("&a:%d\n",&a);printf("&b:%d\n",&b);system("pause");return0;}案例2:voidmain41(){inta=10;constint&b=a;//const引用使用变量a初始化a=11;//b=12;//通过引用修改a,对不起修改不了system("pause");}structTeacher1{charname[64];intage;};voidprintTe2(constTeacher1*constpt){}//const引用让变量(所指内存空间)拥有只读属性voidprintTe(constTeacher1&t){//t.age=11;}voidmain42(){Teacher1t1;t1.age=33;printTe(t1);system("pause");}282使用字面量常量初始化const引用思考:1、用变量对const引用初始化,const引用分配内存空间了吗?2、用常量对const引用初始化,const引用分配内存空间了吗?voidmain(){constintb=10;printf("b:%d",&b);//int&a1=19;如果不加const编译失败constint&a=19;printf("&a:%d\n",&a);system("pause");}3综合案例voidmain(){//普通引用inta=10;int&b=a;//常量引用:让变量引用只读属性constint&c=a;//常量引用初始化分为两种//1用变量初始化常量引用{intx=20;constint&y=x;printf("y:%d\n",y);}//2用常量初始化常量引用{//int&m=10;//引用是内存空间的别名字面量10没有内存空间没有方法做引用constint&m=10;}cout<<"hello..."<<endl;29system("pause");return;}3const引用结论1)Const&inte相当于constint*conste2)普通引用相当于int*conste13)当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名4)使用字面量对const引用初始化后,将生成一个只读变量4const修饰类后续课程介绍5综合练习int&j(){staticinta=0;returna;}int&g(){inta=0;returna;}intmain(){inta=g();int&b=g();j()=10;printf("a=%d\n",a);printf("b=%d\n",b);printf("f()=%d\n",f());system("pause");return0;}307C++对C的函数扩展1inline内联函数C++中的const常量可以替代宏常数定义,如:constintA=3;#defineA3C++中是否有解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 替代宏代码片段呢?(替代宏代码片段就可以避免宏的副作用!)C++中推荐使用内联函数替代宏代码片段C++中使用inline关键字声明内联函数内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。//宏替换和函数调用区别#include"iostream"usingnamespacestd;#defineMYFUNC(a,b)((a)<(b)?(a):(b))inlineintmyfunc(inta,intb){returna<b?a:b;}intmain(){inta=1;intb=3;//intc=myfunc(++a,b);//头疼系统intc=MYFUNC(++a,b);printf("a=%d\n",a);printf("b=%d\n",b);printf("c=%d\n",c);system("pause");return0;}说明1:必须inlineintmyfunc(inta,intb)和函数体的实现,写在一块说明2C++编译器可以将一个函数进行内联编译被C++编译器内联编译的函数叫做内联函数内联函数在最终生成的代码中是没有定义的C++编译器直接将函数体插入在函数调用的地方内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)31说明3:C++编译器不一定准许函数的内联请求!说明4内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)内联函数是对编译器的一种请求,因此编译器可能拒绝这种请求内联函数由编译器处理,直接将编译后的函数体插入调用的地方宏代码片段由预处理器处理,进行简单的文本替换,没有任何编译过程说明5:现代C++编译器能够进行编译优化,因此一些函数即使没有inline声明,也可能被编译器内联编译另外,一些现代C++编译器提供了扩展语法,能够对函数进行强制内联如:g++中的__attribute__((always_inline))属性说明6:C++中内联编译的限制:不能存在任何形式的循环语句不能存在过多的条件判断语句函数体不能过于庞大不能对函数进行取址操作函数内联声明必须在调用语句之前编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。结论:1)内联函数在编译时直接将函数体插入函数调用的地方2)inline只是一种请求,编译器不一定允许这种请求3)内联函数省去了普通函数调用时压栈,跳转和返回的开销2默认参数/*1C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值代替*/voidmyPrint(intx=3){printf("x:%d",x);}/*2函数默认参数的规则只有参数列表后面部分的参数才可以提供默认参数值一旦在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数值*/32//默认参数voidprintAB(intx=3){printf("x:%d\n",x);}//在默认参数规则,如果默认参数出现,那么右边的都必须有默认参数voidprintABC(inta,intb,intx=3,inty=4,intz=5){printf("x:%d\n",x);}intmain62(intargc,char*argv[]){printAB(2);printAB();system("pause");return0;}3函数占位参数/*函数占位参数占位参数只有参数类型声明,而没有参数名声明一般情况下,在函数体内部无法使用占位参数*/intfunc(inta,intb,int){returna+b;}intmain01(){//func(1,2);//可以吗?printf("func(1,2,3)=%d\n",func(1,2,3));getchar();return0;}334默认参数和占位参数/*可以将占位参数与默认参数结合起来使用意义为以后程序的扩展留下线索兼容C语言程序中可能出现的不规范写法*///C++可以声明占位符参数,占位符参数一般用于程序扩展和对C代码的兼容intfunc2(inta,intb,int=0){returna+b;}voidmain(){//如果默认参数和占位参数在一起,都能调用起来func2(1,2);func2(1,2,3);system("pause");}结论://如果默认参数和占位参数在一起,都能调用起来5函数重载(Overroad)函数重载概念1函数重载概念函数重载(FunctionOverload)用同一个函数名定义不同的函数当函数名和不同的参数搭配时函数的含义不同2函数重载的判断标准/*函数重载至少满足下面的一个条件:参数个数不同参数类型不同参数顺序不同*/3函数返回值不是函数重载的判断标准实验1:调用情况分析;实验2:判断标准//两个难点:重载函数和默认函数参数混搭重载函数和函数指针/*34intfunc(intx){returnx;}intfunc(inta,intb){returna+b;}intfunc(constchar*s){returnstrlen(s);}intmain(){intc=0;c=func(1);printf("c=%d\n",c);c=func(1,2);printf("c=%d\n",c);c=func("12345");printf("c=%d\n",c);printf("Pressentertocontinue...");getchar();return0;}*/函数重载的调用准则/*编译器调用重载函数的准则将所有同名函数作为候选者尝试寻找可行的候选函数35精确匹配实参通过默认参数能够匹配实参通过默认类型转换匹配实参匹配失败最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。无法匹配所有候选者,函数未定义,编译失败。*//*函数重载的注意事项重载函数在本质上是相互独立的不同函数(静态链编)重载函数的函数类型是不同的函数返回值不能作为函数重载的依据函数重载是由函数名和参数列表决定的。*/函数重载是发生在一个类中里面函数重载遇上函数默认参数//当函数默认参数遇上函数重载会发生什么/*intfunc(inta,intb,intc=0){returna*b*c;}intfunc(inta,intb){returna+b;}//1个参数的允许吗intfunc(inta){returna+b;}intmain(){intc=0;c=func(1,2);//存在二义性,调用失败,编译不能通过36printf("c=%d\n",c);printf("Pressentertocontinue...");getchar();return0;}*/函数重载和函数指针结合/*函数重载与函数指针当使用重载函数名对函数指针进行赋值时根据重载规则挑选与函数指针参数列表一致的候选者严格匹配候选者的函数类型与函数指针的函数类型*//*intfunc(intx)//int(inta){returnx;}intfunc(inta,intb){returna+b;}intfunc(constchar*s){returnstrlen(s);}typedefint(*PFUNC)(inta);//int(inta)intmain(){intc=0;PFUNCp=func;c=p(1);37printf("c=%d\n",c);printf("Pressentertocontinue...");getchar();return0;}*/函数重载、重写、重定义后续课程。8附录附录1:C++语言对C语言扩充和增强的几点具体体现3839附录2:C语言register关键字—最快的关键字register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU的寄存器也就那么几个或几十个,你要是定义了很多很多register变量,它累死也可能不能全部把这些变量放入寄存器吧,轮也可能轮不到你。一、皇帝身边的小太监----寄存器不知道什么是寄存器?那见过太监没有?没有?其实我也没有。没见过不要紧,见过就麻烦大了。^_^,大家都看过古装戏,那些皇帝们要阅读奏章的时候,大臣总是先将奏章交给皇帝旁边的小太监,小太监呢再交给皇帝同志处理。这个小太监只是个中转站,并无别的功能。好,那我们再联想到我们的CPU。CPU不就是我们的皇帝同志么?大臣就相当于我们的内存,数据从他这拿出来。那小太监就是我们
本文档为【C 基础课程讲义】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: ¥18.0 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
肥猫叫noah
暂无简介~
格式:pdf
大小:3MB
软件:PDF阅读器
页数:0
分类:高中语文
上传时间:2020-03-07
浏览量:1