欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一起來(lái)學(xué)習(xí)C++的函數(shù)指針和函數(shù)對(duì)象

 更新時(shí)間:2022年03月21日 10:48:05   作者:itzyjr  
這篇文章主要為大家詳細(xì)介紹了C++函數(shù)指針和函數(shù)對(duì)象,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

函數(shù)指針

以下是<cstdlib>庫(kù)中的一個(gè)排序數(shù)組的方法qsort()的函數(shù)原型。

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*, const void*));
  • 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ù)可能如下所示:

int compareMyType (const void * a, const void * b) {
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}
#include <cstdlib>
#include <iostream>
int cmpfunc (const void* a, const void* b);
using namespace std;
int main() {
	int values[] = { 88, 56, 100, 2, 25 };
	qsort(values, sizeof(values)/sizeof(int), sizeof(int), cmpfunc);
	cout << "排序之后的列表:" << endl;
	for(int n = 0 ; n < 5; n++ ) {
		cout << values[n] << " ";
	}
	return 0;
}
int cmpfunc (const void* a, const void* b) {
	return ( *(int*)a - *(int*)b );
}
Enter a string (empty line to quit):|abc<Enter>
Enter menu choice:
u) uppercase l) lowercase
t) transposed case o) original case
n) next string
Please enter u, l, t, o, or n:
|u<Enter>
ABC
Enter menu choice:
u) uppercase l) lowercase
t) transposed case o) original case
n) next string
Please enter u, l, t, o, or n:
|l<Enter>
abc
#include <cstdio>
#include <cstring>
#include <string>
#include <cctype>
#include <iostream>
#define LEN 81
char showmenu();
void show(void (* fp)(char*), char* str);
void ToUpper(char*); // 把字符串轉(zhuǎn)換為大寫
void ToLower(char*); // 把字符串轉(zhuǎn)換為小寫
void Transpose(char*); // 大小寫轉(zhuǎn)置
void Dummy(char*); // 不更改字符串
using namespace std;
int main() {
	char line[LEN];
	char copy[LEN];
	char choice;
	void (* pfun)(char*); // 聲明一個(gè)函數(shù)指針, 被指向的函數(shù)接受char *類型的參數(shù), 無(wú)返回值
	cout << "Enter a string (empty line to quit):";
	while (cin >> line) {
		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 << "Enter a string (empty line to quit):";
	}
	cout << "Bye!";
	return 0;
}
 
char showmenu() {
	char ans;
	cout << "Enter menu choice:" << endl;
	cout << "u) uppercase l) lowercase" << endl;
	cout << "t) transposed case o) original case" << endl;
	cout << "n) next string" << endl;
	ans = getchar(); // 獲取用戶的輸入
	ans = tolower(ans); // 轉(zhuǎn)換為小寫
	while (strchr("ulton", ans) == NULL) {
		cout << "Please enter u, l, t, o, or n:" << endl;
		ans = tolower(getchar());
	}
	return ans;
}
void show(void (* fp)(char*), char* str) {
	(*fp)(str); // 把用戶選定的函數(shù)作用于str
	cout << str << endl; // 顯示結(jié)果
}
void ToUpper(char* str) {
	while (*str) {
		*str = toupper(*str);
		str++;
	}
}
void ToLower(char* str) {
	while (*str) {
		*str = tolower(*str);
		str++;
	}
}
void Transpose(char* str) {
	while (*str) {
		if (islower(*str))
			*str = toupper(*str);
		else if (isupper(*str))
			*str = tolower(*str);
		str++;
	}
}
void Dummy(char* str) {
} //不改變字符串

函數(shù)對(duì)象

函數(shù)對(duì)象是專門設(shè)計(jì)用于語(yǔ)法與函數(shù)相似的對(duì)象。在C++中,這是通過(guò)在類中定義成員函數(shù)operator()來(lái)實(shí)現(xiàn)的,例如:

struct myclass {
	int operator()(int a) {
		return a;
	}
} myobject;
 
int x = myobject(0);

它們通常用作函數(shù)的參數(shù),例如傳遞給標(biāo)準(zhǔn)算法的謂詞或比較函數(shù)。

標(biāo)準(zhǔn)庫(kù)預(yù)先定義了些function object。所謂function object,是某種class的實(shí)例對(duì)象,這類class對(duì)function call運(yùn)算符做了重載操作,如此一來(lái)可使function object被當(dāng)成一般函數(shù)來(lái)使用。

function object實(shí)現(xiàn)了我們?cè)究赡芤元?dú)立函數(shù)加以定義的事物。但又何必如此呢?
主要是為了效率。我們可以令call運(yùn)算符成為inline,從而消除“通過(guò)函數(shù)指針來(lái)調(diào)用函數(shù)”時(shí)需要付出的額外代價(jià)。

標(biāo)準(zhǔn)庫(kù)事先定義了一組function object,分為:

算術(shù)運(yùn)算(arithmetic)、關(guān)系運(yùn)算(relational)和邏輯運(yùn)算(logical)三大類。

以下列表中的type在實(shí)際使用時(shí)會(huì)替換為內(nèi)置類型或class類型:

6個(gè)算術(shù)運(yùn)算

plus<type>,minus<type>,negate<type>,

multiplies<type>,divides<type>,modules<type>

6個(gè)關(guān)系運(yùn)算

less<type>,less_equal<type>,greater<type>,

greater_equal<type>,equal_to<type>,not_equal_to<type>

3個(gè)邏輯運(yùn)算logical_and<type>,logical_or<type>,logic_not<type>

要使用事先定義的function object,首先得包含相關(guān)頭文件:<functional>

默認(rèn)情況下sort()是升序排列,我們將元素降序排列:

sort(vec.begin(), vec.end(), greater<int>());

其中的greater<int>()會(huì)產(chǎn)生一個(gè)未命名的class template object,傳給sort()。

binary_search()期望其搜索對(duì)象先經(jīng)過(guò)排序,為了正確搜索vector,就必須傳給它某個(gè)function object object,供vector排序使用:

binary_search(vec.begin(), vec.end(), elem, greater<int>());

我們對(duì)Fibonacci數(shù)列可以做些其他操作,如:每個(gè)元素和自身相加、和自身相乘、被加到對(duì)應(yīng)的Pell數(shù)列等等。做法之一是使用泛型算法transform()并搭配plus<int>和multiplies<int>。

我們必須傳給transform()的參數(shù)有:

?一對(duì)iterator,標(biāo)示出欲轉(zhuǎn)換的元素范圍;

?一個(gè)iterator,所指元素將應(yīng)用于轉(zhuǎn)換上,元素范圍同?;

?一個(gè)iterator,所指位置(及其后面的空間)用來(lái)存放轉(zhuǎn)換結(jié)果;

?一個(gè)function object,表現(xiàn)出我們想要應(yīng)用的轉(zhuǎn)換操作。

以下是將Pell數(shù)列加到Fibonacci數(shù)列的寫法:

transform(fib.begin(), fib.end(), //?
          pell.begin(),           //?
          fib_plus_pell.begin(),  //?
          plus<int>);             //?

transform()的定義:

function template <algorithm> std::transform

unary operation(1)	
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform(InputIterator first1, InputIterator last1,
                         OutputIterator result, UnaryOperation op);
binary operation(2)	
template <class InputIterator1, class InputIterator2,
          class OutputIterator, class BinaryOperation>
OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, OutputIterator result,
                         BinaryOperation binary_op);
————————————————————————————————————————————————————
將操作順序應(yīng)用于一(1)或兩(2)個(gè)范圍的元素,并將結(jié)果存儲(chǔ)在從結(jié)果開始的范圍中。
(1) 一元操作
將op應(yīng)用于[first1,last1]范圍內(nèi)的每個(gè)元素,并將每個(gè)操作返回的值存儲(chǔ)在從result開始的范圍內(nèi)。
(2) 二元操作
使用范圍[first1,last1]中的每個(gè)元素作為第一個(gè)參數(shù),并使用范圍中從first2開始的各個(gè)參數(shù)作為
第二個(gè)參數(shù)來(lái)調(diào)用binary_op。每個(gè)調(diào)用返回的值存儲(chǔ)在從result開始的范圍中。
 
該函數(shù)允許目標(biāo)范圍與其中一個(gè)輸入范圍相同,以便進(jìn)行適當(dāng)?shù)霓D(zhuǎn)換。

函數(shù)對(duì)象適配器:

function object less<type>期望外界傳入兩個(gè)值,如果第一個(gè)值小于第二個(gè)值就返回true。本例中,每個(gè)元素都必須和用戶所指定的數(shù)值進(jìn)行比較。理想情形下,我們需要將less<type>轉(zhuǎn)化為一個(gè)一元(unary)運(yùn)算符。這可通過(guò)“將其第二個(gè)參數(shù)綁定(bind)至用戶指定的數(shù)值”完成。這么一來(lái)less<type>便會(huì)將每個(gè)元素拿出來(lái)一一與用戶指定的數(shù)值比較。

真的可以做到這樣嗎?是的。標(biāo)準(zhǔn)庫(kù)提供adapter(適配器)便應(yīng)此而生。

function object adapter會(huì)對(duì)function object進(jìn)行修改操作。binder adapter(綁定適配器)會(huì)將function object的參數(shù)綁定至某特定值,使binary(二元) function object轉(zhuǎn)化為unary(一元)function object。這正是我們需要的。

標(biāo)準(zhǔn)庫(kù)提供了兩個(gè)binder adapter

bind1st會(huì)將指定值綁定至第一操作數(shù);

bind2nd將指定值綁定至第二操作數(shù)。

如:a < b,則a是第一操作數(shù),b是第二操作數(shù)。

vector<int> filter<const vector<int> &vec, int val, less<int> &lt) {
	vector<int> nvec;
	vector<int>::const_iterator iter = vec.begin();
	while ((iter = find_if(iter, vec.end(), bind2nd(lt, val))) != vec.end()) {
		nvec.push_back(*iter);
		iter++;
	}
	return nvec;
}

bind2nd(less, val);會(huì)把val綁定于less<int>的第二個(gè)參數(shù)身上。于是,less<int>會(huì)將每個(gè)元素拿來(lái)和val比較。上例第一操作數(shù)是*iter,第二操作數(shù)就是固定值val。如果*iter<val則true。

find_if()的定義如下:

template <class InputIterator, class UnaryPredicate>
InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred);
●first、last:輸入迭代器到序列的初始和最終位置。使用的范圍是[first,last),它包含first和last之間的所有元素,包括first指向的元素,但不包括last指向的元素。
●pred:接受范圍內(nèi)的元素作為參數(shù)并返回可轉(zhuǎn)換為bool類型的值的【一元函數(shù)】。返回的值表明該元素是否被認(rèn)為是此函數(shù)的上下文中的匹配。 函數(shù)不能修改它的參數(shù)。 它可以是函數(shù)指針,也可以是函數(shù)對(duì)象(function object)。
●返回值:指向pred不返回false的范圍內(nèi)第一個(gè)元素的迭代器。 如果pred對(duì)所有元素都為false,則函數(shù)返回last。
這個(gè)函數(shù)模板的行為相當(dāng)于:
template<class InputIterator, class UnaryPredicate>
InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred) {
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

下面看一個(gè)泛型函數(shù)find_if()的例子:

#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector
bool IsOdd (int i) {
  return ((i%2)==1);
}
int main () {
  std::vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);
  std::vector<int>::iterator it = std::find_if(myvector.begin(), myvector.end(), IsOdd);
  std::cout << "The first odd value is " << *it << '\n';
  return 0;
}
The first odd value is 25

看一個(gè)bind2nd()和bind1st()的例子:

#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main () {
	int numbers[] = {10,-20,-30,40,-50};
	int cx = count_if(numbers, numbers+5, bind2nd(less<int>(), 0));
	cout << "There are " << cx << " negative elements.\n";
	return 0;
}
There are 3 negative elements.
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main () {
	int numbers[] = {10,-20,-30,40,-50};
	int cx = count_if(numbers, numbers+5, bind1st(less<int>(), 0));
	cout << "There are " << cx << " positive elements.\n";
	return 0;
}
There are 2 positive elements.

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!   

相關(guān)文章

  • 在VC中隱藏控制臺(tái)程序窗口的實(shí)現(xiàn)代碼

    在VC中隱藏控制臺(tái)程序窗口的實(shí)現(xiàn)代碼

    大家都知道,當(dāng)編寫一個(gè)win32 console application時(shí),當(dāng)運(yùn)行此類程序的時(shí)候默認(rèn)情況下會(huì)有一個(gè)類似dos窗口的console窗口,但是有的時(shí)候我們只想在程序中運(yùn)行一段功能代碼,不希望顯示這個(gè)console窗口,讓代碼執(zhí)行完畢之后程序自動(dòng)退出
    2013-04-04
  • 基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    這篇文章主要介紹了基于C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲,對(duì)于學(xué)習(xí)游戲開發(fā)的朋友相信有一定的借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C++實(shí)現(xiàn)結(jié)束應(yīng)用進(jìn)程小工具

    C++實(shí)現(xiàn)結(jié)束應(yīng)用進(jìn)程小工具

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)結(jié)束應(yīng)用進(jìn)程小工具,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)單鏈表接口函數(shù)全面講解教程

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)單鏈表接口函數(shù)全面講解教程

    這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)單鏈表所有接口函數(shù)的全面講解教程,有需要朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-10-10
  • 基于C語(yǔ)言航班信息查詢與檢索

    基于C語(yǔ)言航班信息查詢與檢索

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言航班信息查詢與檢索,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 詳解C語(yǔ)言中的ttyname()函數(shù)和isatty()函數(shù)的用法

    詳解C語(yǔ)言中的ttyname()函數(shù)和isatty()函數(shù)的用法

    這篇文章主要介紹了C語(yǔ)言中的ttyname()函數(shù)和isatty()函數(shù)的用法,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C語(yǔ)言算法練習(xí)之折半查找的實(shí)現(xiàn)

    C語(yǔ)言算法練習(xí)之折半查找的實(shí)現(xiàn)

    二分查找法(也叫折半查找)其本質(zhì)是分治算法的一種。這篇文章主要介紹了如何利用C語(yǔ)言實(shí)現(xiàn)折半查找,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-05-05
  • 在vscode中快速新建html文件的2種方法總結(jié)

    在vscode中快速新建html文件的2種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于在vscode中快速新建html文件的2種方法,以及如何快速打開HTML文件查看編輯效果的方法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • c++中new的三種用法詳細(xì)解析

    c++中new的三種用法詳細(xì)解析

    以下的是對(duì)c++中new的三種使用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-09-09
  • C++如何去除cpp文件的注釋詳解

    C++如何去除cpp文件的注釋詳解

    在日常工作中,我們會(huì)給c/c++代碼寫上一些注釋,但是往往為了保持最終的代碼盡可能小,我們需要?jiǎng)h除注釋,手動(dòng)刪除太緩慢了,下面這篇文章主要給大家介紹了關(guān)于C++如何去除cpp文件注釋的相關(guān)資料,需要的朋友可以參考下
    2022-09-09

最新評(píng)論