版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
傳智播客C++課程講義
傳智掃地僧1、C++對C的擴(kuò)展1簡單的C++程序1.1求圓的周長和面積數(shù)據(jù)描述:半徑,周長,面積均用實型數(shù)表示數(shù)據(jù)處理:輸入半徑r;計算周長=2*n*r:計算面積=n?ノ:輸出半徑,周長,面積;方法1:用結(jié)構(gòu)化方法編程,求圓的周長和面積//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:用面向?qū)ο蠓椒ň幊蹋髨A的周長和面積
分析“圓”是抽象的類類型華徑?建立具體的圓(對象)I圓的周長?面積?分析圓類成員變量半徑成員函數(shù)置半徑值求圓的半徑求周長求面積#include<iostream.h>usingnamestd;classCircle{doubleradius;〃成員變量public:〃類的訪問控制voidSet_Radius(doubler){radius=r;}〃成員函數(shù)doubleGet_Radius(){returnradius;}〃通過成員函數(shù)設(shè)置成員變量doubleGet_Girth() {return2*3.14f*radius;}〃通過成員函數(shù)獲取成員變量doubleGet_Area() {return3.14f*radius*radius;}};voidmain()(CircleA,B;〃用類定義對象A.Set_Radius(6.23);〃類的調(diào)用cout?"A.Radius="?A.GetRadius()?endl;cout?"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;總結(jié):建立類、對象、成員變量、成員函數(shù),輸入輸入流基本概念。1.2初學(xué)者易犯錯誤模型//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;總結(jié):從內(nèi)存四區(qū)的角度,解釋為什么會出現(xiàn)亂碼理解為什么需要成員函數(shù)2程序設(shè)計方法的發(fā)展歷程面向過程的結(jié)構(gòu)化程序設(shè)計方法?設(shè)計思路?自頂向下、逐步求精。采用模塊分解與功能抽象,自頂向下、分而治之。?程序結(jié)構(gòu):按功能劃分為若干個基本模塊,形成一個樹狀結(jié)構(gòu)。各模塊間的關(guān)系盡可能簡單,功能上相對獨立;每一模塊內(nèi)部均是由順序、選擇和循環(huán)三種基本結(jié)構(gòu)組成。其模塊化實現(xiàn)的具體方法是使用子程序。?優(yōu)點:有效地將一個較復(fù)雜的程序系統(tǒng)設(shè)計任務(wù)分解成許多易于控制和處理的子任務(wù),便于開發(fā)和維護(hù)。?缺點:可重用性差、數(shù)據(jù)安全性差、難以開發(fā)大型軟件和圖形界面的應(yīng)用軟件把數(shù)據(jù)和處理數(shù)據(jù)的過程分離為相互獨立的實體。當(dāng)數(shù)據(jù)結(jié)構(gòu)改變時,所有相關(guān)的處理過程都要進(jìn)行相應(yīng)的修改。每ー種相對于老問題的新方法都要帶來額外的開銷。圖形用戶界面的應(yīng)用程序,很難用過程來描述和實現(xiàn),開發(fā)和維護(hù)也都很困難。面向?qū)ο蟮姆椒?將數(shù)據(jù)及對數(shù)據(jù)的操作方法封裝在ー起,作為ー個相互依存、不可分離的整體ーー對象。對同類型對象抽象出其共性,形成類。類通過一個簡單的外部接口,與外界發(fā)生關(guān)系。對象與對象之間通過消息進(jìn)行通信。面向?qū)ο蟮幕靖拍顚ο笠话阋饬x上的對象:是現(xiàn)實世界中一個實際存在的事物。可以是有形的(比如一輛汽車),也可以是無形的(比如一項計劃)。是構(gòu)成世界的一個獨立單位,具有?靜態(tài)特征:可以用某種數(shù)據(jù)來描述?動態(tài)特征:對象所表現(xiàn)的行為或具有的功能?面向?qū)ο蠓椒ㄖ械膶ο螅菏窍到y(tǒng)中用來描述客觀事物的ー個實體,它是用來構(gòu)成系統(tǒng)的ー個基本單位。對象由一組屬性和一組行為構(gòu)成。屬性:用來描述對象靜態(tài)特征的數(shù)據(jù)項。行為:用來描述對象動態(tài)特征的操作序列。類?分類ーー人類通常的思維方法?分類所依據(jù)的原則ーー抽象?忽略事物的非本質(zhì)特征,只注意那些與當(dāng)前目標(biāo)有關(guān)的本質(zhì)特征,從而找出事物的共性,把具有共同性質(zhì)的事物劃分為ー類,得出ー個抽象的概念。?例如,石頭、樹木、汽車、房屋等都是人們在長期的生產(chǎn)和生活實踐中抽象出的概念。?面向?qū)ο蠓椒ㄖ械?I類"具有相同屬性和服務(wù)的ー組對象的集合為屬于該類的全部對象提供了抽象的描述,包括屬性和行為兩個主要部分。類與對象的關(guān)系:猶如模具與鑄件之間的關(guān)系,ー個屬于某類的對象稱為該類的ー個實例。封裝也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進(jìn)行信息隱藏。把對象的屬性和服務(wù)結(jié)合成一個獨立的系統(tǒng)單元。盡可能隱蔽對象的內(nèi)部細(xì)節(jié)。對外形成一個邊界(或者說一道屏障),只保留有限的對外接口使之與外部發(fā)生聯(lián)系。繼承對于軟件復(fù)用有著重要意義,是面向?qū)ο蠹夹g(shù)能夠提高軟件開發(fā)效率的重要原因之一。定義:特殊類的對象擁有其一般類的全部屬性與服務(wù),稱作特殊類對一般類的繼承。例如:將輪船作為ー個一般類,客輪便是ー個特殊類。多態(tài)多態(tài)是指在一般類中定義的屬性或行為,被特殊類繼承之后,可以具有不同的數(shù)據(jù)類型或表現(xiàn)出不同的行為。這使得同一個屬性或行為在一般類及其各個特殊類中具有不同的語義。面向?qū)ο蟮能浖こ堂嫦驅(qū)ο蟮能浖こ淌敲嫦驅(qū)ο蠓椒ㄔ谲浖こ填I(lǐng)域的全面應(yīng)用。它包括:面向?qū)ο蟮姆治觯ī?。A)面向?qū)ο蟮脑O(shè)計(00D)面向?qū)ο蟮木幊蹋∣OP)面向?qū)ο蟮臏y試(00T)面向?qū)ο蟮能浖S護(hù)(〇。SM)總結(jié):面向過程程序設(shè)計:數(shù)據(jù)結(jié)構(gòu)+算法主要解決科學(xué)計算問題,用戶需求簡單而固定特點:分析解決問題所需要的步驟利用函數(shù)實現(xiàn)各個步驟依次調(diào)用函數(shù)解決問題問題:軟件可重用性差軟件可維護(hù)性差構(gòu)建的軟件無法滿足用戶需求面向?qū)ο蟪绦蛟O(shè)計:由現(xiàn)實世界建立軟件模型將現(xiàn)實世界中的事物直接映射到程序中,可直接滿足用戶需求特點:直接分析用戶需求中涉及的各個實體在代碼中描述現(xiàn)實世界中的實體在代碼中關(guān)聯(lián)各個實體協(xié)同工作解決問題優(yōu)勢:構(gòu)建的軟件能夠適應(yīng)用戶需求的不斷變化直接利用面向過程方法的優(yōu)勢而避開其劣勢3C語言和C++語言關(guān)系c語言是在實踐的過程中逐步完善起來的沒有深思熟慮的設(shè)計過程使用時存在很多“灰色地帶”殘留量過多低級語言的特征直接利用指針進(jìn)行內(nèi)存操作C語言的目標(biāo)是高效最終程序執(zhí)行效率的高效當(dāng)面向過程方法論暴露越來越多的缺陷的時候,業(yè)界開始考慮在工程項目中引入面向?qū)ο蟮脑O(shè)計方法,而第一個需要解決的問題就是:髙效的面向?qū)ο笳Z言,并且能夠兼容已經(jīng)存在的代碼。C語言+面向?qū)ο蠓椒ㄕ?==》ObjectiveC/C++C語言和C++并不是對立的競爭關(guān)系C++是C語言的加強(qiáng),是一種更好的C語言C++是以C語言為基礎(chǔ)的,并且完全兼容C語言的特性 學(xué)習(xí)C++并不會影響原有的C語言知識,相反會根據(jù)加深對C的認(rèn)知:學(xué)習(xí)C++可以接觸到更多的軟件設(shè)計方法,并帶來更多的機(jī)會。C++是一種更強(qiáng)大的C,通過學(xué)習(xí)C++能夠掌握更多的軟件設(shè)計方法C++是Java/C#/D等現(xiàn)代開發(fā)語言的基礎(chǔ),學(xué)習(xí)C++后能夠快速掌握這些語言3)C++是各大知名軟件企業(yè)挑選人才的標(biāo)準(zhǔn)之一4C++對C的カ口強(qiáng)namespace命名空間C++命名空間基本常識所謂namespace,是指標(biāo)識符的各種可見范圍。C++標(biāo)準(zhǔn)程序庫中的所有標(biāo)識符都被定義于ー個名為std的namespace中。一:<iostream>和<iostream.h>格式不一樣,前者沒有后綴,實際上,在你的編譯器include文件夾里面可以看到,二者是兩個文件,打開文件就會發(fā)現(xiàn),里面的代碼是不ー樣的。后綴為.h的頭文件C++標(biāo)準(zhǔn)己經(jīng)明確提出不支持了,早些的實現(xiàn)將標(biāo)準(zhǔn)庫功能定義在全局空間里,聲明在帶.h后綴的頭文件里,C++標(biāo)準(zhǔn)為了和C區(qū)別開,也為了正確使用命名空間,規(guī)定頭文件不使用后綴.h。因此,1)當(dāng)使用<iostream.h>時,相當(dāng)于在c中調(diào)用庫函數(shù),使用的是全局命名空間,也就是早期的C++實現(xiàn);2)當(dāng)使用<iostream>的時候,該頭Z件沒有定義余局命名空間,必須使用namespacestd;這樣才能正確使用COUto二:由于namespace的概念,使用C++標(biāo)準(zhǔn)程序庫的任何標(biāo)識符時,可以有三種選擇:1、直接指定標(biāo)識符。例如std::ostream而不是ostream。完整語句如下:std::cout?std::hex?3.4?std::endl;2、使用using關(guān)鍵字。usingstd::cout;usingstd::endl;usingstd::cin;以上程序可以寫成cout?std::hex?3.4?endl;3、最方便的就是使用usingnamespacestd;例如:usingnamespacestd;這樣命名空間std內(nèi)定義的所有標(biāo)識符都有效(曝光)。就好像它們被聲明為全局變量ー樣。那么以上語句可以如下寫:cout?hex?3.4?endl;因為標(biāo)準(zhǔn)庫非常的龐大,所以程序員在選擇的類的名稱或函數(shù)名時就很有可能和標(biāo)準(zhǔn)庫中的某個名字相同。所以為了避免這種情況所造成的名字沖突,就把標(biāo)準(zhǔn)庫中的一切都被放在名字空間std中。但這又會帶來了一個新問題。無數(shù)原有的C++代碼都依賴于使用了多年的偽標(biāo)準(zhǔn)庫中的功能,他們都是在全局空間下的。所以就有了<iostream.h>和<iostream>等等這樣的頭文件,ー個是為了兼容以前的C++代碼,ー個是為了支持新的標(biāo)準(zhǔn)。命名空間std封裝的是標(biāo)準(zhǔn)程序庫的名稱,標(biāo)準(zhǔn)程序庫為了和以前的頭文件區(qū)別,一般不加"ホ"C++命名空間定義及使用語法/*在C++中,名稱(name)可以是符號常量、變量、宏、函數(shù)、結(jié)構(gòu)、枚舉、類和對象等等。為了避免,在大規(guī)模程序的設(shè)計中,以及在程序員使用各種各樣的C++庫時,這些標(biāo)識符的命名發(fā)生沖突,標(biāo)準(zhǔn)C++引入了關(guān)鍵字namespace(命名空間/名字空間/名稱空間/名域),可以更好地控制標(biāo)識符的作用域。*/std是C++標(biāo)準(zhǔn)命名空間,C++標(biāo)準(zhǔn)程序庫中的所有標(biāo)識符都被定義在std中,比如標(biāo)準(zhǔn)庫中的尖iostream>vector等都定義在該命名空間中,使用時要加上using聲明(usingnamespacestd)或using指示(如std::string、std::vector<int>).*//*C中的命名空間在C語言中只有一個全局作用域C語言中所有的全局標(biāo)識符共享同一個作用域標(biāo)識符之間可能發(fā)生沖突C++中提出了命名空間的概念命名空間將全局作用域分成不同的部分不同命名空間中的標(biāo)識符可以同名而不會發(fā)生沖突命名空間可以相互嵌套全局作用域也叫默認(rèn)命名空間7C++命名空間的定義:namespacename{...}*/C++命名空間的使用:使用整個命名空間:usingnamespacename;使用命名空間中的變量:usingname::variable;使用默認(rèn)命名空間中的變量:::variable默認(rèn)情況下可以直接使用默認(rèn)命名空間中的所有標(biāo)識符3C++命名空間編程實踐namespaceNameSpaceA{inta=0;}namespaceNameSpaceB{inta=1;namespaceNameSpaceC(structTeacher(charname[10];intage;};))intmain()(usingnamespaceNameSpaceA;usingNameSpaceB::NameSpaceC::Teacher;printf("a=%d\n',a);printfC'a=%d\n,NameSpaceB::a);NameSpaceB::NameSpaceC::Teachert2Teachertl={“aaa”,3};printf(,=%s\n”,);printf〈tl.age=%d\n*,tl.age);systemC,pause,z);return0;4結(jié)論1)當(dāng)使用くiostream>的時候,該頭文件沒有定義全局命名空間,必須使用namespacestd;這樣才能正確使用cout。若不引入usingnamespacestd,需要這樣做。std::coutoC++標(biāo)準(zhǔn)為了和C區(qū)別開,也為了正確使用命名空間,規(guī)定頭文件不使用后綴.h°C++命名空間的定義:namespacename{...}usingnamespaceNameSpaceA;namespce定義可嵌套。“實用性”增加#include"iostream*'usingnamespacestd;〃(1語言中的變量都必須在作用域開始的位置定義!!〃C++中更強(qiáng)調(diào)語言的“實用性”,所有的變量都可以在需要使用時再定義。intmainll(){inti=0;printf("ddd");intk;system("pauseH);return0;register關(guān)鍵字增強(qiáng)“register關(guān)鍵字請求編譯器讓變量a直接放在寄存器里面,速度快〃在c語言中register修飾的變量不能取地址,但是在C++里面做了內(nèi)容/*//Iregister關(guān)鍵字的變化register關(guān)鍵字請求“編譯器”將局部變量存儲于寄存器中C語言中無法取得register變量地址在C++中依然支持register關(guān)鍵字C++編譯器有自己的優(yōu)化方式,不使用register也可能做優(yōu)化C++中可以取得register變量的地址//2C++編譯器發(fā)現(xiàn)程序中需要取register變量的地址時,register對變量的聲明變得無效。//3早期C語言編譯器不會對代碼進(jìn)行優(yōu)化,因此register變量是一個很好的補(bǔ)充。ツintmain22(){registerinta=0;printf("&a=%x\n",&a);system("pause");return0;}其他補(bǔ)充:請閱讀《register關(guān)鍵字常識課外閱讀.docx》變量檢測增強(qiáng)/*在c語言中,重復(fù)定義多個同名的全局變量是合法的在C++中,不允許定義多個同名的全局變量C語言中多個同名的全局變量最終會被鏈接到全局?jǐn)?shù)據(jù)區(qū)的同一個地址空間上intg_var;intg_var=1;C++直接拒絕這種二義性的做法。*/intmain(intargc,char*argv[])(printf("g_var=%d\n",g_var);return0;}struct類型加強(qiáng)struct類型的加強(qiáng):C語言的struct定義了一組變量的集合,C編譯器并不認(rèn)為這是ー種新的類型C++中的struct是ー個新類型的定義聲明structStudentcharname[100];intage;};intmain(intargc,char*argv[])(Studentsi={"wang",1};Students2={Mwang2",2};return0;C++中所有的變量和函數(shù)都必須有類型/*C++中所有的變量和函數(shù)都必須有類型C語言中的默認(rèn)類型在C++中是不合法的函數(shù)f的返回值是什么類型,參數(shù)又是什么類型?函數(shù)g可以接受多少個參數(shù)?*/〃更換成.cpp試試f(i){printf("i=%d\n",i);|g()(return5;}intmain(intargc,char*argv[])(f(10);printf("g()=%d\n",g(l,2,3,4,5));getchar();return0;總結(jié):/*在c語言中intf():表示返回值為int,接受任意參數(shù)的函數(shù)intf(void);表示返回值為int的無參函數(shù)在C++中intf();和intf(void)具有相同的意義,都表示返回值為int的無參函數(shù)*/C++更加強(qiáng)調(diào)類型,任意的程序元素都必須顯示指明類型-4.6屬于語法級別的增強(qiáng)。新增Bool類型關(guān)鍵字C++中的布爾類型C++在C語言的基本類型系統(tǒng)之上增加了boolC++中的bool可取的值只有true和false理論上boo!只占用ー個字節(jié),如果多個bool變量定義在ー起,可能會各占ー個bit,這取決于編譯器的實現(xiàn)true代表真值,編譯器內(nèi)部用1來表示false代表非真值,編譯器內(nèi)部用。來表示bool類型只有true(非〇)和false(0)兩個值C++編譯器會在賦值時將非0值轉(zhuǎn)換為true,0值轉(zhuǎn)換為falseintmain(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);b=-4;a=b;printf("a=%d,b=%d\n”,a,b);a=10;b=a;printf("a=%d,b=%d\n"za,b);b=0;printf("b=%d\n",b);system("pause");return0;三目運算符功能增強(qiáng)1三目運算符在C和C++編譯器的表現(xiàn)intmain()(inta=10;intb=20;〃返回一個最小數(shù)并且給最小數(shù)賦值成3〃三目運算符是ー個表達(dá)式,表達(dá)式不可能做左值(a<b?a:b)=30;printf("a=%d,b=%d\n",azb);system("pausen);return0;2結(jié)論c語言返回變量的值C++語言是返回變量本身c語言中的三目運算符返回的是變量值,不能作為左值使用C++中的三目運算符可直接返回變量本身,因此可以出現(xiàn)在程序的任何地方2)注意:三目運算符可能返回的值中如果有一個是常量值,則不能作為左值使用(a<b?1:b)=30;3)C語言如何支持類似C++的特性呢?====>當(dāng)左值的條件:要有內(nèi)存空間;C++編譯器幫助程序員取了一個地址而已思考:如何讓C中的三目運算法當(dāng)左值呢?5C/C++中的const1const基礎(chǔ)知識(用法、含義、好處)intmain()(constinta;intconstb;constint*c;int*constd;constint*conste;return0;}Intfuncl(const)初級理解:const是定義常量==》const意味著只讀含義:〃第一個第二個意思ー樣代表ー個常整形數(shù)〃第三個c是ー個指向常整形數(shù)的指針(所指向的內(nèi)存數(shù)據(jù)不能被修改,但是本身可以修改)〃第四個d常指針(指針變量不能被修改,但是它所指向內(nèi)存空間可以被修改)〃第五個e一個指向常整形的常指針(指針和它所指向的內(nèi)存空間,均不能被修改)Const好處〃合理的利用const,〃1指針做函數(shù)參數(shù),可以有效的提高代碼可讀性,減少bug;//2清楚的分清參數(shù)的輸入和輸出特性intsetTeacher_err(constTeacher*p)Const修改形參的時候,在利用形參不能修改指針?biāo)虻膬?nèi)存空間2c中“冒牌貨”intmain(){constinta=10;int*p=(int*)&a;printf("a===>%d\n',/a);*P=H;printf("a===>%d\n"/a);printf("Hello……\n");return0;解釋:C++編譯器對const常量的處理當(dāng)碰見常量聲明時,在符號表中放入常量=つ問題:那有如何解釋取地址編譯過程中若發(fā)現(xiàn)使用常量則直接以符號表中的值替換編譯過程中若發(fā)現(xiàn)對const使用了extern或者&操作符,則給對應(yīng)的常量分配存儲空間(兼容C)?聯(lián)想:int&a=l(err)&constint&a=10(ok)?C++中const符號表原理圖C++編譯器雖然可能為const常量分配空間,但不會使用其存儲空間中的值。結(jié)論;C語言中的const變量C語言中const變量是只讀變量,有自己的存儲空間C++中的const常量可能分配存儲空間,也可能不分配存儲空間當(dāng)const常量為全局,并且需要在其它文件中使用當(dāng)使用&操作符取const常量的地址3const和#define相同之處〃練習(xí)解釋為什么//ftdefineN10intmain()(constinta=1;constintb=2;intarray[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修飾的常量編譯期間,就已經(jīng)確定下來了。4const和#define的區(qū)別對比加深C++中的const常量類似于宏定義constintc=5;=#definec5C++中的const常量與宏定義不同const常量是由編譯器處理的,提供類型檢查和作用域檢查宏定義由預(yù)處理器處理,單純的文本替換〃在funcl定義a,在func2中能使用嗎?〃在fund中定義的b,在func2中能使用嗎?練習(xí)voidfunl()(#definea10constintb=20;//#undefa#undef}voidfun2()(printf("a=%d\n",a);//printf("b=%d\n",b);)intmain()funl();fun2();return0;5結(jié)論C語言中的const變量C語言中const變量是只讀變量,有自己的存儲空間C++中的const常量可能分配存儲空間,也可能不分配存儲空間當(dāng)const常量為全局,并且需要在其它文件中使用,會分配存儲空間當(dāng)使用&操作符,取const常量的地址時,會分配存儲空間當(dāng)constint&a=10;const修飾引用時,也會分配存儲空間6引用專題講座1引用(普通引用)變量名回顧變量名實質(zhì)上是一段連續(xù)存儲空間的別名,是ー個標(biāo)號(門牌號)程序中通過變量來申請并命名內(nèi)存空間通過變量的名字可以使用存儲空間問題1:對一段連續(xù)的內(nèi)存空間只能取一個別名嗎?1引用概念a)在C++中新增加了引用的概念b)引用可以看作一個已定義變量的別名c)引用的語法:Type&name=var;d)引用做函數(shù)參數(shù)那?(引用作為函數(shù)參數(shù)聲明時不進(jìn)行初始化)voidmain01()(inta=10;〃c編譯器分配4個字節(jié)內(nèi)存。。。a內(nèi)存空間的別名int&b=a;〃b就是a的別名。。。a=11;〃直接賦值{int*p=&a;*P=12;printf("a%d\n",a);)b=14;printf("a:%db:%d",a,b);system(Hpause");}2引用是C++的概念屬于C++編譯器對c的擴(kuò)展問題:C中可以編譯通過嗎?intmain()(inta=0;int&b=a;//int*constb=&ab=11;//*b=11;return0;} 結(jié)論:請不要用C的語法考慮b=ll3引用做函數(shù)參數(shù)普通引用在聲明時必須用其它的變量進(jìn)行初始化,引用作為函數(shù)參數(shù)聲明時不進(jìn)行初始化 〃05復(fù)雜數(shù)據(jù)類型的引用structTeacher(charname[64];intage;};voidprintfT(Teacher*pT)(cout?pT->age?endl;}〃pT是tl的別名,相當(dāng)于修改了tlvoidprintfT2(Teacher&pT)(//cout?pT.age?endl;pT.age=33;〃pT和tl的是兩個不同的變量voidprintfT3(TeacherpT)(cout?pT.age?endl;pT.age=45;〃只會修改pT變量,不會修改tl變量}voidmain()(Teachertl;tl.age=35;printfT(&tl);printfT2(tl);〃pT是tl的別名printf("tl.age:%d\n",tl.age);//33printfT3(tl);〃pT是形參,tlcopy一份數(shù)據(jù)給pT〃ー〉pT二tlprintf("tl.age:%d\n",tl.age);//35cout?"hello..."?endl;system("pause,,);return;4引用的意義1)引用作為其它變量的別名而存在,因此在ー些場合可以代替指針2)引用相對于指針來說具有更好的可讀性和實用性Eintswapl(intint&b)(intt=a;a=b;b=t;return0;)5引用本質(zhì)思考思考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);〃請思考:對同一內(nèi)存空間可以取好幾個名字嗎?system("pause*);return0;2 單獨定義的引用時,必須初始化;說明很像ー個常量思考2:普通引用有自己的空間嗎?structTeacer{int&a;int&b;};intmain()(printf(*sizeof(Teacher)%d\n”,sizeof(Teacer));system("pause");return0;2 引用是?個有地址,引用是常量。。。。。char*constp6引用的本質(zhì)1)引用在C++中的內(nèi)部實現(xiàn)是ー個常指針Type&nameW-Type*constname2)C++編譯器在編譯過程中使用常指針作為引用的內(nèi)部實現(xiàn),因此引用所占用的空間大小與指針相同。3)從使用的角度,引用會讓人誤會其只是ー個別名,沒有自己的存儲空間。這是C++為了實用性而做出的細(xì)節(jié)隱藏voidfunc(int&a) voidfunc(int*consta)a=5; *a=5Intmain(){intx=10;func(x);)4)請仔細(xì)對比間接賦值成立的三個條件1定義兩個變量(ー個實參ー個形參)2建立關(guān)聯(lián)實參取地址傳給形參3*p形參去間接的修改實參的值フ引用結(jié)論1)引用在實現(xiàn)上,只不過是把:間接賦值成立的三個條件的后兩步和二為ー〃當(dāng)實參傳給形參引用的時候,只不過是C++編譯器幫我們程序員手工取了一個實參地址,傳給了形參引用(常量指針)2)當(dāng)我們使用引用語法的時,我們不去關(guān)心編譯器引用是怎么做的當(dāng)我們分析奇怪的語法現(xiàn)象的時,我們オ去考慮C++編譯器是怎么做的8函數(shù)返回值是引用(引用當(dāng)左值)C++引用使用時的難點:當(dāng)函數(shù)返回值為引用時若返回棧變量不能成為其它引用的初始值不能作為左值使用若返回靜態(tài)變量或全局變量可以成為其他引用的初始值即可作為右值使用,也可作為左值使用C++鏈?zhǔn)骄幊讨校?jīng)常用到引用,運算符重載專題返回值是基礎(chǔ)類型,當(dāng)引用intgetAAl()inta;a=10;returna;〃基礎(chǔ)類型a返回的時候,也會有一個副本int&getAA2()(inta;a=10;returna;}int*getAA3()(inta;a=10;return&a;)返回值是static變量,當(dāng)引用“static修飾變量的時候,變量是ー個狀態(tài)變量intj()staticinta=10;a++;printf("a:%d\n",a);returna;|int&jl()(staticinta=10;a++;printf("a:%d\n“,a);returna;}int*j2()(staticinta=10;a++;printf("a:%d\n“,a);return&a;|voidmain22(){〃出的運算結(jié)果是一個數(shù)值,沒有內(nèi)存地址,不能當(dāng)左值。。。。。//II=100;//*(a>b?&a:&b)=lll;〃當(dāng)被調(diào)用的函數(shù)當(dāng)左值的時候,必須返回一個引用。。。。。jl()=100;〃編譯器幫我們打造了環(huán)境jl{);*02())=200;〃相當(dāng)于我們程序員手工的打造做左值的條件j2();system("pause");返回值是形參,當(dāng)引用intgl(int*p)(*p=100;return*p;}int&g2(int*p)//(*p=100;return*p;〃當(dāng)我們使用引用語法的時候,我們不去關(guān)心編譯器引用是怎么做的〃當(dāng)我們分析亂碼這種現(xiàn)象的時候,我們才去考慮C++編譯器是怎么做的。。。。voidmain23()(intal=10;al=g2(&al);int&a2=g2(&al);〃用引用去接受函數(shù)的返回值,是不是亂碼,關(guān)鍵是看返回的內(nèi)存空間是不是被編譯器回收了。。。。printf("al:%d\n",al);printf("a2:%d\n",a2);system(Hpause");返回值非基礎(chǔ)類型structTeachar(charname[64];intage;};〃如果返回引用不是基礎(chǔ)類型,是ー個類,那么情況非常賦值。。涉及到copy構(gòu)造函數(shù)和=操作重載,拋磚。。。。structTeachar(charname[64];intage;};〃如果返回引用不是基礎(chǔ)類型,是ー個類,那么情況非常賦值。。涉及到copy構(gòu)造函數(shù)和=操作重載,拋磚。。。。structTeachar&OpTeacher(structTeachar&tl)(}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;*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("pauseH);}2常引用下面開始進(jìn)入const引用難點!使用變量初始化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;〃只能用指針來改變了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(,zpause");return0;I 案例2:voidmain41()(inta=10;constint&b=a;〃const引用使用變量a初始化a=11;//b=12;〃通過引用修改a,對不起修改不了system("pause");)structTeacherl(charname[64];intage;);voidprintTe2(constTeacherl*constpt)(}“const引用讓變量(所指內(nèi)存空間)擁有只讀屬性voidprintTe(constTeacherl&t)(//t.age=11;)voidmain42()(Teacherl11;11.age=33;printTe(tl);system("pause");2使用字面量常量初始化const引用思考:1、用變量對const引用初始化,const引用分配內(nèi)存空間了嗎?2、用常量對const引用初始化,const引用分配內(nèi)存空間了嗎?voidmain0(constintb=10;printf(*b:%d*,&b);//int&al=19;如果不加const編譯失敗constint&a=19;printfC*&a:%d\n”,&a);system("pause");3綜合案例voidmain(){〃普通引用inta=10;int&b=a;〃常量引用:讓變量引用只讀屬性constint&c=a;〃常量引用初始化分為兩種//I用變量初始化常量引用{intx=20;constint&y=x;printf("y:%d\n",y);}//2用常量初始化常量引用{〃int&m=10;〃引用是內(nèi)存空間的別名字面量10沒有內(nèi)存空間沒有方法做引用constint&m=10;)cout?"hello..."?endl;system("pause");return;3const引用結(jié)論1)Const&inte相當(dāng)于constint*conste2)普通引用相當(dāng)于int*constel3)當(dāng)使用常量(字面量)對const引用進(jìn)行初始化時,C++編譯器會為常量值分配空間,并將引用名作為這段空間的別名4)使用字面量對const引用初始化后,將生成一個只讀變量4const修飾類后續(xù)課程介紹5綜合練習(xí)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;7C++對C的函數(shù)擴(kuò)展1inline內(nèi)聯(lián)函數(shù)C++中的const常量可以替代宏常數(shù)定義,如:constintA=3;#defineA3C++中是否有解決方案替代宏代碼片段呢?(替代宏代碼片段就可以避免宏的副作用!)C++中推薦使用內(nèi)聯(lián)函數(shù)替代宏代碼片段C++中使用inline關(guān)鍵字聲明內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)聲明時inline關(guān)鍵字必須和函數(shù)定義結(jié)合在ー起,否則編譯器會直接忽略內(nèi)聯(lián)請求?!ê晏鎿Q和函數(shù)調(diào)用區(qū)別#include"iostream"usingnamespacestd;#defineMYFUNC(a,b)((a)<(b)?(a):(b))inlineintmyfunc(inta,intb)(returna<b?a:b;intmain()(inta=1;intb=3;//intc=myfunc(++azb);〃頭疼系統(tǒng)intc=MYFUNC(++a/b);printf("a=%d\n”,a);printf("b=%d\n",b);printf("c=%d\n"zc);system("pause");return0;說明1:必須inlineintmyfunc(inta,intb)和函數(shù)體的實現(xiàn),寫在ー塊說明2C++編譯器可以將一個函數(shù)進(jìn)行內(nèi)聯(lián)編譯被C++編譯器內(nèi)聯(lián)編譯的函數(shù)叫做內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)在最終生成的代碼中是沒有定義的C++編譯器直接將函數(shù)體插入在函數(shù)調(diào)用的地方內(nèi)聯(lián)函數(shù)沒有普通函數(shù)調(diào)用時的額外開銷(壓棧,跳轉(zhuǎn),返回)說明3:C++編譯器不一定準(zhǔn)許函數(shù)的內(nèi)聯(lián)請求!說明4內(nèi)聯(lián)函數(shù)是ー種特殊的函數(shù),具有普通函數(shù)的特征(參數(shù)檢查,返回類型等)內(nèi)聯(lián)函數(shù)是對編譯器的ー種請求,因此編譯器可能拒絕這種請求內(nèi)聯(lián)函數(shù)由編譯器處理,直接將編譯后的函數(shù)體插入調(diào)用的地方宏代碼片段由預(yù)處理器處理,進(jìn)行簡單的文本替換,沒有任何編譯過程說明5:現(xiàn)代C++編譯器能夠進(jìn)行編譯優(yōu)化,因此ー些函數(shù)即使沒有inline聲明,也可能被編譯器內(nèi)聯(lián)編譯另外,ー些現(xiàn)代C++編譯器提供了擴(kuò)展語法,能夠?qū)瘮?shù)進(jìn)行強(qiáng)制內(nèi)聯(lián)如:g++中的_attribute_((always_inline))屬性說明6:C++中內(nèi)聯(lián)編譯的限制:不能存在任何形式的循環(huán)語句不能存在過多的條件判斷語句函數(shù)體不能過于龐大不能對函數(shù)進(jìn)行取址操作函數(shù)內(nèi)聯(lián)聲明必須在調(diào)用語句之前編譯器對于內(nèi)聯(lián)函數(shù)的限制并不是絕對的,內(nèi)聯(lián)函數(shù)相對于普通函數(shù)的優(yōu)勢只是省去了函數(shù)調(diào)用時壓棧,跳轉(zhuǎn)和返回的開銷。因此,當(dāng)函數(shù)體的執(zhí)行開銷遠(yuǎn)大于壓棧,跳轉(zhuǎn)和返回所用的開銷時,那么內(nèi)聯(lián)將無意義。結(jié)論:1)內(nèi)聯(lián)函數(shù)在編譯時直接將函數(shù)體插入函數(shù)調(diào)用的地方2)inline只是ー種請求,編譯器不一定允許這種請求3)內(nèi)聯(lián)函數(shù)省去了普通函數(shù)調(diào)用時壓棧,跳轉(zhuǎn)和返回的開銷2默認(rèn)參數(shù)/*1C++中可以在函數(shù)聲明時為參數(shù)提供ー個默認(rèn)值,當(dāng)函數(shù)調(diào)用時沒有指定這個參數(shù)的值,編譯器會自動用默認(rèn)值代替*!voidmyPrint(intx=3)(printf("x/d",x);}/*2函數(shù)默認(rèn)參數(shù)的規(guī)則只有參數(shù)列表后面部分的參數(shù)才可以提供默認(rèn)參數(shù)值一旦在一個函數(shù)調(diào)用中開始使用默認(rèn)參數(shù)值,那么這個參數(shù)后的所有參數(shù)都必須使用默認(rèn)參數(shù)值*/〃默認(rèn)參數(shù)voidprintAB(intx=3)(printf(”x:%d\n”,x);}〃在默認(rèn)參數(shù)規(guī)則,如果默認(rèn)參數(shù)出現(xiàn),那么右邊的都必須有默認(rèn)參數(shù)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函數(shù)占位參數(shù)函數(shù)占位參數(shù)占位參數(shù)只有參數(shù)類型聲明,而沒有參數(shù)名聲明一般情況下,在函數(shù)體內(nèi)部無法使用占位參數(shù)Vintfunc(inta,intb,int)(returna+b;intmain01()(〃func(l,2);〃可以嗎?printf("func(l,2,3)=%d\n”,func(l,2,3));getchar();return0;}4默認(rèn)參數(shù)和占位參數(shù)可以將占位參數(shù)與默認(rèn)參數(shù)結(jié)合起來使用意義為以后程序的擴(kuò)展留下線索兼容c語言程序中可能出現(xiàn)的不規(guī)范寫法*/〃C++可以聲明占位符參數(shù),占位符參數(shù)一般用于程序擴(kuò)展和對C代碼的兼容intfunc2(inta,intb,int=0){returna+b;|voidmain()(〃如果默認(rèn)參數(shù)和占位參數(shù)在ー起,都能調(diào)用起來func2(lz2);func2(l,2,3);system("pause,,);結(jié)論:〃如果默認(rèn)參數(shù)和占位參數(shù)在ー起,都能調(diào)用起來5函數(shù)重載(Overroad)函數(shù)重載概念1函數(shù)重載概念函數(shù)重載(FunctionOverload)用同一個函數(shù)名定義不同的函數(shù)當(dāng)函數(shù)名和不同的參數(shù)搭配時函數(shù)的含義不同2函數(shù)重載的判斷標(biāo)準(zhǔn)/*函數(shù)重載至少滿足下面的一個條件:參數(shù)個數(shù)不同參數(shù)類型不同參數(shù)順序不同*/3函數(shù)返回值不是函數(shù)重載的判斷標(biāo)準(zhǔn)實驗1:調(diào)用情況分析;實驗2:判斷標(biāo)準(zhǔn)〃兩個難點:重載函數(shù)和默認(rèn)函數(shù)參數(shù)混搭重載函數(shù)和函數(shù)指針/*intfunc(intx){returnx;}intfunc(inta,intb)(returna+b;}intfunc(constchar*s){returnstrlen(s);}intmain(){intc=0;c=func⑴;printf("c=%d\n",c);c=func(l,2);printf("c=%d\n",c);c=func("12345H);printf("c=%d\n",c);printf("Pressentertocontinuegetchar();return0;}*/函數(shù)重載的調(diào)用準(zhǔn)則~F~編譯器調(diào)用重載函數(shù)的準(zhǔn)則將所有同名函數(shù)作為候選者嘗試尋找可行的候選函數(shù)精確匹配實參通過默認(rèn)參數(shù)能夠匹配實參通過默認(rèn)類型轉(zhuǎn)換匹配實參匹配失敗最終尋找到的可行候選函數(shù)不唯一,則出現(xiàn)二義性,編譯失敗。無法匹配所有候選者,函數(shù)未定義,編譯失敗。7/*函數(shù)重載的注意事項重載函數(shù)在本質(zhì)上是相互獨立的不同函數(shù)(靜態(tài)鏈編)重載函數(shù)的函數(shù)類型是不同的函數(shù)返回值不能作為函數(shù)重載的依據(jù)函數(shù)重載是由函數(shù)名和參數(shù)列表決定的。V函數(shù)重載是發(fā)生在一個類中里面函數(shù)重載遇上函數(shù)默認(rèn)參數(shù)〃當(dāng)函數(shù)默認(rèn)參數(shù)遇上函數(shù)重載會發(fā)生什么/*intfunc(inta,intb,intc=0)(returna*b*c;}intfuncfinta,intb)(returna+b;}//!個參數(shù)的允許嗎intfuncfinta)(returna+b;}intmain(){intc=0;c=func(l,2);〃存在二義性,調(diào)用失敗,編譯不能通過printf("c=%d\n"/c);printf("Pressentertocontinuegetchar();return0;}*/函數(shù)重載和函數(shù)指針結(jié)合/*函數(shù)重載與函數(shù)指針當(dāng)使用重載函數(shù)名對函數(shù)指針進(jìn)行賦值時根據(jù)重載規(guī)則挑選與函數(shù)指針參數(shù)列表一致的候選者嚴(yán)格匹配候選者的函數(shù)類型與函數(shù)指針的函數(shù)類型*//*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(l);printf("c=%d\n",c);printf("Pressentertocontinuegetchar();return0;}*/函數(shù)重載、重寫、重定義后續(xù)課程。8附錄附錄1:C++語言對C語言擴(kuò)充和增強(qiáng)的幾點具體體現(xiàn)在c語言塊注釋的形式/*IxplanationSentence*/的基礎(chǔ)上,C+?語言提供了一種新的單行注釋形式://ExplanationSentence即用“〃”表示注理開始>從該位置直到當(dāng)前行結(jié)束的所有字符都被作為注釋?舉個簡單的例子:/*下面的程序般計範(fàn)從1到100的整數(shù)和,結(jié)果記錄在支Itfs中sum=0:〃變量ヌum初值査為零for(i=1;i<=100;i++)<〃〇!環(huán)體開始sum+=i;/Z儂次累加1.更加靈活的變量說明在傳統(tǒng)的C語言中,局部變量的說明必須集中放在執(zhí)行代碼的前面,數(shù)據(jù)說明語句和執(zhí)行語句的混合將引起黃譯博誤?而在C++中,可以在程序代觸的任何地方進(jìn)行局部變量的說明.比如下面的代碼在C語言中是不正命的,在C+?語咅中卻可以正常運行.fortinti=1;i<=100;i++);這禪做的好處是使變量的定義和它的使用集中在ー起,意義一目了然..更加嚴(yán)格的函數(shù)原型說明C++痛棄了C語言對函數(shù)原型隨意簡化的方式,這種簡化是許多C語言程序錯誤的艮源.C++語言要求編程者カ函數(shù)提供完整的原型,包括全部參數(shù)的類型和返回值得說明.例如,有字符型和雙精度類型兩個參數(shù)、返回整型值的函數(shù)3原型應(yīng)該石為:intf(char,double);而ciS高中允詳將這個原型寫成"f();,在函數(shù)原型說明中,參數(shù)名可有可無,并且可以和函數(shù)定義中的參數(shù)名不一致..増加了函數(shù)重裁機(jī)制重我是程序語言領(lǐng)域的重要槪念.常規(guī)遇害中最典型的例子是"+、ー、X、/"等各種算術(shù)運篁符的重藪,這改符號可以同時用來表示多種類型數(shù)?之間的運算,這腫對ー個名字或ー個符號聯(lián)子多重意義的情況就叫重我.C+?語言増加了C語言所沒有的函數(shù)重羲機(jī)制.對ー個函數(shù)名可以給出多個函數(shù)定義,只要這些定義可以通過分?jǐn)?shù)個數(shù)或類型的不同區(qū)別開來即可.C++還允許對系燒中我先定義的運算符號迸行重載,増加新的定義.這律做的優(yōu)點是在今后對新定義莫型的變量進(jìn)行運算時,計”公式寫起來方便自然..函數(shù)駅省參數(shù)C++中允許函數(shù)有読?、す數(shù).所謂駅省,是指函數(shù)調(diào)用時可以不給出實標(biāo)的參數(shù)值.下面是一個有載香參數(shù)的函數(shù)定義的實例:intf(int?,intb=l)(returnk*b;}此后,函數(shù)調(diào)用f(3,1)和f(3)將返回同樣的結(jié)果..輸入/給岀流機(jī)制C+?保ア了C語言標(biāo)準(zhǔn)庫中各種給入/輸出函數(shù),而且提供了一套新的輪入/輸出機(jī)制ーー流機(jī)制.比如向標(biāo)準(zhǔn)輸出輸出ー個字符串:coutくく“C++isb??utifull或者由標(biāo)権輸入讀ー個整數(shù),歐給變量,inta;cin?a;流式給入/協(xié)出運算符能夠根據(jù)變量尖型自動確定數(shù)格交換過程中的轉(zhuǎn)柒方式,還可以定義“くく》’的重我,方便了編程者自定義類型的數(shù)據(jù)的給入/箱出..作用ぽ限定運算符::作用域限定運篁符::用于對當(dāng)前作用域之外的同名變量進(jìn)行訪問.例如在下面的例子中,我們可以利用實現(xiàn)在局部變量?的作用城范圍內(nèi)對全局變量啲訪問?^includeくioHretmh>xnt■:voidmtinO{floata;a=3.14;:6;coutくく"localvariablea二"くくaくく,ndl;coutくく“globalvariabl?a="くく::aくくむ31;)程序執(zhí)行結(jié)果如下:localvariablea=3.14globalvariablea=6附錄2:C語言register關(guān)鍵字ー最快的關(guān)鍵字register:這個關(guān)鍵字請求編譯器盡可能的將變量存在CPU內(nèi)部寄存器中,而不是通過內(nèi)存尋址訪問,以提髙效率。注意是盡可能,不是絕對。你想想,一個CPU的寄存器也就那么幾個或幾十個,你要是定義了很多很多register變量,它累死也可能不能全部把這些變量放入寄存器吧,輪也可能輪不到你。ー、皇帝身邊的小太監(jiān)一一ー寄存器不知道什么是寄存器?那見過太監(jiān)沒有?沒有?其實我也沒有。沒見過不要緊,見過就麻煩大了。二、大家都看過古裝戲,那些皇帝們要閱讀奏章的時候,大臣總是先將奏章交給皇帝旁邊的小太監(jiān),小太監(jiān)呢再交給皇帝同志處理。這個小太監(jiān)只是個中轉(zhuǎn)站,并無別的功能。好,那我們再聯(lián)想到我們的CPU〇CPU不就是我們的皇帝同志么?大臣就相當(dāng)于我們的內(nèi)存,數(shù)據(jù)從他這拿出來。那小太監(jiān)就是我們的寄存器了(這里先不考慮CPU的高速緩存區(qū))。數(shù)據(jù)從內(nèi)存里拿出來先放到寄存器,然后CPU再從寄存器里讀取數(shù)據(jù)來處理,處理完后同樣把數(shù)據(jù)通過寄存器存放到內(nèi)存里,CPU不直接和內(nèi)存打交道。這里要說明的ー點是:小太監(jiān)是主動的從大臣手里接過奏章,然后主動的交給皇帝同志,但寄存器沒這么自覺,它從不主動干什么事。一個皇帝可能有好些小太監(jiān),那么ー個CPU也可以有很多寄存器,不同型號的CPU擁有寄存器的數(shù)量不一樣。為啥要這么麻煩啊?速度!就是因為速度。寄存器其實就是ー塊ー塊小的存儲空間,只不過其存取速度要比內(nèi)存快得多。進(jìn)水樓臺先得月嘛,它離CPU很近,CPU一伸手就拿到數(shù)據(jù)了,比在那么大的ー塊內(nèi)存里去尋找某個地址上的數(shù)據(jù)是不是快多了?那有人問既然它速度那么快,那我們的內(nèi)存硬盤都改成寄存器得了唄。我要說的是:你真有錢!二、舉例register修飾符暗示編譯程序相應(yīng)的變量將被頻繁地使用,如果可能的話,應(yīng)將其保存在CPU的寄存器中,以加快其存儲速度。例如下面的內(nèi)存塊拷貝代碼,#ifdefNOSTRUCTASSIGNmemcpy(d,s,1)registerchar*d;registerchar*s;registerinti;while(i--)*d++=*s++;Sendif三、使用register修飾符的注意點但是使用register修飾符有幾點限制。首先,register變量必須是能被CPU所接受的類型。這通常意味著register變量必須是ー個單個的值,并且長度應(yīng)該小于或者等于整型的長度?不過,有些機(jī)器的寄存器也能存放浮點數(shù)。其次,因為register變量可能不存放在內(nèi)存中,所以不能用“&”來獲取register變量的地址。由于寄存器的數(shù)量有限,而且某些寄存器只能接受特定類型的數(shù)據(jù)(如指針和浮點數(shù)),因此真正起作用的register修飾符的數(shù)目和類型都依賴于運行程序的機(jī)器,而任何多余的register修飾符都將被編譯程序所忽略。在某些情況下,把變量保存在寄存器中反而會降低程序的運行速度。因為被占用的寄存器不能再用于其它目的:或者變量被使用的次數(shù)不夠多,不足以裝入和存儲變量所帶來的額外開銷。早期的C編譯程序不會把變量保存在寄存器中,除非你命令它這樣做,這時register修飾符是C語言的一種很有價值的補(bǔ)充。然而,隨著編譯程序設(shè)計技術(shù)的進(jìn)步,在決定那弊變量應(yīng)該被存到寄存器中時,現(xiàn)在的C編譯環(huán)境能比程序員做出更好的決定。實際上,許多編譯程序都會忽略register修飾符,因為盡管它完全合法,但它僅僅是暗示而不是命令。9作業(yè)及強(qiáng)化訓(xùn)練!復(fù)雜數(shù)據(jù)類型引用做函數(shù)參數(shù)分析內(nèi)存四區(qū)變化圖2代碼敲一遍3設(shè)計ー個類,求圓形的周長4設(shè)計ー個學(xué)生類,屬性有姓名和學(xué)號,可以給姓名和學(xué)號賦值可以顯示學(xué)生的姓名和學(xué)號2、類和對象1前言C++學(xué)習(xí)技術(shù)路線及目標(biāo)研究C++編譯器管理類和對象的方法===》避免死角C++編譯器對類對象的生命周期管理,對象創(chuàng)建、使用、銷毀C++面向?qū)ο竽P统跆紺++面向?qū)ο蠖鄳B(tài)原理探究操作符重載C++基礎(chǔ)課程學(xué)習(xí)完畢以后,有沒有一個標(biāo)準(zhǔn),來判斷自己有沒有入門。面向抽象類(接口)編程1視角2具體路線1個對象的生命周期2個對象的生命周期類和類之間的關(guān)系classA含有一個classBn個對象的生命周期一族對象C??面向編程思想工具.?面向觸象類編程(面向接口ノ軟件分層)2類和對象2.I基本概念1)類、對象、成員變量、成員函數(shù)2)面向?qū)ο笕蟾拍罘庋b、繼承、多態(tài)3)編程實踐類的定義和對象的定義,對象的使用求圓形的面積定義Teacher類,打印Teacher的信息(把類的聲明和類的實現(xiàn)分開)2.2類的封裝1)封裝(Encapsulation)A)封裝,是面向?qū)ο蟪绦蛟O(shè)計最基本的特性。把數(shù)據(jù)(屬性)和函數(shù)(操作)合成ー個整體,這在計算機(jī)世界中是用類與對象實現(xiàn)的。B)封裝,把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進(jìn)行信息隱藏。備注:有2層含義(把屬性和方法進(jìn)行封裝對屬性和方法進(jìn)行訪問控制)C++中類的封裝成員變量,C++中用于表示類屬性的變量成員函數(shù),C++中用于表示類行為的函數(shù)2)類成員的訪問控制在C++中可以給成員變量和成員函數(shù)定義訪問級別Public修飾成員變量和成員函數(shù)可以在類的內(nèi)部和類的外部被訪問Private修飾成員變量和成員函數(shù)只能在類的內(nèi)部被訪問〃類是把屬性和方法封裝同時對信息進(jìn)行訪問控制〃類的內(nèi)部,類的外部〃我們抽象了一個類,用類去定義對象〃類是ー個數(shù)據(jù)類型,類是抽象的〃對象是ー個具體的變量。。占用內(nèi)存空間。classCircle{public:doubler;doubles;public:doublegetR()(a++;returnr;}voidsetR(doubleval){r=val;}public:doublegetS()〃增加功能時,是在修改類,修改類中的屬性或者是方法(s=3.14f*r*r;returns;}//private:
inta;struct和class關(guān)鍵字區(qū)別在用struct定義類時,所有成員的默認(rèn)屬性為public在用class定義類時,所有成員的默認(rèn)屬性為privateC++面向?qū)ο蟪绦蛟O(shè)計舉例目標(biāo):面向過程向面向?qū)ο笏枷朕D(zhuǎn)變初學(xué)者要仔細(xì)體會類和對象之間的關(guān)系,并通過適當(dāng)練習(xí)鞏固和提髙!案例1設(shè)計立方體類(cube),求出立方體的面積和體積求兩個立方體,是否相等(全局函數(shù)和成員函數(shù))案例2設(shè)計ー個圓形類(AdvCircle),和一個點類(Point),計算點在圓內(nèi)部還是圓外即:求點和圓的關(guān)系(圓內(nèi)和圓外)案例3對于第二個案例,類的聲明和類的實現(xiàn)分開作業(yè)作業(yè)1:編寫C++程序完成以下功能:1)定義ー個Point類,其屬性包括點的坐標(biāo),提供計算兩點之間距離的方法;2)定義一個圓形類,其屬性包括圓心和半徑:3)創(chuàng)建兩個圓形對象,提示用戶輸入圓心坐標(biāo)和半徑,判斷兩個圓是否相交,并輸出結(jié)果。作業(yè)2:設(shè)計并測試ー個名為Rectangle的矩形類,其屬性為矩形的左下角與右上角兩個點的坐標(biāo),根據(jù)坐標(biāo)能計算出矩形的面積作業(yè)3:定義ー個!ree類,有成員ages(樹齡),成員函數(shù)grow(intyears)對ages加上years,age()顯示tree對象的ages的值。3對象的構(gòu)造和析構(gòu)前言創(chuàng)建一個對象時,常常需要作某些初始化的工作,例如對數(shù)據(jù)成員賦初值。注意,類的數(shù)據(jù)成員是不能在聲明類時初始化的。為了解決這個問題,C++編譯器提供了構(gòu)造函數(shù)(constructor)來處理對象的初始化。構(gòu)造函數(shù)是ー種特殊的成員函數(shù),與其他成員函數(shù)不同,不需要用戶來調(diào)用它,而是在建立對象時自動執(zhí)行。3.1構(gòu)造和析構(gòu)函數(shù)!構(gòu)造函數(shù)和析構(gòu)函數(shù)的概念有關(guān)構(gòu)造函數(shù)1構(gòu)造函數(shù)定義及調(diào)用1)C++中的類可以定義與類名相同的特殊成員函數(shù),這種與類名相同的成員函數(shù)叫做構(gòu)造函數(shù):2)構(gòu)造函數(shù)在定義時可以有參數(shù);3)沒有任何返回類型的聲明。2構(gòu)造函數(shù)的調(diào)用自動調(diào)用:一般情況下C++編譯器會自動調(diào)用構(gòu)造函數(shù)手動調(diào)用:在ー些情況下則需要手工調(diào)用構(gòu)造函數(shù)有關(guān)析構(gòu)函數(shù)3)析構(gòu)函數(shù)定義及調(diào)用1)C++中的類可以定義ー個特殊的成員函數(shù)清理對象,這個特殊的成員函數(shù)叫做析構(gòu)函數(shù)語法:?ClassName。2)析構(gòu)函數(shù)沒有參數(shù)也沒有任何返回類型的聲明3)析構(gòu)函數(shù)在對象銷毀時自動被調(diào)用4)析構(gòu)函數(shù)調(diào)用機(jī)制C++編譯器自動調(diào)用代碼演示:dm01_構(gòu)造函數(shù)的基礎(chǔ).卬p2C++編譯器構(gòu)造析構(gòu)方案PK對象顯示初始化方案設(shè)計構(gòu)造函數(shù)和析構(gòu)函數(shù)的原因面向?qū)ο蟮乃枷胧菑纳钪衼?手機(jī)、車出廠時,是ー樣的。生活中存在的對象都是被初始化后オ上市的;初始狀態(tài)是對象普遍存在的一個狀態(tài)的普通方案:為每個類都提供ー個public的initialize函數(shù);對象創(chuàng)建后立即調(diào)用initialize函數(shù)進(jìn)行初始化。優(yōu)缺點分析initialize只是ー個普通的函數(shù),必須顯示的調(diào)用一旦由于失誤的原因,對象沒有初始化,那么結(jié)果將是不確定的沒有初始化的對象,其內(nèi)部成員變量的值是不定的3)不能完全解決問題 〃為什么對象需要初始化有什么樣的初始化方案#include"iostream"usingnamespacestd;/*思考為什么需要初始化面向?qū)ο笏枷雭碜陨?手機(jī)、車、電子產(chǎn)品,出廠時有初始化怎么樣進(jìn)行初始化?方案1:顯示調(diào)用方法缺點:易忘、麻煩;顯示調(diào)用init,不能完全解決問題*/classTest21(public:intm;intgetM()const{returnm;}voidsetM(intval){m=val;}intn;intgetN()const{returnn;}voidsetN(intval){n=val;}public:intinit(intmjntn)this->m=m;this->n=n;return0;)protected:private:};intmain()(intrv=0;Test21tl;〃無參構(gòu)造函數(shù)的調(diào)用方法Test2112;//tl.init(100,200);//t2.init(300,400);cout?tl.getM()?""?tl.getN()?endl;cout?t2.getM()?""?t2.getN()?endl;〃定義對象數(shù)組時,沒有機(jī)會進(jìn)行顯示初始化Test21arr[3];//Testarr_2[3]={Test(l,3),Test。,Test()};system("pauseH);returnrv;}構(gòu)造函數(shù)的分類及調(diào)用C++編譯器給程序員提供的對象初始化方案,高端大氣上檔次?!ㄓ袇?shù)構(gòu)造函數(shù)的三種調(diào)用方法classTest(private:inta;intb;public:〃無參數(shù)構(gòu)造函數(shù)Test()〃帶參數(shù)的構(gòu)造函數(shù)Test(inta,intb)〃賦值構(gòu)造函數(shù)Test(constTest&obj){)public:voidinit(int_a,int_b){a=_a;b=_b;)};!無參數(shù)構(gòu)造函數(shù)調(diào)用方法:Testtl,t2;2有參構(gòu)造函數(shù)有參構(gòu)造函數(shù)的三種調(diào)用方法〃有參數(shù)構(gòu)造函數(shù)的三種調(diào)用方法classTests(private:inta;public:〃帶參數(shù)的構(gòu)造函數(shù)Test5(inta)(printf("\na:%d"za);)Test5(inta,intb)printf("\na:%db:%d",a,b);public:intmain55()(Test5tl(10);〃c++編譯器默認(rèn)調(diào)用有參構(gòu)造函數(shù)括號法Test512=(20,10);〃c++編譯器默認(rèn)調(diào)用有參構(gòu)造函數(shù)等號法TestSt3:TestS(30);〃程序員手工調(diào)用構(gòu)造函數(shù)產(chǎn)生了一個對象直接調(diào)用構(gòu)造構(gòu)造函數(shù)法systemf'pause");return0;3拷貝構(gòu)造函數(shù)調(diào)用時機(jī)賦值構(gòu)造函數(shù)的四種調(diào)用場景(調(diào)用時機(jī))第1和第2個調(diào)用場景#include"iostream”usingnamespacestd;classAA(public:AA()〃無參構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù)(cout<(”我是構(gòu)造函數(shù),自動被調(diào)用了"<<endl;}AA(int_a)〃無參構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù)(a=_a;)AA(constAA&obj2)(cout<<”我也是構(gòu)造函數(shù),我是通過另外一個對象obj2,來初始化我自己”"endl;a=obj2.a+10;)?AA()(cout<<”我是析構(gòu)函數(shù),自動被調(diào)用了”"endl;}voidgetA()printf("a:%d\n”,a);)protected:private:inta;};〃單獨搭建一個舞臺voidObjPlay01()(AAal;〃變量定義〃賦值構(gòu)造函數(shù)的第一個應(yīng)用場景〃用對象1初始化對象2AAa2=al;〃定義變量并初始化〃初始化法a2=al;〃用al來=號給a2編譯器給我們提供的淺copy}第二個應(yīng)用場景〃單獨搭建一個舞臺voidObjPlay02()(AAal(10);〃變量定義〃賦值構(gòu)造函數(shù)的第一個應(yīng)用場景〃用對象1初始化對象2AAa2(al);〃定義變量并初始化〃括號法〃a2=al;〃用al來=號給a2編譯器給我們提供的淺copya2.getA();}〃注意:初始化操作和等號操作是兩個不同的概念第3個調(diào)用場景include"iostream"usingnamespacestd;classLocation(public:Location(intxx=0,intyy=0)(X=xx;Y=yy;cout?"ConstructorObject.\n";)Location(constLocation&p)〃拷貝構(gòu)造函數(shù){X=p.X;Y=p.Y;cout?"Copy_constructorcalled,"?endl;)~Location(){cout?X? ?Y?"Objectdestroyed."?endl;}intGetX(){returnX;}intGetY(){returnY;}private:intX,Y;);//alt+f8排版voidf(Locationp){cout?"Funtion:"?p.GetX()? ?p.GetY()?endl;}voidmainobjplayO(LocationA(1,2)J〃形參是ー個元素,函數(shù)調(diào)用,會執(zhí)行實參變量初始化形參變量f(A);}voidmain()(mainobjplayO;system("pause");}第4個調(diào)用場景第四個應(yīng)用場景include"iostream"usingnamespacestd;classLocation(public:Location(intxx=0zintyy=0)(X=xx;Y=yy;cout?"ConstructorObject.\n";}Location(constLocation&p) 〃復(fù)制構(gòu)造函數(shù)X=p.X;Y=p.Y;cout?"Copy_constructorcalled."?endl;)?Location。{cout?X?"/*?Y?"Objectdestroyed."?endl;)intGetX(){returnX;}intGetY(){returnY;}private:intX,Y;};//alt+f8排版voidf(Locationp)(cout?"Funtion:"?p.GetX()?","?p.GetY()?endl;)Locationg(){LocationA(l,2);returnA;}〃對象初始化操作和=等號操作是兩個不同的概念〃匿名對象的去和留,關(guān)鍵看,返回時如何接voidmainobjplayO(〃若返回的匿名對象,賦值給另外一個同類型的對象,那么匿名對象會被
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年重慶興發(fā)金冠化工有限公司招聘筆試參考題庫含答案解析
- 2025年貴州能礦錳業(yè)集團(tuán)有限公司招聘筆試參考題庫含答案解析
- 二零二五版門樓建筑室內(nèi)外裝修裝飾工程施工合同2篇
- 2025年魯教五四新版九年級歷史下冊月考試卷含答案
- 2025年岳麓版必修5語文下冊月考試卷含答案
- 2025年重慶云陽縣恐龍世界文化旅游開發(fā)有限公司招聘筆試參考題庫附帶答案詳解
- 二零二五年度嬰幼兒奶粉生產(chǎn)許可證申請及審核合同3篇
- 二零二五版南京琴行教師藝術(shù)教育推廣合同4篇
- 上海市嘉定區(qū)2024-2025學(xué)年九年級上學(xué)期期末語文試題
- 2025年蘇教版七年級物理上冊階段測試試卷含答案
- 回收二手機(jī)免責(zé)協(xié)議書模板
- (正式版)JC∕T 60023-2024 石膏條板應(yīng)用技術(shù)規(guī)程
- 人教版高中生物學(xué)新舊教材知識差異盤點
- (權(quán)變)領(lǐng)導(dǎo)行為理論
- 2024屆上海市浦東新區(qū)高三二模英語卷
- 2024年智慧工地相關(guān)知識考試試題及答案
- YY/T 0681.2-2010無菌醫(yī)療器械包裝試驗方法第2部分:軟性屏障材料的密封強(qiáng)度
- GB/T 8005.2-2011鋁及鋁合金術(shù)語第2部分:化學(xué)分析
- 不動產(chǎn)登記實務(wù)培訓(xùn)教程課件
- 不銹鋼制作合同范本(3篇)
- 2023年系統(tǒng)性硬化病診斷及診療指南
評論
0/150
提交評論