版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++标准模板库
泛型程序设计将程序写得尽可能通用
将算法从特定的数据结构中抽象出来,成为通用的C++的模板为泛型程序设计奠定了关键的基础
STL是泛型程序设计的一个范例
容器(container)迭代器(iterator)算法(algorithms)函数对象(functionobject)*命名空间(namespace)一个命名空间将不同的标识符集合在一个命名作用域(namedscope)内为了解决命名冲突例如,声明一个命名空间NS:namspaceNS{classFile;voidFun();}
则引用标识符的方式如下,NS::Fileobj;NS::Fun();没有声明命名空间的标识符都处于无名的命名空间中*概念和术语命名空间(续)可以用using来指定命名空间例如,经过以下声明:
usingNS::File;
在当前作用域中就可以直接引用Fileusingnamespacestd;
命名空间std中所有标识符都可直接引用在新的C++标准程序库中,所有标识符都声明在命名空间std中,头文件都不使用扩展名*概念和术语容器容器类是容纳、包含一组元素或元素集合的对象。异类容器类与同类容器类顺序容器与关联容器七种基本容器:向量(vector)、双端队列(deque)、列表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)*概念和术语容器的接口通用容器运算符==,!=,>,>=,<,<=,=方法(函数)迭代方法begin(),end(),rbegin(),rend()访问方法size(),max_size(),swap(),empty()*适配器适配器是一种接口类为已有的类提供新的接口。目的是简化、约束、使之安全、隐藏或者改变被修改类提供的服务集合。三种类型的适配器:容器适配器用来扩展7种基本容器,它们和顺序容器相结合构成栈、队列和优先队列容器迭代器适配器函数对象适配器。*概念和术语迭代器迭代器是面向对象版本的指针,它们提供了访问容器、序列中每个元素的方法。*概念和术语算法C++标准模板库中包括70多个算法其中包括查找算法,排序算法,消除算法,记数算法,比较算法,变换算法,置换算法和容器管理等等。这些算法的一个最重要的特性就是它们的统一性,并且可以广泛用于不同的对象和内置的数据类型。*概念和术语顺序容器顺序容器的接口插入方法push_front(),push_back(),insert(),运算符“=”删除方法pop(),erase(),clear()迭代访问方法使用迭代器其他顺序容器访问方法(不修改访问方法)front(),back(),下标[]运算符*容器顺序容器——向量向量属于顺序容器,用于容纳不定长线性序列(即线性群体),提供对序列的快速随机访问(也称直接访问)向量是动态结构,它的大小不固定,可以在程序运行时增加或减少。例10-1求范围2~N中的质数,N在程序运行时由键盘输入。*容器//10_1.cpp#include<iostream>#include<iomanip>#include<vector> //包含向量容器头文件usingnamespacestd;intmain(){vector<int>A(10); intn; intprimecount=0,i,j;cout<<"Enteravalue>=2asupperlimit:";cin>>n;A[primecount++]=2; **for(i=3;i<n;i++){if(primecount==A.size()) A.resize(primecount+10);if(i%2==0)continue;j=3;while(j<=i/2&&i%j!=0)j+=2;if(j>i/2)A[primecount++]=i;}for(i=0;i<primecount;i++)//输出质数
{cout<<setw(5)<<A[i];if((i+1)%10==0)//每输出10个数换行一次
cout<<endl;}cout<<endl;}**顺序容器——双端队列双端队列是一种放松了访问权限的队列。元素可以从队列的两端入队和出队,也支持通过下标操作符“[]”进行直接访问。例10-2使用双端队列容器保存double数值序列*容器顺序容器——列表列表主要用于存放双向链表,可以从任意一端开始遍历。列表还提供了拼接(splicing)操作,将一个序列中的元素插入到另一个序列中。例10-3改写例9-7从键盘输入10个整数,用这些整数值作为结点数据,生成一个链表,按顺序输出链表中结点的数值。然后从键盘输入一个待查找整数,在链表中查找该整数,若找到则删除该整数所在的结点(如果出现多次,全部删除),然后输出删除结点以后的链表。在程序结束之前清空链表。*容器//10_3.cpp#include<iostream>#include<list>usingnamespacestd;intmain(){list<int>Link; //构造一个列表用于存放整数链表
inti,key,item;for(i=0;i<10;i++)//输入10个整数依次向表头插入
{cin>>item;Link.push_front(item);}cout<<"List:";//输出链表**list<int>::iteratorp=Link.begin();while(p!=Link.end())//输出各节点数据,直到链表尾
{cout<<*p<<"";p++;//使P指向下一个节点
}cout<<endl;cout<<"请输入一个需要删除的整数:";cin>>key;Link.remove(key);cout<<"List:";//输出链表
p=Link.begin(); //使P重新指向表头
while(p!=Link.end()) {cout<<*p<<"";p++;//使P指向下一个节点
}cout<<endl;}**容器适配器容器适配器是用来扩展7种基本容器的栈容器使用适配器与一种基础容器相结合来实现例10-4:应用标准库中的deque顺序容器生成一个整数栈stack。队列容器使用适配器与一种基础容器相结合来实现的先进先出数据结构。例10-5:应用标准库中的deque顺序容器生成一个整数标准队列queue。*容器什么是迭代器迭代器是面向对象版本的指针指针可以指向内存中的一个地址迭代器可以指向容器中的一个位置STL的每一个容器类模版中,都定义了一组对应的迭代器类。使用迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型。*迭代器迭代器的类型输入迭代器可以用来从序列中读取数据输出迭代器允许向序列中写入数据前向迭代器既是输入迭代器又是输出迭代器,并且可以对序列进行单向的遍历双向迭代器与前向迭代器相似,但是在两个方向上都可以对数据遍历随机访问迭代器也是双向迭代器,但能够在序列中的任意两个位置之间进行跳转。*迭代器迭代器适配器迭代器适配器是用来扩展(或调整)迭代器功能的类。它本身也被称为迭代器,只是这种迭代器是通过改变另一个迭代器而得到的逆向迭代器通过重新定义递增运算和递减运算,使其行为正好倒置插入型迭代器将赋值操作转换为插入操作。通过这种迭代器,算法可以执行插入行为而不是覆盖行为例10-6应用逆向迭代器和后插迭代器来操作向量容器中的元素*迭代器迭代器相关的辅助函数advance()函数将迭代器的位置增加,增加的幅度由参数决定distance()函数返回迭代器之间的距离函数iter_swap()交换两个迭代器所指向的元素值例10-7用三个迭代器辅助函数来操作列表容器中的元素。*迭代器标准C++库中的算法算法本身是一种函数模板不可变序列算法(non-mutatingalgorithms)不直接修改所操作的容器内容的算法可变序列算法(mutatingalgorithms)可以修改它们所操作的容器的元素。排序相关算法数值算法*算法算法应用举例例10-9应用不可变序列算法对数据序列进行分析例10-10以可变序列算法对数据序列进行复制,生成,删除,替换,倒序,旋转等可变性操作。例10-11应用排序相关算法对序列进行各项操作例10-12应用数值算法对数据序列进行操作*算法函数对象一个行为类似函数的对象,它可以没有参数,也可以带有若干参数,其功能是获取一个值,或者改变操作的状态。任何普通的函数和任何重载了调用运算符operator()的类的对象都满足函数对象的特征STL中也定义了一些标准的函数对象,如果以功能划分,可以分为算术运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象,需要包含头文件<functional>。*小结与复习建议主要内容泛型程序设计、与标准模板库有关的概念和术语、C++标准模板库中的容器、迭代器、标准C++库中的算法、函数对象达到的目标初步了解泛型程序设计的概念,学会C++标准模板库(STL)的使用方法实验任务实验十*
C++程序的结构
函数原型的作用域函数原型中的参数,其作用域始于
"(",结束于")"。例如,设有下列原型声明:doublearea(doubleradius);*radius的作用域仅在于此,不能用于程序正文其他地方,因而可有可无。作用域与可见性局部作用域函数的形参,在块中声明的标识符,其作用域自声明处起,限于块中,例如:voidfun(inta){intb=a;cin>>b;if(b>0){intc;
}}*c的作用域b的作用域作用域与可见性a的作用域类作用域类作用域作用于特定的成员名。类X的成员m具有类作用域,对m的访问方式如下:如果在X的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以访问成员m。通过表达式x.m或者X::m访问。通过表达式ptr->m*作用域与可见性文件作用域不在前述各个作用域中出现的声明,具有文件作用域,这样声明的标识符的作用域开始于声明点,结束于文件尾。*作用域与可见性可见性可见性是从对标识符的引用的角度来谈的概念可见性表示从内层作用域向外层作用域“看”时能看见什么。如果标识在某处可见,则就可以在该处引用此标识符。*块作用域类作用域文件作用域作用域与可见性可见性标识符应声明在先,引用在后。如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则该标识符在内层可见。对于两个嵌套的作用域,如果在内层作用域内声明了与外层作用域中同名的标识符,则外层作用域的标识符在内层不可见。*作用域与可见性同一作用域中的同名标识符在同一作用域内的对象名、函数名、枚举常量名会隐藏同名的类名或枚举类型名。重载的函数可以有相同的函数名。*作用域与可见性例5.1#include<iostream>usingnamespacestd;inti;//文件作用域intmain(){
i=5;{inti;//块作用域
i=7;cout<<"i="<<i<<endl;//输出7}
cout<<"i="<<i;//输出5
return0;}*作用域与可见性对象的生存期对象从产生到结束的这段时间就是它的生存期。在对象生存期内,对象将保持它的值,直到被更新为止。*静态生存期这种生存期与程序的运行期相同。在文件作用域中声明的对象具有这种生存期。在函数内部声明静态生存期对象,要冠以关键字static
。*对象的生存期例#include<iostream>usingnamespacestd;inti=5;//文件作用域intmain(){cout<<"i="<<i<<endl;return0;}i具有静态生存期*对象的生存期动态生存期块作用域中声明的,没有用static修是的对象是动态生存期的对象(习惯称局部生存期对象)。开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。*对象的生存期例#include<iostream>usingnamespacestd;voidfun();intmain(){fun();fun();}voidfun(){
staticinta=1;inti=5;
a++;
i++;cout<<"i="<<i<<",a="<<a<<endl;}*运行结果:i=6,a=2i=6,a=3i是动态生存期a是静态生存期对象的生存期例5-2变量的生存期与可见性#include<iostream>usingnamespacestd;inti=1;//i为全局变量,具有静态生存期。voidother(){staticinta=2;staticintb;//a,b为静态局部变量,具有全局寿命,局部可见。
//只第一次进入函数时被初始化。
intc=10;//C为局部变量,具有动态生存期,
//每次进入函数时都初始化。
a+=
2;i+=
32;c+=
5;cout<<"OTHER\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;
b=a;}*对象的生存期intmain(){staticinta;//静态局部变量,有全局寿命,局部可见。
intb=-10;//b,c为局部变量,具有动态生存期。
intc=0; cout<<"MAIN\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;c+=8;other();cout<<"MAIN\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;
i+=
10;other(); return0;}17运行结果:MAIN
i:1
a:0b:-10c:0OTHER
i:33
a:4b:0c:15MAIN
i:33
a:0b:-10c:8OTHER
i:75
a:6b:4c:1518例5-3具有静态、动态生存期对象的时钟程序#include<iostream>usingnamespacestd;classClock{ //时钟类定义public: //外部接口
Clock(); voidsetTime(intnewH,intnewM,intnewS);//三个形参均具有函数原型作用域
voidshowTime();private: //私有数据成员
inthour,minute,second;};*对象的生存期Clock::Clock():hour(0),minute(0),second(0){} //构造函数voidClock::setTime(intnewH,intnewM,intnewS){//三个形参均具有局部作用域
hour=newH; minute=newM; second=newS;}voidClock::showTime(){ cout<<hour<<":"<<minute<<":"<<second<<endl;}20ClockglobClock;//声明对象globClock,
//具有静态生存期,文件作用域intmain(){//主函数 cout<<"Firsttimeoutput:"<<endl;
//引用具有文件作用域的对象:
globClock.showTime();//对象的成员函数具有类作用域
globClock.setTime(8,30,30); ClockmyClock(globClock);
//声明具有块作用域的对象myClock cout<<"Secondtimeoutput:"<<endl;
myClock.showTime(); //引用具有块作用域的对象 return0;}21程序的运行结果为:Firsttimeoutput:0:0:0Secondtimeoutput:8:30:3022数据与函数数据存储在局部对象中,通过参数传递实现共享——函数间的参数传递。数据存储在全局对象中。将数据和使用数据的函数封装在类中。*数据与函数使用全局对象#include<iostream>usingnamespacestd;intglobal;voidf(){global=5;}voidg(){cout<<global<<endl;}intmain(){f();g();//输出“5”return0;}*数据与函数将函数与数据封装#include<iostream>usingnamespacestd;classApplication{public:voidf();voidg();private:intglobal;};voidApplication::f(){
global=5;}voidApplication::g(){cout<<global<<endl;}intmain(){ApplicationMyApp;MyApp.f();MyApp.g();return0;}*数据与函数静态成员静态数据成员用关键字static声明该类的所有对象维护该成员的同一个拷贝必须在类外定义和初始化,用(::)来指明所属的类。静态成员函数类外代码可以使用类名和作用域操作符来调用静态成员函数。静态成员函数只能引用属于该类的静态数据成员或静态成员函数。*静态成员例5-4
具有静态数据成员的Point类#include<iostream>usingnamespacestd;classPoint {public: Point(intx=0,inty=0):x(x),y(y){count++;} Point(Point&p); intgetX(){returnx;} intgetY(){returny;} voidshowCount(){ cout<<"Objectcount=“<<count<<endl;}private: intx,y;
staticintcount;};*静态成员Point::Point(Point&p){ x=p.x; x=p.y; count++;}intPoint::count=0;
intmain(){ Pointa(4,5); cout<<"PointA:"<<a.getX()<<","<<a.getY(); a.showCount(); Pointb(a); cout<<"PointB:"<<b.getX()<<","<<b.getY(); b.showCount(); return0;}28静态成员函数举例#include<iostream>usingnamespacestd;classApplication{public:staticvoidf();staticvoidg();private:staticintglobal;};intApplication::global=0;voidApplication::f(){ global=5;}voidApplication::g(){ cout<<global<<endl;}intmain(){ Application::f(); Application::g(); return0;}*静态成员静态成员函数举例classA{public: staticvoidf(Aa);private: intx;};voidA::f(Aa){ cout<<x;//对x的引用是错误的 cout<<a.x;//正确}*静态成员具有静态数据、函数成员的Point类#include<iostream>usingnamespacestd;classPoint{ //Point类定义public: //外部接口
Point(intx=0,inty=0):x(x),y(y){count++;} Point(Point&p); ~Point(){count--;} intgetX(){returnx;} intgetY(){returny;} staticvoidshowCount(){ //静态函数成员
cout<<"Objectcount="<<count<<endl; }private: //私有数据成员
intx,y; staticintcount; //静态数据成员声明};*静态成员Point::Point(Point&p){ x=p.x; y=p.y; count++;}intPoint::count=0;
intmain(){//主函数实现 Pointa(4,5); //声明对象A cout<<"PointA,"<<a.getX()<<","<<a.getY();
Point::showCount(); //输出对象个数
Pointb(a); //声明对象B cout<<"PointB,"<<b.GetX()<<","<<b.GetY();
Point::showCount(); //输出对象个数 return0;}32友元友元是C++提供的一种破坏数据封装和数据隐藏的机制。通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息。可以使用友元函数和友元类。为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。*
友元友元函数友元函数是在类声明中由关键字friend修饰说明的非成员函数,在它的函数体中能够通过对象名访问private和protected成员作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。访问对象中的成员必须通过对象名。*
友元例5-6使用友元函数计算两点距离#include<iostream>#include<cmath>classPoint{ //Point类声明public: //外部接口
Point(intx=0,inty=0):x(x),y(y){} intgetX(){returnx;} intgetY(){returny;}
friendfloatdist(Point&a,Point&b);
private: //私有数据成员
intx,y;};*
友元floatdist(Point&a,Point&b){doublex=a.x-b.x;doubley=a.y-b.y;returnstatic_cast<float>(sqrt(x*x+y*y));}intmain(){Pointp1(1,1),p2(4,5);cout<<"Thedistanceis:";cout<<dist(p1,p2)<<endl;return0;}36友元类若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。声明语法:将友元类名在另一个类中使用friend修饰说明。*
友元友元类举例classA{friendclassB;public:voiddisplay(){cout<<x<<endl;}private:intx;}classB{public:voidset(inti);voiddisplay();private:
Aa;};*
友元voidB::set(inti){
a.x=i;}voidB::display(){a.display();}39友元关系是单向的如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有、保护数据。*常类型常类型的对象必须进行初始化,而且不能被更新。常对象:必须进行初始化,不能被更新。const类名
对象名常引用:被引用的对象不能被更新。const类型说明符&引用名常数组:数组元素不能被更新(下一章介绍)。类型说明符const数组名[大小]...常指针:指向常量的指针(下一章介绍)。*
共享数据的保护常对象举例classA{public:A(inti,intj){x=i;y=j;}...private:intx,y;};Aconsta(3,4);//a是常对象,不能被更新*
共享数据的保护用const修饰的对象成员常成员函数使用const关键字说明的函数。常成员函数不更新对象的数据成员。常成员函数说明格式:
类型说明符函数名(参数表)const;
这里,const是函数类型的一个组成部分,因此在实现部分也要带const关键字。const关键字可以被用于参与对重载函数的区分通过常对象只能调用它的常成员函数。常数据成员使用const说明的数据成员。*
共享数据的保护例5-7常成员函数举例#include<iostream>usingnamespacestd;classR{public:R(intr1,intr2):r1(r1),r2(r2){}voidprint();voidprint()const;private:intr1,r2;};*
共享数据的保护voidR::print(){cout<<r1<<":"<<r2<<endl;}voidR::print()const{cout<<r1<<";"<<r2<<endl;}intmain(){Ra(5,4);a.print();//调用voidprint()
constRb(20,52);
b.print();//调用voidprint()const return0;}45例5-8常数据成员举例#include<iostream>usingnamespacestd;classA{public: A(inti); voidprint();private: constinta; staticconstintb;//静态常数据成员};*
共享数据的保护constintA::b=10;A::A(inti):a(i){}voidA::print(){cout<<a<<":"<<b<<endl;}intmain(){/*建立对象a和b,并以100和0作为初值,分别调用构造函数,通过构造函数的初始化列表给对象的常数据成员赋初值*/Aa1(100),a2(0);a1.print();a2.print();return0;}47例5-9常引用作形参#include<iostream>#include<cmath>usingnamespacestd;classPoint{ //Point类定义public: //外部接口
Point(intx=0,inty=0):x(x),y(y){} intgetX(){returnx;} intgetY(){returny;} friendfloatdist(constPoint&p1,constPoint&p2);private: //私有数据成员
intx,y;};*
共享数据的保护例5-9常引用作形参floatdist(constPoint&p1,constPoint&p2){
doublex=p1.x-p2.x; doubley=p1.y-p2.y; returnstatic_cast<float>(sqrt(x*x+y*y));}intmain(){ //主函数
constPointmyp1(1,1),myp2(4,5);
cout<<"Thedistanceis:"; cout<<dist(myp1,myp2)<<endl;
return0;}*
共享数据的保护编译预处理命令#include包含指令将一个源文件嵌入到当前源文件中该点处。#include<文件名>按标准方式搜索,文件位于C++系统目录的include子目录下#include"文件名"首先在当前目录中搜索,若没有,再按标准方式搜索。#define宏定义指令定义符号常量,很多情况下已被const定义语句取代。定义带参数宏,已被内联函数取代。#undef删除由#define定义的宏,使之不再起作用。*条件编译指令
#if和#endif#if
常量表达式
//当“常量表达式”非零时编译程序正文#endif*
编译预处理命令条件编译指令——#else #if常量表达式
//当“常量表达式”非零时编译程序正文1#else
//当“常量表达式”为零时编译程序正文2#endif*
编译预处理命令条件编译指令#elif#if常量表达式1
程序正文1
//当“常量表达式1”非零时编译#elif常量表达式2
程序正文2
//当“常量表达式2”非零时编译#else
程序正文3
//其他情况下编译#endif*
编译预处理命令条件编译指令#ifdef标识符程序段1#else
程序段2#endif如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。*
编译预处理命令条件编译指令#ifndef标识符程序段1#else
程序段2#endif如果“标识符”未被定义过,则编译程序段1,否则编译程序段2。*
编译预处理命令多文件结构(例5-10)一个源程序可以划分为多个源文件:类声明文件(.h文件)类实现文件(.cpp文件)类的使用文件(main()所在的.cpp文件)利用工程来组合各个文件。*不使用条件编译的头文件//main.cpp#include"file1.h"#include"file2.h"intmain(){…}//file1.h#include"head.h"…//file2.h#include"head.h"…//head.h…classPoint{…}…*
多文件结构使用条件编译的头文件//head.h#ifndefHEAD_H#defineHEAD_H…classPoint{…}…#endif*
多文件结构常成员函数的声明原则适当地将成员函数声明为常成员函数,能够提高代码质量。凡是不会改变对象状态的函数,都应当声明为常成员函数。什么是改变对象状态?改变对象状态,不简单地等同于改变成员数据的值。只要一个成员函数执行与否,不会影响以后接口函数的调用结果,都可以认为它不会改变对象状态。*深度探索常成员函数的声明原则classLine{ //Line类的定义public: //外部接口
Line(constPoint&p1,constPoint&p2):p1(p1),p2(p2),len(-1){} doublegetLen();private: //私有数据成员
Pointp1,p2; //Point类的对象p1,p2 doublelen;};doubleLine::getLen(){ if(len<0){ doublex=p1.getX()-p2.getX(); doubley=p1.getY()-p2.getY(); len=sqrt(x*x+y*y); } returnlen;}*深度探索改变数据成员,但不改变对象状态常成员函数的声明原则在原则上,应当将getLen声明为常成员函数,但由于修改了数据成员的值,语言规则不允许怎么办?使用mutable关键字mutable关键字使得被修饰的成员对象无视“常对象的成员对象被视为常对象”这一语言原则Mutable须慎用*深度探索代码的编译连接与执行编译:源文件
目标文件源文件的函数代码
目标文件的代码段源文件的静态对象
目标文件的数据段分为初始化的数据段和未初始化的数据段符号表:将静态对象与函数的名字与地址关联重定位记录表:将代码中需用到的地址与符号表关联连接将各段合并将符号表合并根据重定位记录表,确定代码中用到的全局地址*深度探索代码的编译连接与执行代码的执行操作系统首先将文件从磁盘读入,初始化各段——一些静态数据就在此时被初始化从引导代码开始执行,引导代码启动main,main返回后,引导代码会通知操作系统程序结束为什么只有静态对象需要在目标文件中保存信息?连接器负责为静态对象分配唯一地址,而其它对象都是相对寻址为什么类的信息不存在于目标文件中?类的“解构”*深度探索小结与复习建议主要内容作用域与可见性、对象的生存期、数据的共享与保护、友元、编译预处理命令、多文件结构和工程达到的目标深入理解程序的结构、模块间的关系、数据共享。实验任务实验五*C++简单程序设计
C++语言的产生C++是从C语言发展演变而来的,首先是一个更好的C引入了类的机制,最初的C++被称为“带类的C”1983年正式取名为C++从1989年开始C++语言的标准化工作于1994年制定了ANSIC++标准草案于1998年11月被国际标准化组织(ISO)批准为国际标准,成为目前的C++*C++语言概述C++的特点全面兼容C它保持了C的简洁、高效和接近汇编语言等特点对C的类型系统进行了改革和扩充C++也支持面向过程的程序设计,不是一个纯正的面向对象的语言支持面向对象的方法*C++语言概述C++程序实例—例2-1//2_1.cpp#include<iostream>usingnamespacestd;intmain(){ cout<<"Hello!"<<endl; cout<<"Welcometoc++!"<<endl; return0;}运行结果:Hello!Welcometoc++!*C++语言概述C++字符集大小写的英文字母:A~Z,a~z数字字符:0~9特殊字符:
! # % ^ & * _ + = - ~ < > / \ ‘
“ ; . , : ? ( ) [ ] { }*C++语言概述词法记号关键字
C++预定义的单词标识符
程序员声明的单词,它命名程序正文中的一些实体文字
在程序中直接使用符号表示的数据操作符
用于实现各种运算的符号分隔符
(){},:;
用于分隔各个词法记号或程序正文空白符 空格、制表符(TAB键产生的字符)、垂直制表符、换行符、回车符和注释的总称*C++语言概述标识符的构成规则以大写字母、小写字母或下划线(_)开始。可以由以大写字母、小写字母、下划线(_)或数字0~9组成。大写字母和小写字母代表不同的标识符。*C++语言概述
数据类型
——常量与变量#include<iostream>usingnamespacestd;intmain(){constintPRICE=30;intnum,total;floatv,r,h;num=10;total=num*PRICE;cout<<total<<endl;r=2.5;h=3.2;v=3.14159*r*r*h;cout<<v<<endl;return0;}*常量变量变量先声明后使用符号常量基本数据类型和表达式
数据类型
——整型数据#include<iostream>usingnamespacestd;intmain(){constintPRICE=30;intnum,total;floatv,r,h;num=10;total=num*PRICE;cout<<total<<endl;r=2.5;h=3.2;v=3.14159*r*r*h;cout<<v<<endl;return0;}*shortunsignedshort2字节intunsignedint
4字节longunsignedlong4字节整型变量声明基本数据类型和表达式整型变量整型常量数据类型
—整数数据及取值范围类型 说明符 位数 数值范围 短整 short 16 -32768~32767基本 int 32 -231~(231-1)长整 long 32 -231~(231-1)无符号
unsignedshort 16 0~65535
unsigned[int] 32 0~(232-1)
unsignedlong 32 0~(232-1) *基本数据类型和表达式
数据类型
——实数数据#include<iostream>usingnamespacestd;intmain(){constintPRICE=30;intnum,total;floatv,r,h;num=10;total=num*PRICE;cout<<total<<endl;r=2.5;h=3.2;v=3.14159*r*r*h;cout<<v<<endl;return0;}*实型常量float4字节
3.4×10±387位有效数字double8字节
1.7×10±30815位有效数字longdouble8字节
1.7×10±30815位有效数字实型变量默认为double型后缀F(或f)
为float型后缀L(或l)
为longdouble
型基本数据类型和表达式
数据类型
——字符数据(一)字符常量单引号括起来的一个字符,
如:'a','D','?','$'字符变量用来存放字符常量
例:charc1,c2;
c1='a';
c2='A';字符数据在内存中的存储形式以ASCII码存储,占1字节,用7个二进制位*基本数据类型和表达式
数据类型
——字符型数据(二)字符数据的使用方法字符数据和整型数据之间可以运算。字符数据与整型数据可以互相赋值。字符串常量例:"CHINA"
"a"
'a'所以:charc;
c="a";*CHINA\0a
\0aPage*基本数据类型和表达式
数据类型
——布尔型数据布尔型变量的说明:
例:boolflag;布尔型数据的取值:
只有false
和true
两个值*基本数据类型和表达式
数据类型
——变量初始化例:
inta=3;
doublef=3.56;
charc='a';
intc(5);*Page*基本数据类型和表达式数据类型
—混合运算时的类型转换不同类型数据进行混合运算时,C++编译器会自动进行类型转换。为了避免不同的数据类型在运算中出现类型问题,应尽量使用同种类型数据。可以采用强制类型转换:例如:
floatc;
inta,b;
c=float(a)/float(b);或c=(float)a/(float)b;
*基本数据类型和表达式变量的存储类型auto属于一时性存储,其存储空间可以被若干变量多次覆盖使用。register存放在通用寄存器中。extern在所有函数和程序段中都可引用。static在内存中是以固定地址存放的,在整个程序运行期间都有效。*基本数据类型和表达式算术运算符与算术表达式基本算术运算符
+-*/(若整数相除,结果取整)%(取余,操作数为整数)优先级与结合性先乘除,后加减,同级自左至右++,--(自增、自减)例:i++;--j;*Page*基本数据类型和表达式赋值运算符和赋值表达式
简单的赋值运算符"="举例
n=n+5表达式的类型
赋值运算符左边对象的类型表达式的值
赋值运算符左边对象被赋值后的值*Page*基本数据类型和表达式赋值运算符和赋值表达式
复合的赋值运算符有10种复合运算符:
+=,-=,*=,/=,%=,
<<=,>>=,&=,^=,|=例
a+=3
等价于a=a+3
x*=y+8
等价于x=x*(y+8)*基本数据类型和表达式逗号运算和逗号表达式格式表达式1,表达式2求解顺序及结果先求解1,再求解2,最终结果为表达式2的值例a=3*5,a*4
最终结果为60*Page*基本数据类型和表达式关系运算与关系表达式关系运算是比较简单的一种逻辑运算,优先次序为:
<<=>>===!=
优先级相同(高)优先级相同(低)关系表达式是一种最简单的逻辑表达式其结果类型为bool,值只能为true
或false。例如:a>b,c<=a+b,x+y==3*基本数据类型和表达式逻辑运算与逻辑表达式逻辑运算符
!(非)&&(与)||(或)
优先次序:高→低逻辑表达式
例如:(a>b)&&(x>y)
其结果类型为bool,值只能为true
或false*基本数据类型和表达式逻辑运算与逻辑表达式“&&”
的“短路特性”表达式1&&表达式2先求解表达式1若表达式1的值为false,则最终结果为false,不再求解表达式2若表达式1的结果为true,则求解表达式2,以表达式2的结果作为最终结果“||”也具有类似的特性*基本数据类型和表达式条件运算符与条件表达式一般形式表达式1?表达式2:表达式3表达式1必须是bool类型执行顺序先求解表达式1,若表达式1的值为true,则求解表达式2,表达式2的值为最终结果若表达式1的值为false,则求解表达式3,表达式3的值为最终结果例:x=a>b?a:b;*基本数据类型和表达式条件运算符与条件表达式注意:条件运算符优先级高于赋值运算符,低于逻辑运算符表达式2、3的类型可以不同,条件表达式的最终类型为2和3中较高的类型。例:x=a>b?a:b;*基本数据类型和表达式①②sizeof运算符语法形式
sizeof(类型名)
或sizeof表达式结果值:
“类型名”所指定的类型或“表达式”的结果类型所占的字节数。例:sizeof(short)sizeofx*基本数据类型和表达式位运算——按位与(&)运算规则将两个运算量的每一个位进行逻辑与操作举例:计算3&53:000000115:(&)000001013&5:00000001用途:将某一位置0,其他位不变。例如:
将char型变量a的最低位置0:
a=a&0xfe;取指定位。
例如:有charc;inta;
取出a的低字节,置于c中:c=a&0xff;*基本数据类型和表达式位运算——按位或(|)运算规则将两个运算量的每一个位进行逻辑或操作举例:计算3|53:000000115:(|)000001013|5:00000111用途:将某些位置1,其他位不变。
例如:将int
型变量a
的低字节置
1
:
a=a|0xff;*基本数据类型和表达式位运算——按位异或(^)运算规则两个操作数进行异或:
若对应位相同,则结果该位为0,
若对应位不同,则结果该位为1,举例:计算071^052071: 00111001052:(^)00101010071^052: 00010011*基本数据类型和表达式位运算——按位异或(^)用途:使特定位翻转(与0异或保持原值,与1异或取反)例如:要使01111010
低四位翻转:
01111010(^) 00001111 01110101*基本数据类型和表达式位运算——取反(~)单目运算符,对一个二进制数按位取反。例:025:0000000000010101~025:1111111111101010*基本数据类型和表达式位运算——移位左移运算(<<)左移后,低位补0,高位舍弃。右移运算(>>)右移后,低位:舍弃高位:无符号数:补0
有符号数:补“符号位”*基本数据类型和表达式运算符优先级括号++,--,sizeof*,/,%+,-==,!=位运算&&||?:赋值运算逗号运算*低高基本数据类型和表达式混合运算时数据类型的转换
——隐含转换一些二元运算符(算术运算符、关系运算符、逻辑运算符、位运算符和赋值运算符)要求两个操作数的类型一致。在算术运算和关系运算中如果参与运算的操作数类型不一致,编译系统会自动对数据进行转换(即隐含转换),基本原则是将低类型数据转换为高类型数据。
char,short,int,unsigned,long,unsignedlong,float,double
低高*基本数据类型和表达式混合运算时数据类型的转换
——隐含转换当参与运算的操作数必须是bool型时,如果操作数是其它类型,编译系统会自动将非0数据转换为true,0转换为false。位运算的操作数必须是整数,当二元位运算的操作数是不同类型的整数时,也会自动进行类型转换,赋值运算要求左值与右值的类型相同,若类型不同,编译系统会自动将右值转换为左值的类型。*基本数据类型和表达式混合运算时数据类型的转换
——显式转换语法形式(3种):类型说明符(表达式)(类型说明符)表达式类型转换操作符<类型说明符>(表达式)类型转换操作符可以是:
const_cast、dynamic_cast、
reinterpret_cast、static_cast显式类型转换的作用是将表达式的结果类型转换为类型说明符所指定的类型。例:int(z),(int)z,static_cast<int>(z)
三种完全等价*基本数据类型和表达式语句空语句声明语句表达式语句复合语句选择语句循环语句跳转语句标号语句
*表达式语句格式:表达式;表达式语句与表达式的区别:表达式可以包含在其他表达式中,而语句不可。例如:if((a=b)>0)t=a;不可写为:if((a=b;)>0)t=a;*语句复合语句将多个语句用一对大括号包围,便构成一个复合语句例如{ sum=sum+i; i++;} *语句简单的输入、输出向标准输出设备(显示器)输出例:intx;cout<<"x="<<x;从标准输入设备(键盘)输入例:intx;cin>>x;*算法的基本控制结构顺序结构分支结构循环结构*如何解决分支问题?例2-2输入一个年份,判断是否闰年。*算法的基本控制结构#include<iostream>usingnamespacestd;intmain()
{ intyear;boolIsLeapYear;cout
<<
"Entertheyear:";cin
>>
year; IsLeapYear=((year%4==0&&
year%100!=0)
||
(year%400==0));
if(IsLeapYear)
cout
<<
year
<<
"isaleapyear“
<<
endl;
else
cout
<<
year
<<
"isnotaleapyear“
<<endl; return0;}*运行结果:Entertheyear:20002000isaleapyear*if语句
——三种形式if(表达式)语句例:if(x>y)cout<<x;if(表达式)语句1else语句2例:if(x>y)cout<<x;elsecout<<y;if(表达式1)语句1
elseif(表达式2)语句2
elseif(表达式3)语句3
…
else语句n*算法的基本控制结构如何解决多分问题?例2-3输入两个整数,比较两个数的大小。*算法的基本控制结构#include<iostream>usingnamespacestd;intmain(){ intx,y; cout<<"Enterxandy:"; cin>>x>>y; if(x!=y) if(x>y) cout<<"x>y"<<endl; else cout<<"x<y"<<endl; else cout<<"x=y"<<endl; return0;}*运行结果1:Enterxandy:58x<y运行结果2:Enterxandy:88x=y运行结果3:Enterxandy:128x>y*一般形式if()if()语句1else语句2elseif()语句3else语句4注意语句1、2、3、4可以是复合语句,每层的if与else配对,或用{}来确定层次关系。*if语句
——嵌套算法的基本控制结构特殊的多分支结构例2-4输入一个0~6的整数,转换成星期输出。*算法的基本控制结构#include<iostream>usingnamespacestd;intmain()
{
intday; cin>>day; switch(day)
{
case0:
cout
<<
"Sunday"
<<
endl;
break;
case1:
cout
<<
"Monday"
<<
endl;
break;
case2:
cout
<<
"Tuesday"
<<
endl;
break;
case3:cout
<<
"Wednesday"
<<
endl;
break;
case4:
cout
<<
"Thursday"
<<
endl;
break;
case5:
cout
<<
"Friday"
<<
endl;
break;
case6:
cout
<<
"Saturday"
<<
endl;
break;
default:
cout
<<
"DayoutofrangeSunday..Saturday"
<<
endl;
break; } return0;}*switch语句一般形式switch(表达式){case常量表达式1:语句1case常量表达式2:语句2┆case常量表达式n:语句ndefault:语句n+1}*执行顺序以case中的常量表达式值为入口标号,由此开始顺序执行。因此,每个case分支最后应该加break语句。每个常量表达式的值不能相同,次序不影响执行结果。可以是多个语句,但不必用{}。可以是整型、字符型、枚举型算法的基本控制结构使用switch语句应注意的问题case分支可包含多个语句,且不用{}。表达式、判断值都是int型或char型。若干分支执行内容相同可共用一组语句。*算法的基本控制结构如何有效地完成重复工作例2-5求自然数1~10之和分析:本题需要用累加算法,累加过程是一个循环过程,可以用while语句实现。*算法的基本控制结构#include<iostream>usingnamespacestd;intmain(){inti=1,sum=0;
while(i<=10){sum+=i;//相当于sum=sum+i;i++;
}cout<<"sum="<<sum<<endl; return0;}运行结果:sum=55*while语句形式while(表达式)语句
*可以是复合语句,其中必须含有改变条件表达式值的语句。执行顺序先判断表达式的值,若为true时,执行语句。算法的基本控制结构先执行循环体,后判断条件的情况例2-6
输入一个整数,将各位数字反转后输出。*算法的基本控制结构#include<iostream>usingnamespacestd;intmain()
{ intn,right_digit,newnum=0; cout<<"Enterthenumber:"; cin>>n;
cout<<"Thenumberinreverseorderis";
do
{ right_digit=n%10; cout<<right_digit; n/=10;
//相当于n=n/10
}while(n!=0);cout<<endl; return0;}*运行结果:Enterthenumber:365Thenumberinreverseorderis563*do-while语句一般形式do语句while(表达式)*可以是复合语句,其中必须含有改变条件表达式值的语句。执行顺序先执行循环体语句,后判断条件。
表达式为true时,继续执行循环体与while语句的比较:while语句执行顺序
先判断表达式的值,为true时,再执行语句算法的基本控制结构对比下列程序:程序1:#include<iostre
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 酒店照明设计对顾客用餐心情的影响
- 家庭办公环境的卫生与健康改善措施
- 临时劳动合同续签协议
- 临时工程合作合同范例
- 临时工雇佣合同协议
- 中央空调系统维修保养合同
- 上海商业地产营销代理合同
- 交通运输设备合作协议
- 上市公司债券发行专项法律服务合同
- 临街商铺租赁合同书
- 社会主义发展史(齐鲁师范学院)知到智慧树章节答案
- 2023年高考真题-地理(辽宁卷) 含解析
- 课程思政融入高职院校应用文写作课程教学路径探析
- 2024全新钢结构安全培训
- 2025届高三数学一轮复习-分段函数专项训练【含答案】
- 腰椎间盘突出症课件(共100张课件)
- 《工程力学》课程教学大纲
- 2024至2030年中国女装行业市场发展监测及投资前景展望报告
- 7.1.2 直观图的画法-【中职专用】高一数学教材配套课件(高教版2021·基础模块下册)
- 皮肤癣菌病的分子诊断工具
- SL+575-2012水利水电工程水土保持技术规范
评论
0/150
提交评论