C和C++語言基本知識_第1頁
C和C++語言基本知識_第2頁
C和C++語言基本知識_第3頁
C和C++語言基本知識_第4頁
已閱讀5頁,還剩58頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第二章C和C++語言基本知識數(shù)據(jù)類型(datatypes)程序的主要任務(wù)之一是處理數(shù)據(jù),因此,我們首先須要知道有哪些數(shù)據(jù)類型,它們占用多大內(nèi)存。C++語言中,數(shù)據(jù)的類型可歸納為兩大類:第一類是C++系統(tǒng)所提供的一系列基本數(shù)據(jù)類型,稱為“預(yù)定義數(shù)據(jù)類型(pre-defineddatatype)”(和C語言中提供的數(shù)據(jù)類型基本相同);第二類是用戶自己定義的一系列數(shù)據(jù)類型,稱為“用戶自定義數(shù)據(jù)類型(user-defineddatatype)”。C++主要使用第二類。本章主要介紹“預(yù)定義數(shù)據(jù)類型”,而從第三章開始將陸續(xù)介紹‘‘用戶自定義數(shù)據(jù)類型”。C語言中本來也有一些’‘用戶自定義數(shù)據(jù)類型”,主要是數(shù)組、結(jié)構(gòu)體和聯(lián)合。但C++中由于編程需要,用戶將大量定義各種“類”,本課件中主要討論“類”。各“預(yù)定義數(shù)據(jù)類型”可用以下關(guān)鍵詞表達,例如:int,char,double,bool,long等。程序可以為各類數(shù)據(jù)類型建立各個變量(variable),例如建立或聲明(declare)整型變量.i,以下語句用于聲明一個變量:intj;其中int是整型數(shù)據(jù)類型,而j則是整型變量。變量被稱為數(shù)據(jù)類型的實例(instances),建立變量的過程稱為實例化(instantiation)〇也可在聲明變量的同時將它初始化,以下語句用于定義(define)ー個變量。intj=1();或int各種數(shù)據(jù)類型的長度所有數(shù)據(jù)類型的變量都在內(nèi)存中占據(jù)一定空間,其長度可使用sizeof來確定。sizeof是一個宏而不是函數(shù)(本章§2.6.4中將介紹宏與函數(shù)的區(qū)別),它在系統(tǒng)的編譯階段就已求值了。這里它用于求某個變量在內(nèi)存中的長度,也即該變量所占有的字節(jié)數(shù)。其使用格式為:對于變量inta;可用sizeof?;或sizeof(int);其它如§izeof(double);等[例1]讀取預(yù)定義類型(即由C++系統(tǒng)本身所定義的類型)數(shù)據(jù)的長度(大部分數(shù)據(jù)的說明見任何一本C語言書籍)//var_size.cpp//Tocheckthesizesofdifferentkindsofvariables#include<iostream>voidmain()(#include<iostream>voidmain()(std::cout?Msizeof(char)std::cout?v'sizeof(bool)std::cout?Hsizeof(short)std::cout?Msizeof(int):n?sizeof(char)?*\n*;:u?sizeof(bool)?,\n,;:**?sizeof(short)?*\n1;ゴ’vvsizeof(int)vv'\n';:"?sizeof(unsigned)?*\n:"?sizeof(unsigned)?*\n,:"?sizeof(long)?'\n';:"?sizeof(float)?'\n';:"?sizeof(double)?'\n';:"?sizeof(longlong)?'\nstd::cout?"sizeof(unsigned)std::cout?"sizeof(long)std::cout?"sizeof(float)std::cout?"sizeof(double)std::cout?"sizeof(longlong)std::cout?"sizeof(unsignedlonglong):"?sizeof(longlong)?'\n';std::cout?"sizeof(longdouble):"?sizeof(longdouble)?'\n';}/*Results:sizeof(char)

444448888*/這是在32位機上的運行結(jié)果,操作系統(tǒng)是WindowsXP,C++平臺是VisualStudio2003。和以前I6位機上的運行結(jié)果不同。但和64位機的Windows7操作系統(tǒng)的VS2010平臺上運行的結(jié)果卻是相同的。整型數(shù)據(jù)例如intj;(可正可負的整數(shù))和unsignedinti;(只有正值的整數(shù))它們各占32個二進制位(四個字節(jié))的空間。這32個二進制位可用四種不同方式表示一個整數(shù)值:二進制、ハ進制、十進制和十六進制。以十進制值15為例,可表示如下表中任何ー種形式:二進制ハ進制十進制十六進制111101715OxF(或Oxf)這四種表示方式之間的數(shù)值關(guān)系請見文件“附錄.doc”中附錄ー“不同基數(shù)制的整數(shù)表示方式”。正整數(shù)上面提到,整數(shù)有兩類:第一類為:“unsignedinti;"。使用二進制32位表示正整數(shù)i,它不可能為負值。其范圍為〇至約為4.2xl09,即0至庁ユ」)(約為0至+42億,確切地為4,294,967,648,中國人口統(tǒng)計已夠用)?,F(xiàn)以二進制8位為例表示正整數(shù)13:13=0013=000011011286432168421在二進制8位中,最髙有效位(MSB,MostSigniHcantBit)的值是128,最低有效位(LSB,LeastSigniHcantBit)的值是1。2.122負整數(shù)第二類整數(shù)為:“[signed]intj;”。使用32位表示可正可負的整數(shù)j,其范圍約為ー21億至+21億,即ー232/2至Q32/2A1(確切地為ー2,147,483,648至+2,147,483,647)。仍以二進制8位為例表示+13:

對于負整數(shù),一般用補碼(twdscomplement)表示(即“求反加1”),使用特別方便:二進制(以8位為例)的ー13可從其絕對值求反加一求得,表示如下:正數(shù)13表示為:13=00001101求反,得:反碼=11110010加1,得一13,表示為:反碼加1=11110011可見,負數(shù)的最髙有效位為1。讀取負碼絕對值的方法也是通過“求反加1"。如下:某負數(shù)為:X=11110011求反:X的反碼=00001100加1得x的絕對值為:X絕對值=00001101即13。所以知道此整數(shù)值為x=-13。補碼的另一方便處是:正數(shù)和負數(shù)相加時,只須直接將它們的二進制碼相加即可。3浮點型(floating-point)或?qū)嵭停╮eal)數(shù)據(jù)例如floatf;(占32個二進制位制doubled;(占64個二進制位制以64位浮點型數(shù)據(jù)為例,它在內(nèi)存中分為兩部分:指數(shù)部分x(exponent)的換算值共10位;尾數(shù)部分m(mantissa,也稱數(shù)值部分)的換算值共54位。指數(shù)部分X的換算值共10位尾數(shù)部分m的換算值共54位在存入內(nèi)存之前,浮點數(shù)的絕對值先被轉(zhuǎn)換為m?2X(其中0.5Wm<1.0;-1024WxW1023),例如, 1.2=0.6?2](其中m=0.6,x=1)0.0625=0.5?24(其中m=0.5,x=-3)然后m和x被分別換算后存入浮點型數(shù)據(jù)內(nèi)存中,換算目的是取得盡可能髙的精度,換算公式如下:將(x+1024)存入前10位,將(m-0.5)存入后54位。其中后54位(尾數(shù)部分)中每位的值如下:Sblb2b3b4b5b6b7b8-其中s為符號位:正浮點數(shù)的S=o,負浮點數(shù)的S=l。bl=0.25,b2=0.125,b3=0.0625,b4=0.03l25,b5=0.015625等?!癲oubled;”表示使用64個二進制位表示可正可負的浮點數(shù)d,其范圍為±1xグ°23至土1x2+心,大致為±5.0x10.324至±1.7X10+308o讀取某些數(shù)據(jù)類型的最大和最小值的程序可參閱附錄二。了解以上所述內(nèi)容后,就不難理解第一章§1.2.2“優(yōu)越性”中|例1]出錯的原因。字符型(character)數(shù)據(jù)例如charch;字符型變量在內(nèi)存中占據(jù)一個字節(jié)的空間。國際上通用的字符碼集是“美國信息交換標準代碼”(臺灣稱之為“美國標準資訊交換碼つ,通常稱為ASCI!碼(AmericanStandardCodeforInformationInterchange)〇其中每個字符都各有一個數(shù)值,而且大寫和小寫字符的數(shù)值各不相同。文件“附錄.doc”中附錄三是ASCII碼表。程序在輸出單個字符時,將它包括于兩個單引號之間。例如:cout?T;程序在輸出ー系列字符(稱為字符串)時,將它或它們包括于兩個雙引號之間。例如:cout?"Thisisacharacterstring!";反斜杠符號(ヽ)是一個特殊字符,稱為轉(zhuǎn)義符(escapecharacter),它可與其它字符組合使用,組成轉(zhuǎn)義序列符,完成特定顯示功能。常用轉(zhuǎn)義序歹!J(escapesequence)符(character)符號含義\n換行(一般同時回車)(newline)\r回車(carriagereturn)\t水平制表符(相當于tab鍵)\b退格符(backspace)\\反斜線V單引號\H雙引號\0空字符(也用作字符串的結(jié)尾符)ー維數(shù)組數(shù)組(array)是ー種數(shù)據(jù)結(jié)構(gòu),由相同類型的數(shù)據(jù)項組成,在內(nèi)存中占用連續(xù)地址空間。例如inta[5]={1,3,5,7,9);內(nèi)存存儲內(nèi)容a[O]=la[l]=3a⑵二5a[3]=7a[4]=9其中方括號口內(nèi)的數(shù)字稱為序號(ordinalnumber)、位置號(positionnumber)或下標(subscript,index),必須從。開始。數(shù)組內(nèi)每個單元都有一個下標。[例1]顯示數(shù)組各單元內(nèi)容//arr_for.cpp#inciude<iostream>voidmain()(intarr[5]={l,3,5,7,9};for(inti=0;i<5;i++)std::cout?arr[i]?*\n*;//for語句見本章§2.4.23)/*Results:1*/[例2]數(shù)組各單元的初始化//arr_init_mod.cpp#include<iostream>voidmain()(intarrl[3]; /股有初始化std::cout?Marrl[3]:M; //顯示各單元值for(inti=0;i<3;i++)std::cout?arrl[i]?一;std::cout?r\nf;intarr2[4]={()}; 〃將各單元初始化為零std::cout?Harr2[4]:”; 〃顯示各單元值for(i=0;i<4;i++)std::cout?arr2[i]?'std::cout?,\n';intarr3[5]={1,2}; 〃只將前兩個單元初始化為1和2,其余單元則初始化為零std::cout?Marr3[5]:M; 〃顯示各單元值for(i=0;i<5;i++)std::cout?arr3[i]?1r;std::cout?3;)/*Results:arrl[3]:-858993460-858993460-858993460arr2[4]:0000arr3[5]:12000以上程序中,如不進行初始化,數(shù)組各單元的值將一片混亂。所以在使用數(shù)組前必須采取ー定方式進行初始化。字符數(shù)組(characterarray):字符數(shù)組也稱字符串(characterstring),其中數(shù)組的每個單元是ー個字符。字符串可以用雙引號括起的字符序列來表示。例如charch[]=''work";即字符數(shù)組,其內(nèi)存存儲內(nèi)容為:ch[0]='w'ch[I]=’0’ch[2]='r'ch[3]='k'ch[4]='\0'請注意:字符數(shù)組必須用空字符'、〇'結(jié)尾。因此,字符數(shù)組的長度始終比它的有效字符數(shù)多1。字符型數(shù)據(jù)與字符數(shù)組的區(qū)別:.字符型數(shù)據(jù)用單引號表示,如,A'!而字符數(shù)組用雙引號表示,如“A”。.內(nèi)存存儲內(nèi)容不同,例如:'A"的內(nèi)存存儲內(nèi)容為"A”的內(nèi)存存儲內(nèi)容為'、〇'2.3 預(yù)處理功能為有助于執(zhí)行編譯過程(見第一章§1.3.2"C++程序的實現(xiàn)つ,經(jīng)常使用ー些預(yù)處理命令。每條預(yù)處理命令都具備一定的預(yù)處理功能。常用的預(yù)處理命令有以下三項:宏定義命令、文件包含命令和條件編譯命令。預(yù)處理命令具有以下格式:.在左邊加一#號,作為標志。.一般獨占一行。.預(yù)處理命令不是編程語句,因此句末不加分號。,在正常編譯過程之前作為預(yù)備動作而執(zhí)行,編譯過程結(jié)束后不占用存儲空間。2.3.1宏定義(macrodefinition)231.1簡單宏定義例如:#definePI3.14159#deHneSIZE80宏定義命令被執(zhí)行時,用字符串替代宏名,例如用3.14159替代PL用80替代SIZE,等。[例I]計算圓周長和面積。#deHnePI3.14159voidmain()doublecircum,area,r=3;circum=2*PI*r;area=PI*r*r;}宏定義命令被執(zhí)行時,不作語法檢査。例如,用戶希望將EXEC宏替代整句語句(例如inti=5;),使用以下宏:#defineEXECinti=5其中遺漏了分號(inti=5;オ是完整語句),但因不作語法檢査,因此査不出以上錯誤,而直到編譯系統(tǒng)將使用該宏的其它語句進行編譯時才能發(fā)現(xiàn)錯誤。 帶參數(shù)宏定義注意:帶參數(shù)宏定義并不是函數(shù)例如:#defineADD(x,y)x+y[例1]計算兩數(shù)之対。#include<iostream>#defineADD(x,y)x+yvoidmain()(inta(40),b(50); /瀨a、b分別初始化為40、50intsum=ADD(a,b);〃宏替代結(jié)果為intsum=a+b;std::cout?sum?std::endl;}/*運行結(jié)果:90宏替代的操作服從于運算符的優(yōu)先級,見下例:[例2]計算數(shù)的平方。//macro_3.cpp//Attentionindefiningmacro#defineSQ(x)x*x#include<iostream>voidmain()(inta=2,b=3;std::cout?SQ(a+b)?*\n*;〃由于乘法運算符優(yōu)先級髙于加法運算符,所以執(zhí)行a+b*a+bI/*Result:shouldbe25,butwegeta+b*a+b=ll*/問題出在優(yōu)先級,應(yīng)改正如下://macro_l.cpp#defineSQ(x)(x)*(x)#include<iostream>voidmain()(inta=2,b=3;std::cout?SQ(a+b)?V; 〃即(a+b)*(a+b)}/*Result:25 */請注意:宏不是函數(shù)(子程序)!宏與函數(shù)的區(qū)別:宏節(jié)省時間但占用空間;函數(shù)節(jié)省空間但增加時間!(詳見本章§2.6.4)文件包含(inclusionoffiles)如果以上所述的宏定義語句很多,則可將它們包含于ー個單獨的文件中,例如“macros.h”中。此macros.h文件內(nèi)容例如可定義為://macros.h#defineMAX32#definesq(n)(n)*(n)#definePI3.14159此時用戶程序得以簡化為只包含以下一條語句:#include"macros.h"即可執(zhí)行以上所有宏命令。以上macros.h稱為頭文件(headerfiles)(或稱包含文件,includefiles)。其中系統(tǒng)所定義的頭文件名稱(例如iostream)使用尖括弧括nglebrackets)<>將頭文件名稱iostream包括起來,系統(tǒng)就根據(jù)這點到系統(tǒng)的文件夾中去調(diào)用。C++所提供的頭文件在包含時一般不包括字符“.h”,但舊的C語言所提供的頭文件在包含時一般應(yīng)該包括字符“.h”而用戶自定義的頭文件則用雙引號""將頭文件名稱包括起來,例如"macros.h"(一般都應(yīng)包括字符“.h")。系統(tǒng)就根據(jù)這點到用戶程序的文件夾中去調(diào)用。請注意此區(qū)別。C++語言系統(tǒng)中有很多頭文件,它們除包含宏替代定義語句外,更主要包含函數(shù)原型聲明(見本章§)和類的聲明(見第三章§3.2“類及其對象”中有關(guān)頭文件功能的描述),及其所用各種常量的定義(見第三章和第四章)。一般情況下,頭文件可以包含以下內(nèi)容:(1)類、函數(shù)、數(shù)據(jù)的聲明;(2)常量和宏的定義;(3)預(yù)處理語句等。但頭文件不宜包含類、函數(shù)、數(shù)據(jù)變量的定義。條件編譯(conditionalcompiling)條件編譯命令的功能是規(guī)定某些語句(或某個程序塊)在一定條件下オ參加編譯,否則跳過不予理睬。其主要用途為:防止遺漏定義或避免重復(fù)定義;以及在測試時增加某些測試語句,以實現(xiàn)調(diào)試跟蹤的目的。本節(jié)主要講防止遺漏定義或避免重復(fù)定義的功能。其格式為:#ifdef (常量表達式)(或#ifdefined(常量表達式))[條件編譯程序塊]#endif或#ifndef(常量表達式)(或#ifnotdefined(常量表達式))[條件編譯程序塊]#endif以上語句中,當常量表達式無定義時,就編譯兩個條件編譯命令#ifdef(或#ifndef)與#endif之間的條件編譯程序塊。條件編譯命令也可表達如:#if(常量表達式)[條件編譯程序塊]#endif此時如常量表達式非零,則滿足編譯條件,編譯兩個條件編譯命令#if與#endif之間的條件編譯程序塊?,F(xiàn)在講解其避免遺漏定義的功能:以下使用#ifndefMAX,此即(#ifnotdefinedMAX)或(#if!definedMAX)[例1]防止遺漏MAX的定義://test_ifndef_l.cpp//Topreventthemissingofmacrodefinition#include<iostream>#ifndefMAX#defineMAX32#endifvoidmain()std::cout?nMAXisM?MAX?'\n';/*Result:MAXis32 */上例中MAX沒有定義,所以執(zhí)行條件編譯語句#defineMAX32〇[例2]此例中MAX已經(jīng)定義過了,故不執(zhí)行條件編譯程序塊//test_ifndef_2.cpp//Topreventthemissingofmacrodefinition#include<iostream>#deHneMAX10#ifndefMAX#defineMAX32#endifvoidmain()(std::cout?HMAXisn?MAX?\n';)/*Result:MAXis10 */上例中MAX已被定義為等于10,所以不執(zhí)行條件編譯語句#defineMAX32。再看更重要的用途,避免重復(fù)包含頭文件:[例3]防止重復(fù)包含頭文件。設(shè)已有頭文件如下://ifndef.h//Toavoidtheduplicationofincludefiles#if!defined(_IFNDEF_H)#define_IFNDEF_Hintvar=l;//globalvariable#endif//_IFNDEF_H用戶應(yīng)用程序如下://test_ifndef_3.cpp//Topreventtheduplicationofmacrodefinition#include<iostream>#includeMD:\MyDocumentsWS2003?程序\ifndef?h”includeMD:\MyDocumentsWS2003?程序Xifndef.h" 〃看似重復(fù),其實不然voidmain()(std::cout?''變量var="?var?'\n';}/*Result:變量var=1號此程序中雖然多了一句#include“ifndef.h”,但第二句不起作用。原因在于頭文件中使用了條件編譯功能。怎么知道重復(fù)包含的第二句不起作用?因為如果包含第二句的話,將會出錯。如下://test_ifndef_4.cpp//Theerroroftheduplicationofmacrodefinition#include<iostream>intvar=l;intvar=l;voidmain()cout?”變量var="?var?endl;}/*Result:編譯出錯errorC2374:"var"Z重定義:多次初始化參見“var”的聲明サ在任何頭文件中,都必須使用上述條件編譯語句以便避免重復(fù)包含。在有些頭文件中,也可能使用語句#pragmaonce,只要在頭文件的初始部分加入這條指令,就能夠保證頭文件只被編譯ー次。有時同時使用條件編譯語句#if!defined(」FNDEF一H)、#define一IFNDEF_H和#endif以及#pragma語句。2.4 控制流(flowofcontrol)語句Bohm和Jacopini的研究表明:所有程序都可以只用三類控制結(jié)構(gòu)(controlstructure):即順序結(jié)構(gòu)(sequencestructure)、選擇結(jié)構(gòu)(selectionstmcture)和循環(huán)結(jié)構(gòu)(loopingstructure,或稱重復(fù)結(jié)構(gòu),repetitionstructure)〇C和C++程序通常只使用七種控制結(jié)構(gòu):ー種順序結(jié)構(gòu)、三種選擇結(jié)構(gòu)(if、if?else和switch)和三種循環(huán)結(jié)構(gòu)(while、do?while和for)。其中順序結(jié)構(gòu)是任何編程語言所內(nèi)置或固有(inherent)的,即在沒有另外指定控制結(jié)構(gòu)的情況下,計算機總是按照編程順序逐條語句地往下執(zhí)行。因此本節(jié)主要介紹其它兩個控制結(jié)構(gòu):選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。選擇語句條件語句[例1]單項選擇結(jié)構(gòu)(single-selectionstructure)?本例中使用if語句求兩個數(shù)中的最大值//if_l.cpp//Onlyuse"if"tolookforthemaximumvalue#include<iostream>voidmain()(inti=1,j=2,x;if(i>j)x=i;if(j>i)x=j;if(j==i)x=j;std::coutv<”兩個數(shù)據(jù)中最大值:"<<x?,\n';)/*Result:兩個數(shù)藉中最大值:2*/上例中,當if括號中的表達式符合實際情況時,條件為真(true),執(zhí)行其后的語句。如不符合實際情況,則條件為假(false),不執(zhí)行其后的語句。請注意:切不可將邏輯判斷語句if(i==i)和賦值及邏輯判斷語句if(i=i)混為ー談,二者差別甚大。邏輯判斷語句if(j==i)只是用于判斷j是否等于i,如相等,則條件為真:否則為假。而賦值及邏輯判斷語句if(j=i)做兩件事,先將j賦值為等于i,然后再判斷賦值后的j是否不等于零,如不等于零,則條件為真;否則為假。構(gòu)(double-selectionstructure)。本例中使用if-else語句求兩個數(shù)中的最大值//max_2.cpp#include<iostream>voidmain()(inti=4,j=6,x;if(i>j) x=i;else x=j;std::cout?x?'\n';)/*Result:6 */上例中,當if括號中的表達式符合實際情況時,條件為真,執(zhí)行其后的語句。如不符合實際情況,則條件為假,改為執(zhí)行else后的語句。三元條件運算符a>b?a:bresult=a>b?a:b;這ー語句等同于if(a>b)result=a;else result=b;它的優(yōu)點是比較簡練。[例1]條件運算符用于求最大值//max_l.cpp#include<iostream>voidmain()(inti=4,j=6,x;X=i>j?i:j;std::cout?x?へn';)/*Result:6 */〃后兩句可合并為一句,如下://cout?(i>j?i:j)?'\n'; 〃其中()不可省略開關(guān)增句switch此處switch選擇結(jié)構(gòu)稱為多項選擇結(jié)構(gòu)(multiple-selectionstructure)〇[例11實現(xiàn)兩個數(shù)的四則運算//switch」,cpp#include<iostream>voidmain()(doubledl,d2; 〃兩個操作數(shù)charop;〃運算符std::cout?MPleaseinputthreedata:operand1operatoroperand?:'';std::cin?dl?op?d2;switch(op)(doubletemp;case*+':temp=dl+d2;std::cout<<dl?op?d2?'='?temp?'\n';break;casetemp=dl-d2;std::cout<<dl?op?d2?'='?temp?'\n';break;casetemp=dl*d2;std::cout?dl?op?d2?'='?temp?'\n';break;case7':temp=dl/d2;std::cout<<dl?op?d2?'='?temp?'\n';break;default:std::cout?"Error"?*\n';)}運算結(jié)果例如:Pleaseinputthreedata:operand1operatoroperand2:2+32+3=5其中帶下劃線的字符由用戶鍵入。注意事項:Lease后面的表達式必須是整型、字符型或枚舉型(enum)表達式。.case后面的表達式必須互不相同。.每個case語句序列最后一條語句是break,用于退出開關(guān)語句。最后ー個case語句序列可以不用break〇.帶有break的case語句序列的順序可以是任意的。break語句還可用于退出循環(huán),見本章§2.423[例5]。第九章§11.1.2“編輯框(EDIT)控件和數(shù)據(jù)交換”中有本程序的改進版本,名為“EditComputer”的對話框項目,使用圖形化界面,可以自動反復(fù)運算。2.4.2循環(huán)語句2?4?2.1 while循環(huán)語句while(循環(huán)條件) {循環(huán)體);#include<iostream>voidmain()(intcount=1;while(count<=3)std::cout?count++?*\n*;//post-incremental,后置自增,其使用多于“前置自增”}/*Result:(共循環(huán)三次)123 */2.422do?while循環(huán)語句do{循環(huán)體}while(循環(huán)條件);在判斷循環(huán)條件之前已先執(zhí)行ー次循環(huán)體內(nèi)的程序塊!#include<iostream>voidmain()(intcount=1;do{std::cout?count++?*\n*;}while(count<=3);}/*Result:(只循環(huán)兩次)123 */2.423for循環(huán)語包for(循環(huán)變量初始值;循環(huán)條件;循環(huán)增量)循環(huán)體(可以包含多條語句)I例1]使用for循環(huán)語句的第一種形式//for_l.cpp/Z預(yù)先定義循環(huán)變量#include<iostream>voidmain()(intcount;for(count=1;count<=3;count++)std::cout?count?,\n';/*Results:*/[例2]使用for循環(huán)語句的第二種形式//for_2.cpp//在for語句內(nèi)定義循環(huán)變量#include<iostream>voidmain()|for(intcount=l;count<=3;count++)std::cout?count?*\n*;)/*Results:*/[例3]使用for循環(huán)語句的第三種形式//for_3.cpp/Z預(yù)免定義循環(huán)變量并將其初始化#include<iostream>voidmain()(intcount=l;for(;count<=3;count++)std::cout?count?*\n*;/*Results:*/[例4]使用for循環(huán)語句的第四種形式//for_4.cpp//在滴環(huán)體內(nèi)進行循環(huán)增量#include<iostream>voidmain(){intcount=1;for(;count<=3;)std::cout?count++?'\n';}/*Results:*/[例5]使用for循環(huán)語句的第五種形式//for_5.cpp//在在環(huán)體內(nèi)判斷循環(huán)條件#include<iostream>voidmain()(intcount=l;for(;;)if(count>3)break;std::cout?count++?'\n*;

/*Results:123 */上一程序中兩個花擴號(if(count>3)break;std::cout?count++?std::endl;}之間的內(nèi)容也稱為復(fù)合語句,當復(fù)合語句中還包含變量或函數(shù)聲明(functiondeclarations)時,它也稱為程序塊(block)。2.5 指針(pointer)251 定義指針是ー種數(shù)據(jù)類型,用于存放某個變量的地址值。此時該指針被稱為是指向該變量。ー個指針的類型決定于它所指向的變量的類型,它決定指針能夠訪問多大的數(shù)據(jù)空間。這點很重要。指針既可指向基本數(shù)據(jù)類型(即預(yù)定義數(shù)據(jù)類型),又可指向數(shù)組、函數(shù)、類和文件等用戶自定義數(shù)據(jù)類刑。指針可以初始化為0、NULL(即0,這是標準庫頭文件中定義的符號化常量)或ー個地址。內(nèi)容為0或NULL的指針不指向任何變量,稱為空指針。例如:inta=5;int*ptr;中的ptr。指針ptr在下式中被初始化為指向變量a。ptr=&a;以上兩條語句也可組合地表示為:int*ptr=&a;其中“&”為存地址運算符,而則為取內(nèi)容運算符。inta,*ptr;ptr=&a;在下冊的MFC項目中,用于指向特殊結(jié)構(gòu)(例如進程、線程、同步類對象、視圖類對象、窗口、設(shè)備描述表、數(shù)據(jù)結(jié)構(gòu)的節(jié)點以及動態(tài)鏈接庫模塊等)的指針還具有另ー稱呼一句柄(Handle)。數(shù)組的指針數(shù)組名是ー個指向該數(shù)組的常量指針(其值不能改變),也是該數(shù)組中首單元的地址值。指針類型單個變量的指針ー維數(shù)組的指針定義變量:inta=5;intarr[5]={1,3,5,7,9);聲明指針:int*ptr;int*ptra;將指針初始化:ptr=&a;ptra=arr;此處指向數(shù)組的指針的定義格式(int*ptra;)與普通預(yù)定義數(shù)據(jù)的指針的定義格式(int*ptr;)完全相同。但指針ptra的賦值語句卻不同,語句中不使用符號’&'。數(shù)組指針與數(shù)組名兩者的異同:(1)整型指針與整型數(shù)組:air既是數(shù)組名,又是數(shù)組地址,還是數(shù)組指針(稱為常量指針),三位一體。因此arr可在一定范圍內(nèi)與ptra等效地使用。U可在一定范圍內(nèi)與?等效地使用。但arr不準重新賦值。例如:arr[0]即?arr即?ptra即ptra[O]=1air[3]即?(arr+3)即?(ptra+3)即ptra[3]=7但arr的使用不如ptra靈活,如:*arr++表達式不合法,但?ptra++表達式卻合法。見以下例子:即§2.2中[例1]的主程序voidmain(){intarr[5]={1,3,5,7,9);for(inti=0;i<5;i++)std::cout?arr[i]?4\n\〃數(shù)組名)其中的for語句可改為:for(inti=0;i<5;i++)std::cout?*(arr+i)?4\n5;〃指針//但不允許arr自身加減,即不允許://std::cout?*(arr++)?An';notallowed但指針ptra卻可以加減:int*ptra=arr;for(inti=0;i<5;i++)std::cout?*(ptra++)?fc\n';〃此處可以將指針ptra增減,指針增減詳見§253.2此處可見,一般情況下,可不必為數(shù)組另外定義指針。(2)字符串與字符數(shù)組:字符串一般使用指針(包括變量指針和常量指針兩種方式)表示其地址和內(nèi)容,此地址也即其第一個字符的地址。第一種為變量指針方式例如:char*ch_ptr="home";(ch_ptr為變量指針)。第二種為常量指針方式例如:charch_arr[5]="OK";(ch.arr為常量指針)。此處字符數(shù)組名是ー個指向該數(shù)組的常量指針,它不能重新賦值。字符串內(nèi)容及其地址的顯示方式,牽涉到數(shù)據(jù)的類型轉(zhuǎn)換問題。請參閱本章§2.7“數(shù)據(jù)類型轉(zhuǎn)換”。指針的賦值和增減和其它變量一樣,指針也可賦值和增減。但指針有它特殊之處,請看下面。指針的賦值所有變量,包括指針在內(nèi),在賦值運算中要求等式兩側(cè)的變量具有相同數(shù)據(jù)類型(以后本章§2.7“數(shù)據(jù)類型轉(zhuǎn)換”和第五章§5.4.1“數(shù)據(jù)和對象的類型轉(zhuǎn)換”中將會詳述)。例如:intj=5,k;k=j;又如:[例?指針的賦值//ptr_=_l.cpp//assigningapointer#include<iostream>voidmain()intj=5,k=11,*ptr=&j;std::cout?*ptr?,\n*;ptr=&k;std::cout?*ptr?*\n*;}/*Results:511號在以下語句中,第三句出錯:inti=5;doubled=1.2,*ptr=&d;ptr=&i;//error:*=*:cannotconvertfrom'int*'to'double*'這個錯誤是由于等號兩側(cè)變量的類型不同,請參閱本章§2.7“數(shù)據(jù)類型轉(zhuǎn)換'在字符指針的賦值運算中,還有一個條件。我們知道,字符串一般使用指針表示其地址,也即其第一個字符的地址。對字符串賦值也即對指針賦值。因此,對字符指針重新賦值的條件是“該指針不可以是常量指針”。上面§2.5.2“數(shù)組的指針”中提到:字符數(shù)組名是ー個指向該數(shù)組的常量指針,不能重新賦值。因此,使用數(shù)組形式表示的字符串(因它使用常量指針)無法使用普通賦值運算符“=”對字符串重新賦值。請見下例:I例2]不同情況下字符指針的賦值運算//overld_str_=_2.cpp//seetheconditionthatcharacterstringscanorcannotbere-assigned#include<iostream>#include<string.h>voidmain(){chararray[]="OK"5 〃常量指針char*ptrl="home"; 〃變量指針char*ptr2="World"; 〃變量指針std::cout.setf(std::ios::hex|std::ios::uppercase); 〃顯示十六進制和大寫字母,詳見第八章std::cout?"Originalstringsare:"?std::endl;std::cout?"array[]="<<array?','?"*ptrl="?ptrl?".withaddressesas:"?std::endl;std::cout?"array="?(int)array?','<<"ptrl="?(int)ptrl?std::endl;ptrl=ptr2;std::cout?"Afteroperationptrl=ptr2,stringsbecome:"?std::endl;std::cout?"array[]="<<array?','?"*ptrl="?ptrl?".withaddressesas:"?std::endl;std::cout?"array="<<(int)array?\'?"ptrl="?(int)ptrl?std::endl;ptrl=array;std::cout?"Afteroperationptrl=array,stringsbecome:"?std::endl;std::cout?"array[]="<<array?','?"*ptrl="?ptrl?".withaddressesas:"?std::endl;std::cout?"array="<<(int)array?','?"ptrl="?(int)ptrl?std::endl;std::cout?"'array=ptrl'isnotallowed!"?std::endl;//array=ptrl;//error:cannotconvertfrom'char*'to'char[3]'}/*Results:Originalstringsare:array[]=OK,*ptrl=home.withaddressesas:array=1244884,ptrl=4518348Afteroperationptrl=ptr2,stringsbecome:array[]=OK,*ptrl=World.withaddressesas:array=1244884,ptrl=4518340Afteroperationptrl=array,stringsbecome:array[]=OK,*ptrl=OK.withaddressesas:array=1244884,ptrl=1244884'array=ptrl'isnotallowed!*/從以上程序可以看出,指向數(shù)組的常量指針是不允許重新賦值的。253.2 指針的增減與其它預(yù)定義數(shù)據(jù)類型的變量相同,指針也可以隨意增量(incremented?以++表示)或減量(decremented,以ー-表示)。但這并不意味它的值只是增ー或減ー。事實上,它的數(shù)值變化是和它的類型(也即它所指向的數(shù)據(jù)類型)有關(guān)的。請看以下兩例:[例整型指針的增量//arr_ptrl.cpp//Showtheeffectofincrementofapointerofintegertype#include<iostream>intarrロ={1,2,3};voidmain()(int*ptra=arr;for(inti=0;i<3;i++,ptra++)std::coutvv”指針所指向的地址=M?ptra?M;指針所指向的數(shù)據(jù)=M?*ptra?,\n,;)/*Results:指針所指向的地址=00455FA0;指針所指向的數(shù)據(jù)=1指針所指向的地址=00455FA4;指針所指向的數(shù)據(jù)=2指針所指向的地址=00455FA8;指針所指向的數(shù)據(jù)=3以上程序中,指針ptra每增量一次,其數(shù)值即增加4,這正好是ー個整型數(shù)據(jù)的長度。[例2]浮點型指針的增量//arr_ptr2.cpp//Showtheeffectofincrementofapointerofdoubletype#include<iostream>doublearr[]={1.1,2.2,3.3};voidmain()(double*ptra=arr;for(inti=0;i<3;i++,ptra++)std::cout<<"指針所指向的地址="?ptra?"5指針所指向的數(shù)據(jù)="?*ptra?'\n';}/*Results:指針所指向的地址=004564A8;指針所指向的數(shù)據(jù)=1.1指針所指向的地址=004564B0;指針所指向的數(shù)據(jù)=2.2指針所指向的地址=004564B85指針所指向的數(shù)據(jù)=3.3*/以上程序中,指針ptra每增量一次,其數(shù)值即增加8,這正好是ー個double型數(shù)據(jù)的長度。指向指針的指針例如:inti=5;int*ptr=&i; 〃ー級指針int**pp=&ptr; 〃二級指針即:指向整型指針ptr的指針 指向整型變量i的指針整型變量pp=&ptr ?Ptr=&i >i=5可表示為: i=*ptr;或i=**pp;第五章中將用到“二級指針”的概念。255 指針數(shù)組(arrayofpointers)在實際應(yīng)用中,常常使用ー維ー級字符指針數(shù)組來存放ー些字符串,以便于操作。[例1]使用ー維ー級字符指針數(shù)組來存放一星期中的各天。//arr_ptr3.cpp//Showthefunctionofacharacterarray#include<iostream>#include<conio.h>//forgetch()char*name[]={''Monday",''Tuesday","Wednesday”,"Thursday","Friday","Saturday","Sunday");voidmain(){intweek;while(1)(std::cout?"Inputsequentialnumber:";std::cin?week;if(week<l||week>7)break;std::cout?"Thisis"?name[week-l]?*\n';/Z指針數(shù)組第1單元的序號為〇,而用戶輸入的〃week值卻從1開始,所以week應(yīng)減1}std::cout?"Illegalnumber.Programended!"?'\n';getch();)/*Results:Inputsequentialnumber:!ThisisTuesdayInputsequentialnumber:5ThisisFridayInputsequentialnumber:0Illegalnumber.Programended! */2.6函數(shù)(function)262 函數(shù)定義和函數(shù)原型(函數(shù)聲明)函數(shù)的功能及函數(shù)定義(functiondefinition)[例1]不用函數(shù)的例子(此程序示意用,不能上機)#include<iostream>voidmain()(doublex=8.(),y=64.0,z=125.0;std::cout?用于求解x的立方根的程序塊vv'\n';std::cout?用于求解y的立方根的程序塊vv'\n';std::cout?用于求解z的立方根的程序塊?'\n';)/*Results:245 */上例中求解立方根的程序塊可以使用逼近算法,包含數(shù)十條語句,精度髙時甚至超過100條,則整個程序?qū)㈤L達300多條,占據(jù)太多空間??捎靡韵路椒ü?jié)省空間開銷。[例2]使用函數(shù)的例子(此程序示意用,不能上機)#include<iostream>doublecuberoot(double);〃函數(shù)原型voidmain()doublex=8.0,y=64.0,z=125.0;std::cout?cuberoot(x)?ヘn';std::cout?cuberoot(y)?,\n’;std::cout?cuberoot(z)?,\n’;)doublecuberoot(doublei)(用于求解double型數(shù)據(jù)的立方根的程序塊,包含至少數(shù)十條語句,甚至超過ー百條。}/*Results:245 */如此使用函數(shù),能將程序壓縮很多,由三百多條壓縮至ー百多條,從而節(jié)省空間,并具有良好的可讀性。函數(shù)的定義格式如下:〈返回值〉 く函數(shù)名〉V(參數(shù)表)>(く函數(shù)體〉)其中第一行也稱函數(shù)頭或首部(functionheader),一般能在一行內(nèi)寫完,但多行也可?!捶祷刂怠狄卜Q〈類型說明符〉,也即,函數(shù)的返回值也代表函數(shù)的類型。如無返回值,則使用void表ZjSo函數(shù)定義的關(guān)鍵部分是函數(shù)體(functionbody),有時也可稱為塊(block)。設(shè)計函數(shù)時一般考慮使函數(shù)具有單ー功能。各C++系統(tǒng)對于函數(shù)返回值都有自己規(guī)定的缺省值,目前本課件所用VC++6,0版本規(guī)定:函數(shù)返回值的缺省值是int,即返回整型值。函數(shù)原型['聲明](functionprototype)ANSI(AmericanNationalStandardsInstitute,美國國家標準學會)曾對C語言規(guī)定:任何函數(shù)必須使用函數(shù)原型(或稱函數(shù)原型聲明,或簡稱函數(shù)聲明,函數(shù)聲明,functiondeclaration),VisualC++也沿用此規(guī)定它規(guī)定所有函數(shù)在使用之前,必須先聲明它的函數(shù)原型,以便于檢査錯誤。在ANSIC之前,編譯系統(tǒng)并不對函數(shù)進行參數(shù)類型檢査,如果在函數(shù)調(diào)用中參數(shù)類型、參數(shù)順序或參數(shù)數(shù)量有錯,編譯系統(tǒng)都無法察覺,直至函數(shù)運行結(jié)果中出現(xiàn)錯誤,オ被發(fā)現(xiàn)。使用函數(shù)原型有助于克服這個缺陷。ANSIC語言使用函數(shù)原型后,編譯系統(tǒng)能夠及早地在編譯階段就驗證函數(shù)調(diào)用的參數(shù)列表(包括參數(shù)的類型和數(shù)量)是否正確,不至于產(chǎn)生不必要的錯誤或不易發(fā)現(xiàn)的邏輯錯誤。函數(shù)原型的另ー個重要功能是參數(shù)的強制類型轉(zhuǎn)換(coercionofargument),將函數(shù)調(diào)用時的參數(shù)強制轉(zhuǎn)換為函數(shù)原型中所指定的類型。(以后將在本章§2.7“數(shù)據(jù)類型轉(zhuǎn)換”和第五章§5.4中敘述)大多數(shù)情況下,用戶在調(diào)用函數(shù)時,只須知道函數(shù)原型而對函數(shù)定義不感興趣。函數(shù)原型的格式如下:〈返回值〉 〈函數(shù)名〉〈(參數(shù)表)>i可以看出:函數(shù)原型的格式是函數(shù)首部加分號。函數(shù)原型的參數(shù)表中可以包括參數(shù)類型和參數(shù)名兩者,如:intsq(皿);也可以只包括參數(shù)類型。如:intsa(int):這兩種形式都可以使用。[例1J不允許省略函數(shù)原型[聲明]。//fun_prot_l.cpp//functionprototypeshouldnotbeomitted#include<iostream>intadd(int,int);IIIfomitted,errorC2065:'add':undeclaredidentifiervoidmain()(inta=2,b=3;std::cout?add(a,b)?'\n';}intadd(intx,inty){return(x+y);)/*Result:5 */函數(shù)原型(函數(shù)聲明)和函數(shù)定義在表現(xiàn)形式上的差別在于:.函數(shù)原型(函數(shù)聲明)沒有函數(shù)體,而函數(shù)定義則必須具有函數(shù)體。.函數(shù)原型(函數(shù)聲明)必須用分號結(jié)尾,而函數(shù)定義的結(jié)尾則不用分號。函數(shù)原型和函數(shù)定義的形參類型和數(shù)量以及返回值都必須相同。一般將所有函數(shù)原型(函數(shù)聲明)都放在ー個頭文件中,這是頭文件的ー個重要用途。而該頭文件一般位于程序首部。在第三章§3.2.4“類的聲明與其實現(xiàn)部分的分離”ー節(jié)中,我們將會看到,按照軟件工程的觀點,類的成員函數(shù)的函數(shù)聲明(即函數(shù)原型)和函數(shù)定義應(yīng)是分離的。.6.2 有參與無參函數(shù).1 無參[數(shù)的]函數(shù)[例1]函數(shù)正常結(jié)束//fun_l.cpp#include<iostream>voidmain()(inti=1;std::cout?i?'\n';=2;std::cout?i?'\n';}/*Results:1*/大部分函數(shù)都是運行至函數(shù)末尾時オ結(jié)束。事實上,在某些函數(shù)中遇見return語句時也結(jié)束,如下例。[例2]函數(shù)遇return時結(jié)束//fun_2.cpp#include<iostream>voidmain()(inti=1;std::cout?i?'\n';return;=2;std::cout?i?'\n';}/*Result:*/此時最后兩條語句根本無用![例3]兩個無參函數(shù)(顯示出錯信息的函數(shù))//err_msg_l.cpp//toshowanerrormessaage#include<iostream>voiderr_msg();〃函數(shù)原型voidmain()(intflag=-1;if(flag<0)err_msg();)voiderr__msg()(std::cout?‘'Error!”?*\n*;}/*Result:Error!*/262.2 有參[數(shù)的]函數(shù)有參函數(shù)具有一個或更多參數(shù)(argument)。當函數(shù)的形參多于ー個時,組成“參數(shù)列表(argumentlist)”或“形參列表”。[例1]求平方的函數(shù)#include<iostream>intsq_int(inta);voidmain()(inti=5,j;j=sq_int(丄); 〃當然也可和上一句合并為sq_int⑸std::cout?j?‘\n‘;)intsq_int(inta) {returna*a;}/*Result:25 */以上函數(shù)中,intsq_int(inta);中的"a”稱為形參(形式參數(shù))(dummyargument),"j=sqJnt(丄)メ中的“i”稱為實參(實際參數(shù))(realoractualargument)。I例2]顯示出錯序號的有參函數(shù)//err_msg_2.cpp#include<iostream>voiderr_msg(int);voidmain(){intflag=-1;if(flag<0)err__msg(-flag);}voiderr_msg(intnum)(std::cout?"ErrorNo."?num?‘\n‘;}/*Results:ErrorNo.1 */其中num是形參,-flag是實參。有時也可將實參與運算符結(jié)合起來使用,例如下例:I例3]實參經(jīng)過一定運算后,再使用條件運算符進行非線性運算,形成飽和特性,對實參加以限制,然后再輸入函數(shù)內(nèi)。//argument_operat_2.cpp//usingconditionaloperatoractingonrealargument#include<iostream>intsq(int);voidmain()for(intj=l;j<=10;j++)

std::cout?sq((j<6)?j:6)?std::cout?*\nf;)intsq(intk){,returnk*k;)/*Result:14916253636363636號程序中各變量間的關(guān)系*2.623 參數(shù)表可變的函數(shù)個別情況下,雖然知道參數(shù)的類型,但其數(shù)量卻不確定。此時可使用參數(shù)表可變的函數(shù).其實c語言中已有這類函數(shù),例如標準輸出函數(shù)printf。在C++中,這類函數(shù)的函數(shù)原型具有以下形式的參數(shù)表:(inti,...).這個整型變量i的數(shù)值代表處理實參的循環(huán)次數(shù).編譯系統(tǒng)只檢査第一個實參是否為整型,而不過問其余實參的類型.使用參數(shù)表可變的函數(shù)時,程序必須包含<cstdarg>頭文件.參數(shù)表可變的函數(shù)必須使用ー個va」ist類型(大部分情況下它是char?類型)的變量和三個宏.在處理實參前使用宏va-start:在處理實參過程中使用宏va-arg;在處理實參后使用宏va-end.試看兩個例子.[例1]用于顯示不同數(shù)量整型變量的程序.//argument_var_3.cpp//modifiedversionofexamplein”視頻學VisualC++(光盤)明日科技梁水王家勝編著”#include<iostream>#include<cstdarg>voidshow(inti,...); 〃參數(shù)表可變函數(shù)的函數(shù)原型voidmain()(std::coutvv”第一次調(diào)用:H;show(4,8,12,432,1005); 〃調(diào)用函數(shù)std::coutvぐ第二次調(diào)用:“;show(2,l08,1234); 〃調(diào)用函數(shù))voidshow(inti,...) 〃定義參數(shù)表可變函數(shù)vajistlist;va_start(list,i);while(i—)//vajist類型變量,or"char*list;vajistlist;va_start(list,i);while(i—)〃將int型的參數(shù)傳給va!〃將int型的參數(shù)傳給va!變量

隔出操作intval=va_arg(list,int);std::cout?val?'

std::cout?,\n,; /輪出回車符va.end(list); 〃將指針設(shè)置為NULL}/*Results:第一次調(diào)用:8124321005第二次調(diào)用:1081234號ピtypedefchar*va_list;#endif#define_VA_LIST_DEFINED#endif#ifdef_M_IX86#defineJNTSIZEOF(n)((sizeof(n)+sizeof(int)-1)&-(sizeof(int)-1))#defineva_start(ap,v)(ap=(va_list)&v+_INTSIZEOF(v))#defineva_arg(ap,t)(*(t*)((ap+=JNTSIZEOF(t))-JNTSIZEOF(t)))#defineva_end(ap)(ap=(va_list)0)*/主函數(shù)第一次顯示了四個實參,第二次顯示了兩個實參。第二次調(diào)用時堆棧內(nèi)容如右圖所示: i=21081234[例2]用于顯示多組不同類型相同數(shù)目的變量。//argument_var__4.cpp//modifiedversionofexamplein"視頻學VisualC++(光盤)明日科技梁水王家勝編著”#include<iostream>#include<cstdarg>voiddisplay(inti,...); 〃參數(shù)表可變函數(shù)的函數(shù)原型voidmain(){displaysノ第一組的第一值為”,8,“第二值為”,12.34, 〃調(diào)用函數(shù))voiddisplay(inti9...)|)voiddisplay(inti9...)|vajistlist;va_start(list,i);while(i—)〃定義參數(shù)表可變函數(shù)〃valist類型^^量〃建務(wù)掃描參數(shù)表的起始指針,并保存vajist型變量中的信息char*chl=va_arg(list,char*);intval=va_arg(list,int);char*ch2=va_arg(list,char*);〃將char?型的參數(shù)傳給chi變量〃將intchar*chl=va_arg(list,char*);intval=va_arg(list,int);char*ch2=va_arg(list,char*);〃將char?型的參數(shù)傳給ch2變量doubledbl=va_arg(list,double);//將double型的參數(shù)傳給dbl變量std::cout?chl?val?"?"?ch2?dbl?'\n'; /獺出操作va_end(list);〃將指針設(shè)置為NULLva_end(list);}/*Results:第一組的第一值為8;第二值為12.34第二組的第一值為!6S第二值為34.56以上主函數(shù)顯示了兩組變量的數(shù)值,每組有四個不同類型但相同順序的變量。下面列舉四個宏的定義,供參考:[摘自頭文件stdarg.h]指針總是指向下一個待訪問變量。#defineJNTSIZEOF(n)((sizeof(n)+sizeof(int)-1)&~(sizeof(int)-1))〃將變量長度擴展為4的倍數(shù)〃按位運算符(bitwiseoperators)中:&是按位與,?是按位非。#defineva_start(ap,v)(ap=(va_list)&v+_INTSIZEOF(v))〃其中&v是參數(shù)表中第一個參數(shù),即i([例1]中i=2)〃ーINTSIZEOF(v)是此參數(shù)長度的4的倍數(shù)。〃因此,就將list指針指向棧上第一個待訪問變量(如[例1]中108)#defineva_arg(ap,t)(*(t*)((ap+=JNTSIZEOF(t))-JNTSIZEOF(t)))〃(ap+=」NTSIZEOFQ))用于將福針指向下ー個變番〃ー」NTSIZEOF⑴指針值不變,但將地址值改為指向本變量〃*(t*)用于指針類型轉(zhuǎn)換,接著讀取本變量內(nèi)容#defineva_end(ap)(ap=(va_list)0)〃復(fù)篇這是規(guī)范做法,可省展。262.4 指針用作函數(shù)參數(shù)指針用作函數(shù)參數(shù)時具有以下優(yōu)點:.對于用戶自定義的較復(fù)雜數(shù)據(jù)類型(例如結(jié)構(gòu)體、類等),使用指針能夠節(jié)省時間和空間,因只須在棧上復(fù)制指針的副本(只占4個字節(jié))而不是整個數(shù)據(jù)類型的副本(可能多達數(shù)十或數(shù)百個字節(jié))。.可以從子函數(shù)內(nèi)改變子函數(shù)以外的參量。本章§2.9"函數(shù)調(diào)用的基本概念”將詳述此點。[例1]通過指針修改結(jié)構(gòu)體中的子項//ptr_argl.cpp//pointerusedasfunctionargument〃通過指針修改結(jié)構(gòu)中的子項〃只用于教學目的#include<iostream>structperson{intyear;intmonth;intday;doublesalary;〃其它各東);voidmodify(person*ptr,doubleval);〃函數(shù)原型voidmain()(personsample,*ptrl=&sample;modify(ptrl,1234.5);std::cout?sample.salary?,\n,;}voidmodify(person*ptr,doubleval)|ptr->salary=val;}/?Results:1234,5 */下面例子中display()函數(shù)通過指針來調(diào)用不同數(shù)組。サ例2]使用指針作為函數(shù)參數(shù),既顯示成功信息又顯示出錯信息。//err_msg_4.cpp//Pointerusedasfunctionargument#include<iostream>voiddisplay(char**ptr,intnum);char*msg[]={"Coolingwaterrunning!","VentilationOK!","LubricationOK!"};char*err_msg[]={"Nocoolingwater!","Noventilation!","Nolubrication!"};voidmain() 〃只是為了講解(intflag=1;display(msg,flag);flag=-2;display(err_msg,-flag);}voiddisplay(char**ptr,intnum)(,,std::cout?ptr[num-l]?'\n';}/*Results:Coolingwaterrunning!Noventilation!*/此處使用指針后,在調(diào)用函數(shù)display(char**ptr,intnum)時,不必復(fù)制占用很多空間的數(shù)組副本,只需復(fù)制占用很少空間的指針副本。(詳見本章§2.9"函數(shù)調(diào)用的基本概念”)但指針使用并不方便,因此在各種面向?qū)ο蟪绦蛟O(shè)計語言中,“指針”現(xiàn)已逐漸被“引用”(見§2.8“引用”)所取代。263具有返回值的函數(shù)以前提到過,函數(shù)的類型是由函數(shù)的返回值所代表的?,F(xiàn)在看個例子。[例11整型函數(shù)用于求最大值,返回整型值#include<iostream>intmax(inta,intb);voidmain()(inti=l,j=2,result;result=max(i,j);std::cout?MmaxvalueisM?result?,\n,;}intmax(inta,intb)(intresult;result=a>b?a:b;returnresult;}/*Result:maxvalueis2 */由于函數(shù)的返回值是整型變量,因此我們稱max為整型函數(shù)。另外,函數(shù)max()可簡化為:intmax(inta,intb)(returna>b?a:b;}264 函數(shù)與宏的區(qū)別下面具體看一下宏與函數(shù)的區(qū)別:宏節(jié)省時間但占用空間;函數(shù)節(jié)省空間但增加時間開銷!宏的例子:(此程序示意用,不能上機)#include<iostream>#definecubrt(x) (用于求解double型數(shù)據(jù)的立方根的程序塊,至少數(shù)十條語句)voidmain()(doublex=8.0,y=64.0,z=125.0;std::cout?cubrt(x)?endl;std::cout?cubrt(y)?endl;std::cout?cubrt(z)?endl;

/*Results:24函數(shù)的例子(相同功能):(此程序示意用,不能上機)#include<iostream>doublecuberoot(double);〃函數(shù)原型voidmain()(doublex=8.0,y=64.0,z=125.0;std::cout?cuberoot(x)?endl;std::cout?cuberoot(y)?endl;std::cout?cuberoot(z)?endl;)doublecuberoot(doublei)(用于求解double型數(shù)據(jù)的立方根的程序塊,至少數(shù)十條語句)/*Results:245 */宏調(diào)用 函數(shù)調(diào)用voidmain()voidmain()voidmain()cuberoot(x)cuberoot(y)cuberoot(z)doublecuberoot(doublei)求立方根的程序塊cuberoot(x)cuberoot(y)cuberoot(z)doublecuberoot(doublei)求立方根的程序塊(例如有一百多條語句)cubrt(x)求立方根的程序塊(例如有一百多條語句)cubrt(y)

求立方根的程序塊(例如有一百多條語句)cubrt(z)求立方根的程序塊(例如有一百多條語句)265 函數(shù)指針與其指針數(shù)組函數(shù)既然有地址,就可以具有指針。[例1]函數(shù)指針//fun_ptr_l.cpp//Toshowtheuseofafunctionpointer#include<iostream>voidfun();voidmain()void(*ptr)()=fun; 〃ptr即函數(shù)指針,指向函數(shù)fun〃?uuiva121111。''void(*p—)(and"ptr-fun;“ptr();}voidfun()(std::cout?Mfun()iscalle

溫馨提示

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

評論

0/150

提交評論