C++程序設(shè)計教程(第二版)第二章基本編程語句概述和性質(zhì)_第1頁
C++程序設(shè)計教程(第二版)第二章基本編程語句概述和性質(zhì)_第2頁
C++程序設(shè)計教程(第二版)第二章基本編程語句概述和性質(zhì)_第3頁
C++程序設(shè)計教程(第二版)第二章基本編程語句概述和性質(zhì)_第4頁
C++程序設(shè)計教程(第二版)第二章基本編程語句概述和性質(zhì)_第5頁
已閱讀5頁,還剩335頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、C + 程序設(shè)計教程(第二版)第二章 基本編程語句概述和性質(zhì) Chapter 2 Basic Programming Statements21:28:351第二章內(nèi)容21:28:352說明語句 ( Declarative Statements ) 條件語句 (Condition Statements ) 循環(huán)語句 ( Loop Statements ) 循環(huán)設(shè)計(Loop Designs )輸入輸出語句( Input/Output Statements ) 轉(zhuǎn)移語句 ( Move Statements ) 再做循環(huán)設(shè)計(More Loop Designs ) 1. 說明語句 ( Declara

2、tive Statements )數(shù)據(jù)說明:求解問題所使用的數(shù)據(jù)是什么性質(zhì),進行什么運算,表達范圍如何,必須預(yù)先說明說明方式: 既要指明其名字,也要指明其是什么類型,還可以順便初始化如: int a; double d = 3.5;說明數(shù)據(jù)的另一個目的是創(chuàng)建一個所需大小的實體空間給該名字,以便存儲所用的數(shù)據(jù)值若數(shù)據(jù)名字沒有說明,使用其便是非法的21:28:353過程(函數(shù))說明:求解中需要通過函數(shù)調(diào)用來實施求解時,便要對函數(shù)的性質(zhì)進行說明,說明其返回類型,參數(shù)類型,參數(shù)個數(shù)函數(shù)說明分函數(shù)聲明和函數(shù)定義兩種: 函數(shù)聲明是說明函數(shù)的名字,函數(shù)的返回類型,以及函數(shù)的參數(shù)和個數(shù)如: double ar

3、ea(double ra); 函數(shù)定義是在函數(shù)聲明的基礎(chǔ)上,對整個實現(xiàn)過程進行詳細定義如: double area(double ra) return ra*ra*3.14; 21:28:354調(diào)用函數(shù)就是使用函數(shù)名字,使用名字前必須清楚名字的性質(zhì),所以必須先對函數(shù)進行聲明運行程序中,會涉及到被調(diào)用函數(shù)的執(zhí)行,所以凡是被調(diào)用的函數(shù)都必須有函數(shù)定義,不管該定義在程序的什么位置如: double sphere(); / 聲明 int main() double result = sphere(); / 調(diào)用 cout“area: ”result“n”; void sphere() / 定義 cou

4、tr; return r*r*3.14; 21:28:355. 條件語句(Condition Statements )if語句的兩種形態(tài):21:28:356語句1條件語句1條件語句2是是否否對應(yīng)語句: if(ab) coutaendl; if(a=b) coutaendl; else coutb0) if(x50) cout”x is ok.n”; else cout0) if(x 50) cout”O(jiān)Kn”; else cout0) if(x 50) cout”O(jiān)Kn”; else cout”NOT OKn”;21:28:359條件表達式:對于 if(x) a = 327981; else

5、b = 327981;可表示為: x ? a=327981 : b=327981;如果a和b為同類型,則還可以: (x?a:b) = 327981;21:28:3510switch多分支語句: switch(整數(shù)表達式) case value1: 語句1; break; case value2: 語句2; break; default: 語句n; 等價于: if(整數(shù)表達式=value1) 語句1; else if(整數(shù)表達式=value2) 語句2; else 語句n; 21:28:3511雖然switch有等價的復(fù)合if表示, 而且,分支判斷值只能是整數(shù),顯得應(yīng)用范圍狹窄, 但是switc

6、h在使用上的直觀和靈活形式, 使得其仍具有編程價值. 如:break可選,甚至case可以重疊: case value1: 語句1; case value2: 語句2; case v1: case v2: case v3: 語句;3. 循環(huán)語句 ( Loop Statements )for循環(huán)結(jié)構(gòu): 21:28:3512開 始循環(huán)初始狀態(tài)循環(huán)體狀態(tài)修正條件判斷未結(jié)束結(jié)束結(jié) 束對應(yīng)語句為: for(int i=1; i=10; i+) cout”hello.n”;21:28:3513循環(huán)初始狀態(tài)條件判斷狀態(tài)修正循環(huán)體每次循環(huán)體執(zhí)行,都改變循環(huán)狀態(tài),直到條件不滿足而終止.如,設(shè)置求和的初始值,交給

7、循環(huán)計算,完成循環(huán)后,輸出求和結(jié)果:int sum = 0;for(int i=1; i=100; i+) sum = sum+i;coutsumendl;21:28:3514循環(huán)開始循環(huán)結(jié)束因為并不是所有循環(huán)都有明顯的循環(huán)初始狀態(tài)和狀態(tài)修正的,所以,while循環(huán)是一種for循環(huán)的簡潔形式.如,同樣的求和:int sum=0, i=1;while(i=100) sum += i+;coutsumendl;21:28:3515循環(huán)開始循環(huán)結(jié)束4. 循環(huán)設(shè)計 ( Loop Designs )(1)簡單字符圖形的雙重循環(huán)MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

8、MMMMMMMMMMMMMMMM21:28:3516分析方法:該圖形一共10行,每一行增加一個字符,所以,應(yīng)循環(huán)10次,每次輸出一行,其循環(huán)模式為:for(int i=1; i=10; +i) 輸出第i行(循環(huán)) 換行行 i M個數(shù) 1 1 1 2 2 2 3 3 3 4 4 4.10 10 1021:28:3517for(int i=1; i=10; +i) for(int j=1; j=i; +j) cout”M”; coutendl;21:28:3518(2)判斷素數(shù):(利用數(shù)學(xué)定律)mij 假定ij, 則 i2ijmj2 即 i2mj2 即 imj bool isPrime(int m

9、) double sqm=sqrt(m*1.0); for(int i=2; i=sqm; +i) if(m%i=0) return false; return true; 21:28:35195. 輸入輸出語句( Input/Output Statements ) 標準輸出流:可以控制輸出格式coutshowpos12; / +12couthex18” “showbase18; / 12 0 x12couthex255” “uppercase255; / ff FFcout3)” “boolalpha3); / 0 falsecoutscientific123456.678; / 1.234

10、568e+0521:28:3520控制寬度和填充字符的操作是帶參數(shù)的,注意width(n)為一次性操作,即第二次顯示時將不再有效。默認為width(0),表示僅顯示數(shù)值。例如:cout.width(5);cout.fill(S);cout2323; / 輸出: SSS2323在頭文件iomanip的支持下,還可以直接由操作:#includecoutsetw(6)setfill($)27endl; / 輸出: $2721:28:3521文件流的輸入出操作與標準輸入出基本相同,只是需要以一定方式打開和關(guān)閉如,將文件打開,逐行讀入字符,輸出到文件: ifstream in(“a.in”); ofst

11、ream out(“a.out”); for(string s; getline(in, s); ) outsendl;其中文件流讀入操作總是伴隨著狀態(tài)返回,判斷狀態(tài)就可以確定文件是否正常讀入,如getline(in,s)當(dāng)讀到文件尾時,便返回false,以使循環(huán)結(jié)束21:28:3522. 轉(zhuǎn)移語句 ( Move Statements ) break除了用在switch之外,主要的是用在終結(jié)本次循環(huán)for(int i; ; ) for( ; ; ) / . if(i=1) break; / . a=1; / .21:28:3523break跳到此處continue一般是用條件判斷執(zhí)行的,通過反

12、條件,可以免去continue的使用,所以,它用來構(gòu)筑良好的程序風(fēng)格 for(int n=100; n=200; +n) if(n%3=0) continue; coutnendl; 免去continue的情形: for(int n=100; n=200; +n) if(n%3!=0) coutnendl; 21:28:3524goto的程序段除了系統(tǒng)跟蹤和架構(gòu)困難外,閱讀也相對復(fù)雜: int a; goto Init; Forward: a = a + 1; Print: coutaendl; goto Down; Init: a = 1; goto Print; Down: if(a100

13、) goto Forward;等價于: for(int i=1; i=100; +i) couti“n”;21:28:3525break語句的可取之處:/ 用break語句的代碼段bool flag=false; / 用于做退出記號for(int i=1; i100; +i) for(int j=1; j100; +j) if(i*j=651) flag=true; break; else / . if(flag) break;/ goto語句的代碼段for(int i=1; i100; +i)for(int j=1; j100; +j) if(i*j=651) goto End; / .En

14、d:21:28:35267. 再做循環(huán)設(shè)計( More Loop Designs ) 邏輯判斷類的語句控制結(jié)構(gòu): for(所有可能情況) / 可為多重循環(huán) if(條件1不滿足) continue; if(條件2不滿足) continue; / if(條件n不滿足) continue; 輸出所要的結(jié)果 21:28:3527百雞問題的例子: for(int c=1; c=13; +c) for(int h=1; h=18; +h) for(int s=1; s=96; +s) if(7*c+5*h+s/3-100) continue; if(c+h+s-100) continue; if(s%3)

15、 continue; coutCock:c , Hens:h , Chicks:100-c-h1e-6; +n) item *= (-1.0)*(2*n-3)/(2*n-1); sum += item;coutPi = “ setiosflags(ios:fixed) sum*4endl;21:28:3530C + 程序設(shè)計教程(第二版)第三章 數(shù)據(jù)類型 Chapter 3 Data Types21:28:3531清華大學(xué)出版社 錢 能數(shù)據(jù)類型:一定的數(shù)據(jù)在計算機的內(nèi)部表示;該數(shù)據(jù)所表示的值的集合;在該數(shù)據(jù)上的一系列操作。內(nèi)部數(shù)據(jù)類型: 1.整型長整型,短整型,字符型,布爾型 2.浮點型單精度

16、,雙精度21:28:3532第三章內(nèi)容21:28:3533 整型 ( int Types ) 整型子類 ( sub-int Types ) 浮點型 ( Floating-Point Type ) C-串與string ( C-string & string ) 數(shù)組 ( Arrays ) 向量 ( vectors ) 指針與引用 ( Pointer & References ) 1. 整型 ( int Types )整型數(shù)的內(nèi)部表示:二進制補碼 位數(shù)既定的二進制補碼運算沒有加減的區(qū)別;對于溢出,只是簡單的舍棄而不是錯誤整型數(shù)的表示范圍:取決于二進制位數(shù)整型數(shù)的操作:+,-,*,/,%,=,!,

17、=,=,=,&,|,&=,|=,&,|,&=,|=,!=,=,+=,-=,*=,/=,%=,+,-,,,? :21:28:3534編譯器的機器字長總是與整型的位長有關(guān)如: 32位編譯器的整型數(shù)一定為32位長整型字面值分八進制,十進制和十六進制不同表示如: 0123 / 8進制 0 x12af3 / 16進制 12345 / 10進制 超過表示范圍的整型數(shù)其值不可預(yù)料或者出錯如: 錯21:28:3535. 整型子類( Sub-int Types )字符型:表示范圍: 有符號:-128127 無符號:0255 輸出形式與整型數(shù)不同: int a = 65; char b = 65; couta“n

18、”; coutb“n”; 結(jié)果為: 65 A 21:28:3536枚舉型: 自定義整數(shù)區(qū)間,甚至列舉單個整數(shù)值 enum Week Mon, Tue, Wed, Thu, Fri, Sat, Sun ; 最大特點是可以給每個值指定一個在程序中直接使用的標記(枚舉符) 編程中將其當(dāng)作整數(shù)常量用如: int a = 7; if ( a = Sun) cout “Sundayn”; 21:28:353721:28:3538布爾型:表示范圍僅含整數(shù)和1,也可以表示成true和false,相當(dāng)于: enum bool false, true ;因為條件表達式、邏輯運算的結(jié)果都是或,所以,相當(dāng)大數(shù)量的表達

19、式的值與布爾型對應(yīng)3. 浮點型 ( Floating-Point Types )浮點數(shù)的內(nèi)部表示: 國際標準IEEE754浮點表示法,它與編程所用的浮點數(shù)字面量以及輸出的十進制浮點數(shù)之間有一個轉(zhuǎn)換關(guān)系浮點數(shù)的表示范圍:32位浮點數(shù)3.41038 64位浮點數(shù)1.810308浮點數(shù)的操作: 常規(guī)的加、減、乘、除等操作21:28:35394. C-串與string ( C-string & string )C-串結(jié)構(gòu)每個字符占據(jù)1個字節(jié)一個C-串是一個字符序列,用來表示各種名字或者文字說明C-串的字符序列的最后總是添加有一個結(jié)束標志.即在6個字符的字串(“Hello!”)其空間存儲有7個字節(jié)左邊三

20、圖是不同細節(jié)的同一空間結(jié)構(gòu)描述21:28:3540Hello!0 72 101 108 108 111 33 0知道了C-串首地址,即可知道整個串,所以可以藉字符首址(字符指針)來操作C-串,但要注意,串的第一個字符與整個串的操作不同,如,C-串的輸出操作: char* str = ”Hello”; cout *str endl; / 顯示H cout str endl; / 顯示Hello21:28:3541C-串不能直接比較,因為字符指針的比較只是地址值的比較而不是C-串的字典序比較: cout(“join”=”join” ? ” : ”not “)”equaln”; / 字面值比較 ch

21、ar* str1=”good”; char* str2=”good”; cout(str1=str2 ? ” : ”not “)”equaln”; / 字符指針比較 char buffer16=”Hello”; char buffer26=”Hello”; cout(buffer1=buffer2 ? ” : ”not “)”equaln”; / 字符數(shù)組比較 結(jié)果:not equal not equal not equal21:28:3542不得不配備專門操作C-串的庫函數(shù):strcpy(s1, s2); /從s2拷貝到s1strcmp(s1, s2); /比較s1與s2strcat(s1,

22、 s2); /連接s2到s1strrev(s); /將s倒排 strset(s, c); /將s全置為cstrstr(s, “ell”); /查找s中的子串strchr(s,c); /查找s中的字符 等等21:28:3543但字符指針操作C-串的安全性受到質(zhì)疑:char* str1;char* str2 = new char5;strcpy(str2, ”ugly”);strcpy(str1,str2); / 錯: str1沒有空間可儲strcpy(str2, ”Hello”); / 錯: str2空間不夠大str2 = ”Hello”; / 錯:原來的”ugly”空間脫鉤,導(dǎo)致內(nèi)存泄漏根源:

23、復(fù)制操作須以足夠的目的地空間為前提,而所有C-串操作的空間調(diào)配都是人為安排的,C-串庫函數(shù)一概不管21:28:3544類串string串類自定義串對應(yīng)字符指針的C-串操作: string a, s1 = Hello ; string s2 = 123; a = s1; / copy cout(a=s1 ? : not)equaln; / compare couta+s2endl; / concatenate reverse(a.begin(), a.end(); coutaendl; / reverse couta.replace(0,9,9,c)endl; / set cout(s1.fin

24、d(ell)!= -1 ? : not )foundn;/ find string cout(s1.find(c)!= -1 ? : not )的讀入方式總是將前導(dǎo)的空格(所謂空格,即包括空格、回車、水平或垂直制表符等)濾掉,將單詞讀入,在遇到空格時結(jié)束本次輸入getline總是將行末的回車符濾掉,將其整行輸入對字串”Hello, How are you?”的兩種輸入方式 for ( string s; cins; ) couts” “; coutendl; string s; getline(cin, s); couts a ; sum += a ) ; cout sum “n” ; 21:

25、28:35475. 數(shù)組( Arrays ) 數(shù)組是同類元素的集合,它的元素排列在連續(xù)的空間中,按下標來標記描述數(shù)組必須給出元素類型,元素個數(shù)元素個數(shù)必須在編程時確定,任何變量都不允許 int aa ; / 表示int a97; int n = 100 ; int an ; / 錯: 元素個數(shù)必須預(yù)知 const int n = 100 ; int an ; / ok int a ; / 錯: 無元素個數(shù) int a = 1, 2, 3, 4, 5 ; / ok:通過初始化確定元素個數(shù)21:28:3548數(shù)組初始化可選,但須遵循語法無初始化的數(shù)組按規(guī)定取默認值 int array15 = 1,

26、 2, 3, 4, 5, 6 ; / 錯: 初始值個數(shù)超元素個數(shù)int array25 = 1, , 2, 3, 4 ; / 錯: 不能以逗號方式省略int array35 = 1, 2, 3, ; / 錯: 同上int array45 = ; / 錯: 初始值不能為空int array55 = 1, 2, 3 ; / ok: 后面元素取0int array65 = 0 ; / ok: 元素全為0int array75 ; / ok: 元素值不確定int a35 = 1, 2, 3, 4, 5 , 2, 3, 4, 5, 6 , 3, 4, 5, 6, 7 ; 21:28:3549數(shù)組有諸多缺

27、陷,造成編程艱難和不安全 int a5 = 1,2,3,4,5, c5; int b5 = a; / 錯:無法拷貝創(chuàng)建 c = a; / 錯:無法整體拷貝和局部拷貝 a8 = 10; / 錯:無法動態(tài)擴容和隨意增減元素 for(int i=0; i=5; +i) / 錯:無法防范下標溢出 ai = i+1; if(a=c) a0 = 2; / 錯:不可比較 int a5 = 1; / 初始化呆板,無法獲得全初值21:28:3550二維數(shù)組的初始化,下標訪問及輸出 int array123=1,2,3,4,5; int array223=1,2,4; coutarray1: ; for(int

28、i=0; i2; +i) for(int j=0; j3; +j) coutarray1ij,; coutnarray2: ; for(int i=0; i2; +i) for(int j=0; j3; +j) coutarray2ij,; coutn;結(jié)果為: array1: 1,2,3,4,5,0, array2: 1,2,0,4,0,0,21:28:3551.向量( vector ) 向量與數(shù)組的共同特征是元素的排列在邏輯上是線性序列結(jié)構(gòu),可以用下標進行訪問 向量可以按需創(chuàng)建,拷貝創(chuàng)建,局部拷貝創(chuàng)建,異類拷貝和創(chuàng)建 靈活的初始化 隨意擴容和元素增減 可通過異常來進行下標溢出追蹤和處理 可

29、比較 等等21:28:3552int n=10;int t5=1,2,3,4,5;vector a(n); /按需創(chuàng)建vector b(10, 1); /元素賦全,靈活的初始化vector c(b); / 整體拷貝創(chuàng)建vector f(t, t+5); /異類拷貝創(chuàng)建vector d(b.begin(), b.begin()+3);/局部拷貝創(chuàng)建d為b的前個元素a.assign(100); /動態(tài)擴容至100個元素21:28:3553向量常用操作a.assign(b.begin(), b.begin()+3); / b的前3個元素賦給aa.assign(4,2); / a向量含4個元素,全初始

30、化為2int x = a.back(); / a的最后一個元素賦給變量xa.clear(); / a向量清空(不再有元素)if(a.empty() cout”empty”; / a判空操作int y = a.front(); / a的第一個元素賦給變量ya.pop_back(); / 刪除a的最后一個元素a.push_back(5); / a最后插入一個元素,其值為5a.resize(10); / a元素個數(shù)調(diào)至10。多刪少補,其值隨機a.resize(10,2);/a元素個數(shù)調(diào)至10。多刪少補,新添元素初值為2if(a=b) cout”equal”; / a與b的向量比較操作21:28:35

31、54向量操作尤其適合于函數(shù)參數(shù)傳遞(-D以上的數(shù)組參數(shù)的傳遞十分丑陋):傳遞一個矩陣,無論其每行中的元素個數(shù)不同.輸出之:typedef vectorvector Mat;void print(const Mat& a) for(int i=0; ia.size(); +i) for(int j=0; jai.size(); +j) coutaij ; coutendl; 21:28:35557. 指針與引用 ( Pointers & Reference ) 指針指向存放數(shù)據(jù)的地址指針必須初始化或者賦值(指向了數(shù)據(jù))后,才能進行間接訪問(間訪)操作int* ip;int iCount = 18

32、;int* iPtr = &iCount; / 初始化ip = &iCount; / 賦值*ip = 8; / 間訪操作21:28:3556指針操作與指向數(shù)據(jù)的類型密切相關(guān) float f = 34.5; int* ip = reinterpret_cast(&f); cout“fAddr: ”&f”f“n”; cout“iAddr: ”ip”*ip“n”; *ip = 100; cout“ int: ”*ip“n”; cout“float: ”f“n”;結(jié)果為: 21:28:3557指針加減整數(shù)的操作表示空間位置上的挪動但是挪動的字節(jié)數(shù)與其數(shù)據(jù)類型相關(guān):對float指針加6實際增加了24個字

33、節(jié)對long int指針加5實際增加了20個字節(jié)對char指針減7實際減少了7個字節(jié)對double指針減2實際減少了16個字節(jié)21:28:3558數(shù)組名本身就是表示元素集合的首地址可以將數(shù)組名賦給指針 int a3; for(int i=0; i3; +i) ai = i*2; for(int* iP=a; iPa+3; iP+=1) coutiP“: ”*iP“n”; 結(jié)果為: 1245036: 0 1245040: 2 1245044: 421:28:3559指針限定const int a = 78;int b = 10;int c = 18;const int* ip = &a; / c

34、onst修飾指向的實體類型常量指針int* const cp = &b; / const修飾指針*cp指針常量int const* dp = &b; / 等價于上一句指針常量const int* const icp = &c; / 常量指針常量*ip = 87; / 錯:常量指針不能修改指向的常量,*ip只能做右值ip = &c; / ok:常量指針可以修改指針值*cp = 81; / ok:指針常量可以修改指向的實體cp = &b; / 錯:指針常量不能修改指針值,即使是同一個地址*icp = 33; / 錯:常量指針常量不能修改指向的常量icp = &b; / 錯:常量指針常量不能修改指針

35、值int d = *icp; / ok21:28:3560引用必須初始化,因為引用總是附屬于某個實體int someInt = 5;int& rInt = someIne; /初始化修改引用的值,即是修改了附屬的實體值int a = 5;int& ra = a;ra = 8;couta“n”;結(jié)果為:8引用多用在函數(shù)參數(shù)的傳遞上21:28:3561C + 程序設(shè)計教程(第二版)第四章 計算表達 Chapter 4 Computational Expressing21:28:3562清華大學(xué)出版社 錢 能計算表達: 表達計算使用一系列操作,它依賴于特定語言的操作符功能,關(guān)乎數(shù)據(jù)類型的內(nèi)在特性,故

36、計算表達目的在于深入剖析數(shù)據(jù)類型對于編程的影響,從而準確使用操作符學(xué)習(xí)方法: 1.掌握操作符的功能和相互關(guān)系(優(yōu)先級和結(jié)合性) 2.針對內(nèi)部數(shù)據(jù)類型,對一些典型的操作中的典型問題留下深刻印象21:28:3563第四章內(nèi)容21:28:3564 名詞解釋( Name Explainations ) 算術(shù)運算問題 ( Arithmetic Problems ) 相容類型的轉(zhuǎn)換 ( Cast Campatible Type ) 關(guān)系與邏輯操作 ( Relation & Logic Operations ) 位操作 ( Bit Operations ) 增量操作 ( Increment Operatio

37、ns ) 表達式副作用 ( Expressions Side Effects ) 1. 操作符 ( Operators )單目操作符:在一個操作數(shù)上施加的操作,如:-3雙目操作符:在二個操作數(shù)上施加的操作,如:- 故有些操作符既是單目操作符,又是雙目操作符表達式:若干個操作數(shù)和操作符按語法規(guī)則構(gòu)成的操作,如: a = -3-5+6*7/-821:28:3565優(yōu)先級:表達式中多個操作符的執(zhí)行順序的規(guī)定性,如: *x+; / 先做x+結(jié)合性:同級操作符的執(zhí)行順序的規(guī)定性,如: a=b=6; / 先做b=621:28:3566. 算術(shù)運算問題( Arithmetic Problems )整型數(shù)表示

38、范圍有限,如: 不能用整型變量累計的一般循環(huán)方法來解: int sum = 0; for(int i=1; i=10000; +i) sum += i; coutsum“n”;21:28:3567整型數(shù)的周而復(fù)始性,如: unsigned int a = 2000000000; unsigned int b = 3000000000; cout a+b“n”; 結(jié)果為: 705032704 超過表示范圍的整型數(shù)不是報錯,而是表示成一個去掉進位后的余數(shù)21:28:356821:28:3569中間結(jié)果溢出導(dǎo)致計算錯誤,如: int a = 100000; int b = 100000; int c

39、 = 1000; couta*b/cn; couta*(b/c)n; 結(jié)果為: 10000000浮點數(shù)的精度和有效位 影響比較的正確性,如: float f1 = 7.123456789; float f2 = 7.123456785; if ( f1=f2 ) cout“f1 equal to f2n”; float f = 1.0/3.0; double d = 1.0/3.0; if ( g=d ) cout“g not equal to dn”;結(jié)果為: f1 equals to f2 g not equals to d21:28:3570浮點數(shù)計算的近似性 使精確性比較失敗,如: d

40、ouble d1 = 123456789.9*9; double d2 = 1111111109.1;if ( d1!=d2 ) cout “Not samen” ;else cout “Samen” ;if ( abs ( d1-d2 ) 1e-05 ) cout “Samen” ;else cout “Not samen” ;結(jié)果為:Not sameSame21:28:35713. 相容類型轉(zhuǎn)換 ( Cast Compatible Type ) 隱式轉(zhuǎn)換:整型和浮點型都是數(shù)值型,所以它們是相容類型指針與整型不相容,如: 7.0 / 3 = 7.0 / 3.0 /將隱式轉(zhuǎn)換成浮點 int a

41、 = 9; int* ap = &a; 3 + ap /錯21:28:3572從表達能力弱的類型到強的類型的轉(zhuǎn)換是安全的,反之,會引起精度丟失如: float f = 7.0/3; / doublefloat int a = 7.0/3; / doubleint cout.precision(9); cout fixed 7.0/3 “n” ; cout f “n” a “n” ; 結(jié)果為: 221:28:3573可以用顯式轉(zhuǎn)換的方法,人為控制運算在一定的數(shù)據(jù)類型下工作,如: double d = sqrt ( 123456.0 ) ;int a = static_cast(d) * 8 +

42、5;int b = d * 8 + 5; / 隱式轉(zhuǎn)換為浮點couta“n”b“n”;結(jié)果為:2813281521:28:35744. 關(guān)系與邏輯操作 (Relations & Logic Operations )=與=的區(qū)別int x = 9;if ( x = 0 ) cout “test 1 okn” ;if ( x = 5 ) cout “test 2 okn” ;if ( x = 0 ) cout “test 3 okn” ;結(jié)果為:test 2 ok21:28:3575!=是操作符,=!不是操作符 int x = 3; if ( x!=9 ) cout “not 9n” ; if (

43、 x=!9 ) cout “impossiblen” ;條件表達式(x!=0)與(x)等同 int x = 3; if ( x != 0 ) cout x ; if ( x ) cout x ;21:28:3576不等式連寫的錯誤: int a = -1, b = 0, c = 1; if ( abc ) cout “ok1n” ; if ( ab & bc ) cout 2 ) cout “okn” ; 避免不必要的求值 if ( a=0 | b=func() ) cout”uselessn”; 21:28:35785. 位操作( Bit Operations ) 左移操作將整數(shù)最高位擠掉,

44、在右端補0。如: int a = 12; / a為:0000001100 a = a在整數(shù)的高位擠一個0或1進去(有符號數(shù)擠符號位,無符號數(shù)擠 ),而整數(shù)最低位被擠掉。如: short int a = a1; / a=-1 即 unsigned short int b = b1; / b=32767即1111121:28:3580位與操作&將兩個操作數(shù)每一位做與操作,如: int a = 12; / a為: 0000001100 int b = 6; / b為: 0000000110 / a & b為: 0000000100 int cbit = a & b; int clogic = a &

45、 b; cout cbit “n” clogic “n” ; 結(jié)果為:( 比較 & 與 & 的區(qū)別 ) 4 121:28:3581位與操作 |將兩個操作數(shù)每一位做或操作,如: int a = 12; / a為: 0000001100 int b = 6; / b為: 0000000110 / a | b為: 0000001110 int cbit = a | b; int clogic = a | b; cout cbit “n” clogic m? m:n)*10; / 保證運輸次數(shù)最少21:28:3595參數(shù)傳遞:形參是對實參的克隆,克隆必須遵守類型匹配規(guī)則void f(Type a);

46、/a為形參void g() Type x; f(x); /x為實參21:28:3596a實體x實體復(fù)制Type類型Type類型. 指針參數(shù) ( Pointer Parameters )傳遞指針:指針參數(shù)也是值傳遞的,指針值的真正用途是進行數(shù)據(jù)間訪,以達到操作數(shù)據(jù)塊(大小由之)的目的傳遞引用:引用參數(shù)本質(zhì)上也是值傳遞的,它表現(xiàn)為名字傳遞,即以形參的名字來代替實參名字如果實參不是實體名而是表達式,那么其表達式所對應(yīng)的臨時實體取名為形參,并要求其為常量引用意義:指針和引用參數(shù)的存在,使函數(shù)實際上可以訪問非局部的數(shù)據(jù)區(qū),函數(shù)的黑盒性便名存實亡但這并非一定壞事,指針是一把雙刃劍,或靈巧或邪惡引用是為了防

47、范指針非安全的無意操作21:28:3597傳遞指針須附帶傳遞單位數(shù)據(jù)的個數(shù)21:28:3598void mySort(int* b, int size);void f() int a = 3, 5, 7, 1, 8, 4, 9; mySort(a, sizeof(a)/sizeof(a0);元素個數(shù)傳指針21:28:3599限制無意操作帶來的意外副作用vector add( / 向量加法 const vector& a, const vector& b) vector c(a.size(); for(unsigned i=0; ia.size(); +i) ci = ai + bi; retu

48、rn c;3. 棧機制 ( Stack Mechanism )運行時內(nèi)存布局21:28:35100棧區(qū)進程空間代碼區(qū)全局數(shù)據(jù)區(qū)堆區(qū)未初始化局部數(shù)據(jù)的不確定性#includevoid f() int b; / 未初始化 std:cout”b“n”;/-int main() int a; / 未初始化 std:cout”a“n”; f();/-/ 8804248/ 278804821:28:35101#includeint a=5;int b=6;int main() int* ap=(int*)4202660; *ap=8; std:couta“n”; std:coutint(&b)“n”;/

49、8/ 4202664 21:28:35102指針的無約束性56abap4. 函數(shù)指針 ( Function Pointers )函數(shù)類型:函數(shù)類型因參數(shù)類型、個數(shù)和排列順序的不同而不同,也因返回類型的不同而不同函數(shù)指針:指向代碼區(qū)中函數(shù)體代碼的指針.不同的函數(shù)類型,其函數(shù)指針也不同用法:函數(shù)指針經(jīng)常用作函數(shù)參數(shù),以傳遞連函數(shù)本身都不知道的處理過程(函數(shù))21:28:35103不同的函數(shù)指針,不能相互賦值int g(int);int (*gp)(int) = g;void f();void (*fp)();fp = f;gp = fp; / error21:28:35104不同的函數(shù)函數(shù)指針作為

50、參數(shù)傳遞 (函數(shù)名看作是函數(shù)指針)bool lessThanBitSum(int a, int b) int suma=0, sumb=0; for(int x=a; x; x/=10) suma += x%10; for(int x=b; x; x/=10) sumb += x%10; return suma sumb;int main() int a = 33, 61, 12, 19, 14, 71, 78, 59; sort(aa, aa+8, lessThanBitSum); for(int i=0; i8; +i) coutaai ; coutn;/ 12 14 33 61 71 1

51、9 59 7821:28:35105指定函數(shù)指針類型,定義函數(shù)指針數(shù)組typedef void (*MenuFun)();void f1() coutgood!n; void f2() coutbetter!n; void f3() coutbest!n; MenuFun fun=f1,f2,f3;21:28:35106指針類型名5. main參數(shù) ( The mains Parameters )程序運行:操作系統(tǒng)讀入命令以啟動程序重定向命令:操作系統(tǒng)讀入命令后,識別并自我消化的參數(shù)main函數(shù)參數(shù):操作系統(tǒng)讀入命令后,不能識別參數(shù),將其直接傳遞給所啟動的程序21:28:35107命令重定向#

52、includeusing namespace std;int main() for(int a,b; cinab;) couta+b”n”;21:28:3510817213578 99 1212 345abc.txtmain函數(shù)參數(shù)#includeusing anmespace std;int main(int argc, char* argv) for(int i=0; iargc; +i) coutargvif0510 a1 a2 a3f0510a1a2a36. 遞歸函數(shù) ( Recursive Functions )形式上:一個正在執(zhí)行的函數(shù)調(diào)用了自身(直接遞歸).或者,一個函數(shù)調(diào)用了另

53、一個函數(shù),而另一個函數(shù)卻調(diào)用了本函數(shù)(間接遞歸)本質(zhì)上:程序在運行中調(diào)用了相同代碼實體的函數(shù),卻在函數(shù)棧中重新復(fù)制了該函數(shù)的整套數(shù)據(jù),由于每套數(shù)據(jù)中的參數(shù)也許不同,導(dǎo)致了計算條件發(fā)生變化,使得函數(shù)得以逐步逼近終極目標而運行21:28:35110遞歸函數(shù)可以轉(zhuǎn)換為非遞歸函數(shù)例如,求最大公約數(shù)long gcd1(int a, int b) / 遞歸版 if(a%b=0) return b; return gcd(b, a%b);/-long gcd2(int a, int b) / 非遞歸版 for(int temp; b; a=b, b=temp) temp = a%b; return a;/-

54、21:28:351117. 函數(shù)重載 ( Function Overload )函數(shù)重載:一組概念相同,處理對象(參數(shù))不同的過程,出于方便編程的目的,用同一個函數(shù)名字來命名的技術(shù)稱為函數(shù)重載參數(shù)默認:一個函數(shù),既可以嚴謹和地道的調(diào)用,也可以省略參數(shù),輕靈地調(diào)用,達到此種方便編程目的的技術(shù)稱為參數(shù)默認重載與參數(shù)默認:它們都是通過參數(shù)的變化來分辨處理任務(wù)的不同如果參數(shù)決定了不同的處理過程,則應(yīng)重載,否則參數(shù)默認更簡捷一些21:28:35112重載是不同的函數(shù),以參數(shù)的類型,個數(shù)和順序來分辨void print(double);void print(int);void func() print(1

55、); / void print(int); print(1.0); / void print(double); print(a); / void print(int); print(3.1415f); / void pirnt(double); 21:28:35113參數(shù)默認是通過不同參數(shù)來分辨一個函數(shù)調(diào)用中的行為差異void delay(int a = 2); / 函數(shù)聲明時int main() delay(); / 默認延遲秒 delay(2); / 延遲秒 delay(5); / 延遲秒void delay(int a) / 函數(shù)定義時 int sum=0; for(int i=1; i

56、=a; +i) for(int j=1; j3500; +j) for(int k=1; k100000; +k) sum+;21:28:35114C+程序設(shè)計教程(第二版)第六章 性能 Chapter 6 Performance 21:28:35115清華大學(xué)出版社 錢 能提高性能的意義: 性能對提高編程能力舉足輕重如何提高性能? 以合理使用資源為前提,盡快完成任務(wù)的能力稱為效率效率影響性能,提高效率就能提高性能學(xué)習(xí)目標: 1. 擴展視野,對同一問題的不同要求,模仿各種編程技巧與空間布局策略,予以應(yīng)對從而對各種不同的問題,亦能應(yīng)變自如 2. 掌握測試性能的方法,學(xué)會測算時/空交換的代價,客觀

57、評估自身的編程能力21:28:35116第六章內(nèi)容21:28:35117 內(nèi)聯(lián)函數(shù) ( Inline Functions ) 數(shù)據(jù)結(jié)構(gòu) ( Data Structures ) 算法 ( Algorithms ) 數(shù)值計算 ( Numerical Computation ) STL算法 ( STL Algorithms ) 動態(tài)內(nèi)存 ( Dynamic Memory ) 低級編程 ( Lower Programming ) 1. 內(nèi)聯(lián)函數(shù) ( Inline Functions )做法:將一些反復(fù)被執(zhí)行的簡單語句序列做成小函數(shù)用法:在函數(shù)聲明前加上inline關(guān)鍵字作用:不損害可讀性又能提高性能2

58、1:28:35118頻繁調(diào)用的函數(shù):用昂貴的開銷換取可讀性21:28:35119/=#includebool isDigit(char); / 小函數(shù)int main( ) for(char c; cinc & c!=n; ) if(isDigit(c) std:cout“Digit.n; else std:cout=0 & ch=9 ? 1 : 0;/=內(nèi)嵌代碼:開銷雖少,但可讀性差21:28:35120/=#includeint main( ) for(char c; cinc & c!=n; ) if(ch=0 & ch=9 ? 1 : 0) std:cout“Digit.n; else

59、 std:cout“NonDigit.n;/=21:28:35121內(nèi)聯(lián)方式:開銷少,可讀性也佳/=#includeinline bool isDigit(char); / 小函數(shù)int main( ) for(char c; cinc & c!=n; ) if(isDigit(c) std:coutDigit.n; else std:cout=0 & ch=9 ? 1 : 0;/=內(nèi)聯(lián)標記放在函數(shù)聲明的前面內(nèi)聯(lián)函數(shù)的使用經(jīng)驗:函數(shù)體適當(dāng)小,且無循環(huán)或開關(guān)語句,這樣就使嵌入工作容易進行,不會破壞原調(diào)用主體如:排序函數(shù)不能內(nèi)聯(lián)程序中特別是在循環(huán)中反復(fù)執(zhí)行該函數(shù),這樣就使嵌入的代碼利用率較高如:上

60、例中的isDigit函數(shù)程序并不多處出現(xiàn)該函數(shù)調(diào)用,這樣就使嵌入工作量相對較少,代碼量也不會劇增 21:28:35122/=#include#includeusing namespace std;/-int calc1(int a, int b) return a+b; inline int calc2(int a, int b) return a+b; /-int main() int x1000, y1000, z1000; clock_t t = clock(); for(int i=0; i1000*1000*1000; +i) zi = calc1(xi%1000, yi%1000)

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論