《C++面向對象程序設計》譚浩強剖析課件_第1頁
《C++面向對象程序設計》譚浩強剖析課件_第2頁
《C++面向對象程序設計》譚浩強剖析課件_第3頁
《C++面向對象程序設計》譚浩強剖析課件_第4頁
《C++面向對象程序設計》譚浩強剖析課件_第5頁
已閱讀5頁,還剩53頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

C++語言設計

第一章C++的初步知識青島理工大學呂秀艷參考教材選用教材

《C++面向對象程序設計》譚浩強參考教材《C++Primer》中文版StanleyB.lippman

著【C++程序設計課程安排】1.

C++語言特點。2.C++語言語法、C++程序設計示例。3.上機實驗(16/48學時)1.1從C到C++

C語言是結構化和模塊化的語言,C程序的設計者必須細致地設計程序中的每個細節,準確地考慮程序運行時每一時刻發生的事情,當程序規模變大時,結構化程序設計就顯得力不從心。 為了解決軟件設計危機,在20世紀80年代提出了面向對象的程序設計思想(OOP)在實踐中人們發現C語言使用如此廣泛,如果在它的基礎上發展一種面向對象的語言,一定會讓大眾容易接收這種語言,所以產生了C++。1.1從C到C++AT&T發布的第一個C++編譯系統是一個預編譯器,它把C++代碼轉換成C代碼,然后再用C編譯系統生成目標代碼。1988產生第一個C++編譯系統1989C++2.0類的多重繼承1991C++3.0類的模板

C++4.0異常處理、命名空間1997ANSI發布C++標準1.1從C到C++

C++既可以用于面向過程的結構化程序設計,也可用于面向對象的程序設計。

C++對C的增強體現在兩個方面:

1.對原來的面向過程機制做了擴充。

2.增加了面向對象的機制。 學習C++之后,既可以進行面向對象的程序設計,也可以進行面向過程的程序設計。C++語言C語言※與C語言兼容※是C語言的一個超集※絕大多數C語言代碼無須修改就可以直接在C++程序中使用

※支持面向對象程序設計支持面向過程的程序設計【

C++語言與C語言的關系】7/20/20237【

VisualC++6.0編程開發環境簡介】1.2

最簡單的C++程序例1.1輸出一行字符“ThisisaC++program.”。#include<iostream>//用cout輸出時需要用

//此頭文件usingnamespacestd;//使用命名空間stdintmain(){cout<<"ThisisaC++program.\n";

//上面用C++的方法輸出一行return0;}(1)標準C++規定main函數必須聲明為int類型,如果程序正常運行,向操作系統返回一個零值,否則返回非零值,通常是-1。(2)C++程序中可以用/*…*/做注釋,可以用//做注釋。前者可以做多行注釋,后者只做單行注釋。(3)C++程序中常用cout、cin進行輸出輸入,cout是C++定義的輸出流對象,<<是插入運算符。(4)使用cout、cin需要用頭文件iostream,在程序開始要用#include聲明包含的頭文件。(5)usingnamespacestd;意思是使用命名空間。C++標準庫中的類和函數是在命名空間std中聲明的,因此程序中如用C++標準庫中的有關內容(此時需要用#include命令行),就要用usingnamespacestd;語句聲明。

例1.2求a和b兩個數之和

//求兩數之和#include<iostream>//預處理命令usingnamespacestd;//使用命名空間stdintmain()//主函數首部{//函數體開始inta,b,sum;//定義變量cin>>a>>b;//輸入語句sum=a+b;//賦值語句cout<<"a+b="<<sum<<endl;//輸出語句return0;//如程序正常結束,返回一個零值}例1.3求兩個數中的大數#include<iostream>usingnamespacestd;intmain(){intmax(intx,inty)

;//對max函數作聲明

inta,b,c;cin>>a>>b;c=max(a,b);//調用max函數

cout<<"max="<<c<<endl;return0;}intmax(intx,inty)//定義max函數{intz;if(x>y)z=x;elsez=y;return(z);}例1.4包含類的C++程序#include<iostream>usingnamespacestd;classStudent//聲明一個類,類名為Student{private://以下為類中的私有部分

intnum;//私有變量numintscore;//私有變量scorepublic://以下為類中公用部分

voidsetdata()//定義公用函數setdata{cin>>num;//輸入num的值

cin>>score;}//輸入score的值

voiddisplay()//定義公用函數display{cout<<"num="<<num<<endl;//輸出num的值

cout<<"score="<<score<<endl;};//輸出score的值};//類的聲明結束

Studentstud1,stud2;//定義stud1和stud2為Student類的變量,稱為對象intmain()//主函數首部{stud1.setdata();//調用對象stud1的setdata函數

stud2.setdata();//調用對象stud2的setdata函數

stud1.display();//調用對象stud1的display函數

stud2.display();//調用對象stud1的display函數

return0;}具有類類型的變量稱為對象。Student的對象stud1,stud2具有同樣的結構和特征。在類外調用成員函數時必須在函數名前冠以類的名稱。

為了與C兼容,C++保留了C語言中的一些規定,例如頭文件的文件名,以C語言里頭文件的擴展名是.h,許多C++編譯系統保留了這種擴展名,近年推出的C++編譯系統新版本,推出了一批不帶擴展名的頭文件如iostream,string,cmath等。為了兼容C++仍允許使用帶擴展名的頭文件。由于C語言無命名空間,因此使用帶擴展名的頭文件時不用usingnamespacestd。1.3C++對C的擴充C++既可用于面向過程的程序設計,也可用于面向對象程序設計。C++繼承了C語言提供的絕大部分功能和語法規定,并在此基礎上作了擴充。1.3.1C++的輸入和輸出1.3.2

用const定義常變量1.3.3

函數原型聲明1.3.4

函數的重載1.3.5

函數模板1.3.6

有默認參數的函數1.3.7變量的引用1.3.8內置函數1.3.9作用域運算符1.3.10字符串變量1.3.11動態分配/回收內存運算符1.3.1C++的輸入輸出C++為了方便使用,除了可以利用printf和scanf函數進行輸入和輸出外,還增加了標準輸入流輸出流cin和cout。它們是在頭文件iostream中定義的,標準流是不需要打開文件和關閉文件就能直接操作的流式文件,在此標準輸入流是指從鍵盤上輸入的數據,標準輸出流是指向屏幕輸出的數據流。C++預定義的標準流如表1.2所示。1.3.1C++的輸入輸出1.用cout進行輸出格式:cout<<表達式1[<<表達式2……]功能:由左向右逐個計算表達式的值,將其插入到輸出流cout中。cout必須與輸出運算符<<一起使用,每個<<后跟一個表達式,<<運算符的結合方向是從左向右,所以各個表達式的值按從左到右的順序插入到輸出流中。for(k=1;k<=3;k++)cout<<“k=“<<k<<endl;endl是C++輸出流的常數,在頭文件iostream中定義,代表讓光標換行。在C++中也可以用”\n”控制光標換行。所以輸出語句也可寫成:cout<<“k=“<<k<<“\n”;2.用cin進行輸入格式:cin>>變量1[>>變量2……]>>是C++的提取運算符,表示從標準輸入設備取得數據,賦予其后的變量。從鍵盤輸入數值數據時,兩個數據之間用空格分隔或用回車分隔。inta;floatbcin>>a>>b;從鍵盤輸入2032.45<回車>例1.5cin和cout的使用#include<iostream>usingnamespacestd;intmain(){cout<<"pleaseenteryournameandage:"<<endl;

charname[10];intage;cin>>name;cin>>age;cout<<"yournameis"<<name<<endl;cout<<"yourageis"<<age<<endl;return0;}1.指出下列輸出語句哪些是合法的?cout<<"/*";cout<<"*/";cout<</*"*/"*/;2.下面這段代碼合法嗎?為什么?#include<iostream>usingnamespacestd;intmain(){

intv1=1,v2=3;

cout<<"thesumof"<<v1; <<"and"<<v2; <<"is"<<v1+v2 <<endl; return0;}習題與思考C語言中,用#define定義符號常量:

#definePI3.14159 #defineRa+b

它只是在預編譯時進行字符置換,將標識符置換成表達式或數字。預編譯后,標識符PI,R不再存在。PI,R不是變量,沒有類型,不占用存儲單元,很容易出錯:

inta=1;b=2; #definePI3.14159 #defineRa+b

cout<<PI*R*R;

輸出的不是3.14159*(a+b)*(a+b),而是3.14159*a+b*a+b。 程序因此出錯。1.3.2用const定義常變量C++進行了改進,用const定義常變量。如:

constfloatPI=3.14159;

它定義了常變量PI,有數據類型,占用存儲單元,有地址,可以用指針指向它,只是在程序運行中,此變量的值固定,不能改變。常變量定一旦創建后其值就不能再改變,因此必須對其進行初始化。

constintbufsize=512;inti=42;constintc=i;

constintk;(錯誤)bufsize=530;(錯誤)1.3.3函數原型聲明C++強制規定,如果函數調用的位置在函數定義之前,則在調用函數之前必須實現作函數原型聲明。這一點與C不同,C只是建議,而沒有強制函數聲明的一般形式為: 函數類型函數名(參數表);最后的分號可不能忘了,否則出錯!參數表中可以只指定各個參數的類型,而不指定參數名!函數聲明和定義的示例#include<iostream>usingnamespacestd;floatarea(floatr){returnr*r*3.14159;}//先定義intmain(){floatradius;

cout<<“Pleaseinputradius:“;

cin>>radius;if(radius>0)cout<<area(radius)<<endl;

//再使用return0;}程序可以改為如下形式://求圓面積,將函數聲明和定義分開,在調用函數前先聲明它#include<iostream>usingnamespacestd;floatarea(float);//先聲明intmain(){floatradius;

cout<<“Pleaseinputradius:“;

cin>>radius;if(radius>0)cout<<area(radius)<<endl;

//再使用

return0;}floatarea(floatr)//最后定義{returnr*r*3.14159;}1.3.4

函數的重載(overloading)什么叫重載? 運算符“<<”是左移運算符,在C++中,又作為輸出算符;而“*”是乘法算符,也是指針符號。這種一個標識符有多種含義用途的現象,就叫“重載”(overloading)。如果標識符為運算符,就叫“運算符重載”;如果標識符為函數名,就叫“函數重載”。什么時候用到重載?

用于相類似而又不同的操作。例如,求多個數值的最大數,不同類型的參數,C語言要編寫不同的函數:

intmax1(inta,intb,intc);//3個整形數值求最大值 floatmax2(floata,floatb);//2個實形數值求最大值 longmax3(longa,longb,longc);//3個長整形數值求最大值而C++的做法是重載:將這三個函數名取相同的名字,程序運行時,系統會根據實際參數的不同,調用相近參數的函數:#include<iostream>int

max(inta,intb,intc){if(b>a)a=b;if(c>a)a=c;returna;}floatmax(floata,floatb){if(b>a)a=b;returna;}longmax(longa,longb,longc){if(b>a)a=b;if(c>a)a=c;returna;}voidmain(){inta,b,c,d;floatx,y,z;longm,n,p,q;

cin>>a>>b>>c;

cin>>x>>y;

cin>>m>>n>>p;d=max(a,b,c);

cout<<“int_d=“<<d<<endl;z=max(x,y);

cout<<“float_z=“<<z<<endl;q=max(m,n,p);

cout<<“long_q=“<<q<<endl;}Main函數三次調用max函數,每次實參的個數或類型不同,系統會尋找與之匹配的函數調用。注意:重載函數的參數個數或類型必須至少有其中之一不同,函數返回值類型可以相同也可以不同。但不允許參數個數和類型都相同而只有返回值類型不同。思考重載函數的不便之處在于,對于同名的函數要一個一個地編寫,編碼量很大,怎樣改進?1.3.5

函數模板什么時候使用模板?對于有些相同功能的函數,如果函數形參個數相同,可以用另外的方法來解決,這就是模板(Template)。函數模板的定義形式:

Template<類型參數表>

返回類型函數模板名(數據參數表) {函數模板定義體 }示例:將上述重載示例改為函數模板。#include<iostream>usingnamespacestd;//默認使用std標準庫名

template<typename

T>Tmax(Ta,Tb,Tc)//建立函數模板時,只需要{if(b>a)a=b;//將函數類型、參數類型int

換成T就行。if(c>a)a=c;//即用虛擬的類型名T代替實際的類型returna;}intmain(){inti=8,j=3,k=4,h;longm=1,n=2,p=3,q;h=max(i,j,k);q=max(m,n,p);

cout<<“int_h=“<<h<<endl;

cout<<“long_q=“<<q<<endl;return0;}類型參數可以有多個:template<typenameT1,typenameT2>由此程序可以看到,函數模板比函數重載更方便,但模板只適用于函數的參數個數相同而類型不同,且函數體相同的情況。不滿足這種情況時,就只能使用函數重載。注意1.3.6

有默認參數的函數背景:一般情況下,函數調用時,形參從實參那里取得值。因此要求實參的個數和類型應該與形參相同。但是,有時候,多次調用同一函數時用的是同一實參數,或者調用時還不好確定實參數。C++提供一個簡單的解決辦法,即給參數一默認值。這樣當不提供實參數時,形參就用默認參數作為參數值。示例:有一函數聲明為:

floatarea(floatr=6.5); 調用area函數時,如果不提供實際參數給r,r就以默認數值6.5作為參數頂用area: area();//相當于area(6.5);注意: 1)當有多個參數時,如果只有部分參數有默認值,則指定了默認值的參數必須放在參數表的最右邊,否則出錯。因為實參與形參的結合是從左至右順序進行的,第一個實參必須給第一個形參,第二個實參必須給第二個形參…。1.3.6

有默認參數的函數聲明: voidarea(floatx1,intx2=1,charx3=‘a’);調用:area(1.2,3,‘b’);//形參值全部由實參得到

area(1.2,3);//最后一個參數取自默認值

area(1.2);//最后兩個參數取自默認值area();//出錯,第一個形參沒有實參,也沒有默認值2)一個函數不能既作為重載函數,又作為默認參數函數。因為當調用函數時如果少寫一實際個參數,系統無法判斷是利用重載函數還是利用默認參數函數。1.3.7

變量的引用(reference)什么叫引用?變量的引用就是變量的別名。建立引用的作用,是為一個變量另取一個名字,以便在需要的時候間接地引用該別名。如何使用引用?假如有一個變量a,想給它另取一個別名b,可以這樣寫:

inta;

int&b=a;//聲明b是一個整形變量的引用變量,并且被初始化為a此處&不代表取地址,只是“引用聲明符”。對一個變量聲明一個引用,并不另外開辟內存空間。b和a代表同一個變量單元。引用不是獨立的變量,編譯系統不給它分配存儲單元。因此建立引用只有聲明,沒有定義,只是聲明和某一個變量的關系。1.3.7

變量的引用(reference)聲明了一個變量的引用后,在本函數執行期間,該引用一直與代表的變量相聯系,不能再作為另一個變量的別名。請看如下示例:

inta,b;

int&c=a;

int&c=b;//錯誤,c已經是a的引用,不能再作為另一個變量b的引引用不是獨立的數據類型,它必須與某一種類型的數據相聯系:

int&x;//錯誤,沒有指定x代表哪個變量示例:

#include<iostream> usingnamespacestd;

intmain() {inta=10;

int&b=a; a=a*a;

cout<<“b=“<<b<<endl;return0; }運行結果:b=1001.3.7

變量的引用(reference)將引用作為函數參數:C++之所以增加“引用”,主要是利用它作為函數參數,以彌補函數傳遞參數的不方便的遺憾。也降低了編程難度。將變量名作為實參:這時傳給形參的是變量的值,傳遞是單向的,函數運行時,形參發生變化,并不回傳給實參。因為形參和實參不是同一個存儲單元。請看下面示例:1.3.7

變量的引用(reference)#include<iostream>voidswap(inta,intb){inttemp;temp=a;a=b;b=temp;}voidmain(){inti=3,j=5;swap(i,j);

cout<<i<<“,”<<j<<endl;}運行結果,i,j仍然是3,5。沒有發生交換。傳遞變量的指針:這時傳給形參的是變量的地址,形參得到一個變量的地址,即形參指針變量指向實參變量單元。函數中形參發生改變,實際上是改變實參。這種方法實際上仍然是值傳遞:想指針變量傳遞地址值。然后通過指針變量訪問有關變量?!伴g接地”回傳了改變的變量。請看下面示例:1.3.7

變量的引用(reference)#include<iostream>voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidmain(){inti=3,j=5;swap(&i,&j);

cout<<i<<“,”<<j<<endl;}運行結果,i,j是5,3。變量值發生交換。傳遞變量的別名:將變量的引用作為函數形參,彌補了上面兩種方法的不足。請看下面示例: 注意:swap函數形參&a,&b是指定整形變量的引用作為形參,但引用誰還沒定。而main函數中,用一,i,j的名調用swap,就是將i,j的名字傳給引用,這樣a就成立i的別名,b就成立j的別名。1.3.7

變量的引用(reference)#include<iostream>voidswap(int&a,int&b){inttemp;temp=a;a=b;b=temp;}voidmain(){inti=3,j=5;swap(i,j);

cout<<i<<“,”<<j<<endl;}運行結果,i,j是5,3。變量值發生交換。對引用的說明:不能建立void類型的引用。因為任何實際存在的變量都屬于非void類型。void&a=9;//錯誤不能對數組名進行引用,因為數組名只代表數組首地址,本身不是變量不占有存儲空間。

charc[6]=“hello”; char&r=c;//錯誤可以建立指針變量的引用:

inti=5;

int*p=&i;//定義指針變量p,指向i

int*&t=p;//t是指向整形變量的指針變量的引用,初始化為p.1.3.7

變量的引用(reference)可以將引用的地址賦給指針。此時,指針指向原來變量:

inta=3;

int&b=a;

int*p=&b;//指針p指向變量a的引用b,相當與指向a不能定義指向引用類型的指針變量:

int&*p=&a;//錯誤可以用常量或表達式對引用初始化,但必須用const限定:

constint&c=3;//合法1.3.7

變量的引用(reference)引入原因:目的是為了解決程序中函數調用的效率問題。 函數調用時需要時間和空間的代價。

1.3.8

內聯函數(inlinefunction)main(){statement;

fun1();statement;}fun1(){statement;fun2();statement;return;}fun2(){statement;return;}保存返回地址及當前現場恢復函數main的現場,取得返回地址保存返回地址及當前現場恢復函數fun1的現場,取得返回地址函數調用的執行過程而有時一些函數代碼很短(1~5行),卻有高使用頻率,造成處理現場的開銷巨增。 這時若將函數體嵌入函數調用處,則可避免每次調用函數的開銷,大大提高效率。1.3.8

內聯函數(inlinefunction)在聲明一個函數時,加上限定詞inline,該函數就成為內聯函數。編譯時,系統將調用此函數的地方用函數的原代碼替換。即以空間代價換取時間。例如: #include<iostream.h>

inline

int

power(intx)//定義一個內聯函數 {returnx*x;} voidmain() {cout<<power(2)<<endl;//編譯系統展開為{x=2;x*x;}

cout<<power(1+2)<<endl;//編譯系統展開為{x=1+2;x*x;} }運行結果: 4 9內聯函數還有限制:函數內不能含有循環結構或switch結構;不能含有任何靜態數據及數組聲明。不能是遞歸函數。1.3.8

內聯函數(inlinefunction)標識符只能在說明它或定義它的范圍內是可見的,而在該范圍之外是不可見的。大多數標識符的說明與定義是一致的,只有少數例外。如:函數等。范圍有大有小:程序—〉文件—〉函數—〉塊每一個變量都有自己的有效范圍。我們只能在變量的作用域內使用該變量。不能直接使用其它作用域中的變量。如果要使用其它作用域中的同名變量,必須使用“作用域運算符”,即“::”。1.3.9

作用域運算符

示例:

#include<iostream.h> floata=1.5; voidmain() {inta=5;

cout<<a<<endl;//輸出作用域為main函數的局部變量a的值

cout<<::a<<endl;//輸出作用域為全局的全局變量a的值 }運行結果:51.5注意:不能用作用域運算符“::”訪問函數中的局部變量。1.3.9

作用域運算符局部變量和全局變量1、局部變量是指作用域在函數級和塊級的變量。2、全局變量是指作用域在程序級和文件級的變量。#include<iostream.h>inti(5);

//外部全局變量externvoidfunc(){cout<<i<<endl;}voidmain(){

inti=3;//內部局部變量

func();

cout<<i<<endl;}局部變量全局變量藍色為文件作用域綠色為函數作用域1.3.10

字符串變量

C++除了可以使用C語言提供的字符型變量和字符型數組外,還提供了字符串類。這種類可以定義字符串對象。但在文件開頭必須包含string庫:#include<string>字符串定義:

strings1;

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論