




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第一起來(lái)學(xué)習(xí)C++的函數(shù)指針和函數(shù)對(duì)象目錄函數(shù)指針函數(shù)對(duì)象總結(jié)
函數(shù)指針
以下是cstdlib庫(kù)中的一個(gè)排序數(shù)組的方法qsort()的函數(shù)原型。
voidqsort(void*base,size_tnum,size_tsize,
int(*compar)(constvoid*,constvoid*));
base--指向要排序的數(shù)組的第一個(gè)元素的指針。num--由base指向的數(shù)組中元素的個(gè)數(shù)。size--數(shù)組中每個(gè)元素的大小,以字節(jié)為單位。compar--用來(lái)比較兩個(gè)元素的函數(shù)。
對(duì)于可以使用常規(guī)關(guān)系運(yùn)算符進(jìn)行比較的類型,常規(guī)比較函數(shù)可能如下所示:
intcompareMyType(constvoid*a,constvoid*b){
if(*(MyType*)a*(MyType*)b)return-1;
if(*(MyType*)a==*(MyType*)b)return0;
if(*(MyType*)a*(MyType*)b)return1;
}
#includecstdlib
#includeiostream
intcmpfunc(constvoid*a,constvoid*b);
usingnamespacestd;
intmain(){
intvalues[]={88,56,100,2,25};
qsort(values,sizeof(values)/sizeof(int),sizeof(int),cmpfunc);
cout"排序之后的列表:"endl;
for(intn=0;nn++){
coutvalues[n]"";
return0;
intcmpfunc(constvoid*a,constvoid*b){
return(*(int*)a-*(int*)b);
}
Enterastring(emptylinetoquit):|abcEnter
Entermenuchoice:
u)uppercasel)lowercase
t)transposedcaseo)originalcase
n)nextstring
Pleaseenteru,l,t,o,orn:
|uEnter
Entermenuchoice:
u)uppercasel)lowercase
t)transposedcaseo)originalcase
n)nextstring
Pleaseenteru,l,t,o,orn:
|lEnter
abc
#includecstdio
#includecstring
#includestring
#includecctype
#includeiostream
#defineLEN81
charshowmenu();
voidshow(void(*fp)(char*),char*str);
voidToUpper(char*);//把字符串轉(zhuǎn)換為大寫
voidToLower(char*);//把字符串轉(zhuǎn)換為小寫
voidTranspose(char*);//大小寫轉(zhuǎn)置
voidDummy(char*);//不更改字符串
usingnamespacestd;
intmain(){
charline[LEN];
charcopy[LEN];
charchoice;
void(*pfun)(char*);//聲明一個(gè)函數(shù)指針,被指向的函數(shù)接受char*類型的參數(shù),無(wú)返回值
cout"Enterastring(emptylinetoquit):";
while(cinline){
while((choice=showmenu())!='n'){
switch(choice){//switch語(yǔ)句設(shè)置指針
case'u':
pfun=ToUpper;
break;
case'l':
pfun=ToLower;
break;
case't':
pfun=Transpose;
break;
case'o':
pfun=Dummy;
break;
strcpy(copy,line);//為show()函數(shù)拷貝一份
show(pfun,copy);//根據(jù)用戶的選擇,使用選定的函數(shù)
cout"Enterastring(emptylinetoquit):";
cout"Bye!";
return0;
charshowmenu(){
charans;
cout"Entermenuchoice:"endl;
cout"u)uppercasel)lowercase"endl;
cout"t)transposedcaseo)originalcase"endl;
cout"n)nextstring"endl;
ans=getchar();//獲取用戶的輸入
ans=tolower(ans);//轉(zhuǎn)換為小寫
while(strchr("ulton",ans)==NULL){
cout"Pleaseenteru,l,t,o,orn:"endl;
ans=tolower(getchar());
returnans;
voidshow(void(*fp)(char*),char*str){
(*fp)(str);//把用戶選定的函數(shù)作用于str
coutstrendl;//顯示結(jié)果
voidToUpper(char*str){
while(*str){
*str=toupper(*str);
str++;
voidToLower(char*str){
while(*str){
*str=tolower(*str);
str++;
voidTranspose(char*str){
while(*str){
if(islower(*str))
*str=toupper(*str);
elseif(isupper(*str))
*str=tolower(*str);
str++;
voidDummy(char*str){
}//不改變字符串
函數(shù)對(duì)象
函數(shù)對(duì)象是專門設(shè)計(jì)用于語(yǔ)法與函數(shù)相似的對(duì)象。在C++中,這是通過(guò)在類中定義成員函數(shù)operator()來(lái)實(shí)現(xiàn)的,例如:
structmyclass{
intoperator()(inta){
returna;
}myobject;
intx=myobject(0);
它們通常用作函數(shù)的參數(shù),例如傳遞給標(biāo)準(zhǔn)算法的謂詞或比較函數(shù)。
標(biāo)準(zhǔn)庫(kù)預(yù)先定義了些functionobject。所謂functionobject,是某種class的實(shí)例對(duì)象,這類class對(duì)functioncall運(yùn)算符做了重載操作,如此一來(lái)可使functionobject被當(dāng)成一般函數(shù)來(lái)使用。
functionobject實(shí)現(xiàn)了我們?cè)究赡芤元?dú)立函數(shù)加以定義的事物。但又何必如此呢?
主要是為了效率。我們可以令call運(yùn)算符成為inline,從而消除通過(guò)函數(shù)指針來(lái)調(diào)用函數(shù)時(shí)需要付出的額外代價(jià)。
標(biāo)準(zhǔn)庫(kù)事先定義了一組functionobject,分為:
算術(shù)運(yùn)算(arithmetic)、關(guān)系運(yùn)算(relational)和邏輯運(yùn)算(logical)三大類。
以下列表中的type在實(shí)際使用時(shí)會(huì)替換為內(nèi)置類型或class類型:
6個(gè)算術(shù)運(yùn)算plustype,minustype,negatetype,
multipliestype,dividestype,modulestype
6個(gè)關(guān)系運(yùn)算lesstype,less_equaltype,greatertype,
greater_equaltype,equal_totype,not_equal_totype
3個(gè)邏輯運(yùn)算logical_andtype,logical_ortype,logic_nottype
要使用事先定義的functionobject,首先得包含相關(guān)頭文件:functional
默認(rèn)情況下sort()是升序排列,我們將元素降序排列:
sort(vec.begin(),vec.end(),greaterint
其中的greaterint()會(huì)產(chǎn)生一個(gè)未命名的classtemplateobject,傳給sort()。
binary_search()期望其搜索對(duì)象先經(jīng)過(guò)排序,為了正確搜索vector,就必須傳給它某個(gè)functionobjectobject,供vector排序使用:
binary_search(vec.begin(),vec.end(),elem,greaterint
我們對(duì)Fibonacci數(shù)列可以做些其他操作,如:每個(gè)元素和自身相加、和自身相乘、被加到對(duì)應(yīng)的Pell數(shù)列等等。做法之一是使用泛型算法transform()并搭配plusint和multipliesint。
我們必須傳給transform()的參數(shù)有:
?一對(duì)iterator,標(biāo)示出欲轉(zhuǎn)換的元素范圍;
?一個(gè)iterator,所指元素將應(yīng)用于轉(zhuǎn)換上,元素范圍同?;
?一個(gè)iterator,所指位置(及其后面的空間)用來(lái)存放轉(zhuǎn)換結(jié)果;
?一個(gè)functionobject,表現(xiàn)出我們想要應(yīng)用的轉(zhuǎn)換操作。
以下是將Pell數(shù)列加到Fibonacci數(shù)列的寫法:
transform(fib.begin(),fib.end(),//?
pell.begin(),//?
fib_plus_pell.begin(),//?
plusint//?
transform()的定義:
functiontemplatealgorithmstd::transform
unaryoperation(1)
templateclassInputIterator,classOutputIterator,classUnaryOperation
OutputIteratortransform(InputIteratorfirst1,InputIteratorlast1,
OutputIteratorresult,UnaryOperationop);
binaryoperation(2)
templateclassInputIterator1,classInputIterator2,
classOutputIterator,classBinaryOperation
OutputIteratortransform(InputIterator1first1,InputIterator1last1,
InputIterator2first2,OutputIteratorresult,
BinaryOperationbinary_op);
————————————————————————————————————————————————————
將操作順序應(yīng)用于一(1)或兩(2)個(gè)范圍的元素,并將結(jié)果存儲(chǔ)在從結(jié)果開(kāi)始的范圍中。
(1)一元操作
將op應(yīng)用于[first1,last1]范圍內(nèi)的每個(gè)元素,并將每個(gè)操作返回的值存儲(chǔ)在從result開(kāi)始的范圍內(nèi)。
(2)二元操作
使用范圍[first1,last1]中的每個(gè)元素作為第一個(gè)參數(shù),并使用范圍中從first2開(kāi)始的各個(gè)參數(shù)作為
第二個(gè)參數(shù)來(lái)調(diào)用binary_op。每個(gè)調(diào)用返回的值存儲(chǔ)在從result開(kāi)始的范圍中。
該函數(shù)允許目標(biāo)范圍與其中一個(gè)輸入范圍相同,以便進(jìn)行適當(dāng)?shù)霓D(zhuǎn)換。
函數(shù)對(duì)象適配器:
functionobjectlesstype期望外界傳入兩個(gè)值,如果第一個(gè)值小于第二個(gè)值就返回true。本例中,每個(gè)元素都必須和用戶所指定的數(shù)值進(jìn)行比較。理想情形下,我們需要將lesstype轉(zhuǎn)化為一個(gè)一元(unary)運(yùn)算符。這可通過(guò)將其第二個(gè)參數(shù)綁定(bind)至用戶指定的數(shù)值完成。這么一來(lái)lesstype便會(huì)將每個(gè)元素拿出來(lái)一一與用戶指定的數(shù)值比較。
真的可以做到這樣嗎?是的。標(biāo)準(zhǔn)庫(kù)提供adapter(適配器)便應(yīng)此而生。
functionobjectadapter會(huì)對(duì)functionobject進(jìn)行修改操作。binderadapter(綁定適配器)會(huì)將functionobject的參數(shù)綁定至某特定值,使binary(二元)functionobject轉(zhuǎn)化為unary(一元)functionobject。這正是我們需要的。
標(biāo)準(zhǔn)庫(kù)提供了兩個(gè)binderadapter:
bind1st會(huì)將指定值綁定至第一操作數(shù);
bind2nd將指定值綁定至第二操作數(shù)。
如:ab,則a是第一操作數(shù),b是第二操作數(shù)。
vectorintfilterconstvectorintvec,intval,lessintlt){
vectorintnvec;
vectorint::const_iteratoriter=vec.begin();
while((iter=find_if(iter,vec.end(),bind2nd(lt,val)))!=vec.end()){
nvec.push_back(*iter);
iter++;
returnnvec;
}
bind2nd(less,val);會(huì)把val綁定于lessint的第二個(gè)參數(shù)身上。于是,lessint會(huì)將每個(gè)元素拿來(lái)和val比較。上例第一操作數(shù)是*iter,第二操作數(shù)就是固定值val。如果*iterval則true。
find_if()的定義如下:
templateclassInputIterator,classUnaryPredicate
InputIteratorfind_if(InputIteratorfirst,InputIteratorlast,UnaryPredicatepred);
●first、last:輸入迭代器到序列的初始和最終位置。使用的范圍是[first,last),它包含first和last之間的所有元素,包括first指向的元素,但不包括last指向的元素。
●pred:接受范圍內(nèi)的元素作為參數(shù)并返回可轉(zhuǎn)換為bool類型的值的【一元函數(shù)】。返回的值表明該元素是否被認(rèn)為是此函數(shù)的上下文中的匹配。函數(shù)不能修改它的參數(shù)。它可以是函數(shù)指針,也可以是函數(shù)對(duì)象(functionobject)。
●返回值:指向pred不返回false的范圍內(nèi)第一個(gè)元素的迭代器。如果pred對(duì)所有元素都為false,則函數(shù)返回last。
這個(gè)函數(shù)模板的行為相當(dāng)于:
templateclassInputIterator,classUnaryPredicate
InputIteratorfind_if(InputIteratorfirst,InputIteratorlast,UnaryPredicatepred){
while(first!=last){
if(pred(*first))returnfirst;
++first;
returnlast;
}
下面看一個(gè)泛型函數(shù)find_if()的例子:
#includeiostream//std::cout
#includealgorithm//std::find_if
#includevector//std::vector
boolIsOdd(inti){
return((i%2)==1);
intmain(){
std::vectorintmyvector;
myvector.push_back(10);
myvector.push_back(25);
myvector.push_back(40);
myvector.push_back(55);
std::vectorint::iteratorit=
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 辦公室區(qū)塊鏈技術(shù)的安全性分析與防范
- 企業(yè)房屋包租合同范例
- 個(gè)人公寓傭金合同范例
- 人參購(gòu)銷合同范例
- Office知識(shí)點(diǎn)總結(jié)模版
- 銀行業(yè)法律法規(guī)與綜合能力總結(jié)模版
- 書插畫合作合同范例
- 與物業(yè)續(xù)簽合同范例
- 產(chǎn)品測(cè)試服務(wù)合同范例
- 專線電路合同范例
- 體外診斷試劑標(biāo)準(zhǔn)品、校準(zhǔn)品、質(zhì)控品
- GB/T 3452.4-2020液壓氣動(dòng)用O形橡膠密封圈第4部分:抗擠壓環(huán)(擋環(huán))
- 王力宏-緣分一道橋-歌詞
- (完整版)建筑施工技術(shù)規(guī)范
- 高校電子課件:現(xiàn)代管理學(xué)基礎(chǔ)(第三版)
- 《藥物學(xué)》課程教學(xué)大綱
- 艾滋病感染孕產(chǎn)婦所生兒童艾滋病早期診斷與抗體檢測(cè)流程圖
- 修改版絲竹相和
- 博物館學(xué)概論:第十講 數(shù)字博物館
- 客戶退貨處理流程圖
- RNN+LSTM學(xué)習(xí)資料課件
評(píng)論
0/150
提交評(píng)論