




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农业机械生产建设项目可行性研究报告范文
- 冰雪旅游项目投资可行性研究及旅游产业投资分析报告
- 软件测试工程师的成长路径试题及答案
- 2025年广播媒体融合传播中的媒体融合与版权保护技术创新与应用案例研究报告
- 工业互联网平台量子通信技术在智能工厂生产过程可视化中的应用前景分析报告
- 2025年电商绿色物流绿色物流包装材料回收与再利用产业发展现状与趋势报告
- 酒店跟网吧合作协议
- 康复医疗器械市场前景分析:2025年需求增长创新产品推动行业新发展报告
- 2025年文化旅游演艺项目策划与市场细分策略研究报告
- 工业互联网平台边缘计算硬件架构在智能家居行业的创新应用报告
- 2025年日历(日程安排-可直接打印)
- 软件项目成果报告范文
- 【MOOC】心理学-华南师范大学 中国大学慕课MOOC答案
- 针灸治疗之蛇串疮课件
- 大型商场装修施工组织设计方案
- 【MOOC】材料力学-西北工业大学 中国大学慕课MOOC答案
- 《英语翻译》教案全套 陈霞 第1-8章 中西方翻译史 - 文体翻译
- 人教版(2024)八年级上册物理期中模拟试卷3套(含答案)
- DB11∕T 2115-2023 机械式停车设备使用管理和维护保养安全技术规范
- 2025年中考化学易错类型:物质检验 鉴别 除杂 分离“五大”易错防范(解析版)
- 福建省泉州市语文小升初试卷及答案指导(2024-2025学年)
评论
0/150
提交评论