題目
傳遞函數的位址
每個變數都有配置特定的記憶體位置,每個陣列也都有配置特定的記憶體位置,那麼函式是不是配置有記憶體位址?答案是肯定的。每個函式都有它的記憶體位置,我們可以使用函式的記憶體位置將一個函式傳入另一個函式中。但是要怎麼做?
首先,我們宣告一個函式的指標變數,用來存放函式的記憶體位址, 例如
int (*ptr)(int,int);
接著就可以把這個指標變數指向所有相同宣告原型的函式(具有兩個int資料型別的傳遞參數和int傳回型別)。
請嘗試設計一個函式其輸入為兩個指標陣列,並且函示會根據其輸入的指標函示作為依據執行,範例請看
int* mergearray(int* arr1, int* arr2, int length, int(*ptr)(int,int)){
...
}
mergearray須提供的功能有1. add、2. sub、3. mul,三樣所以各位需要再額外寫出三個函示,提供參照,範例請看
int add(int a,int b){
...
}
int sub(int a, int b){
...
}
int mul(int a,int b){
...
}
例一:
input自此始,但不包括此行
6
7 3 2 1 5 0
8 6 7 3 2 2
add
input至此止,但不包括此comment
output自此始,但不包括此行
15 9 9 4 7 2
完整程式碼
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int add(int a,int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
int mul(int a,int b){
return a*b;
}
int* mergearray(int* arr1, int* arr2, int length, int(*ptr)(int,int)){
for(int i=0;i<length;i++){
int num1 = *(arr1+i);
int num2 = *(arr2+i);
printf("%d ",ptr(num1,num2));
}
cout << endl ;
}
int main(){
int inputLength;
cin >> inputLength;
int arr1[inputLength];
int arr2[inputLength];
int (*funcptr)(int,int); // function pointer declaration
char sign[10]; //add/sub/mul
for(int i=0;i<inputLength;i++){
cin >> arr1[i];
}
for(int i=0;i<inputLength;i++){
cin >> arr2[i];
}
//input add/sub/mul
cin >> sign;
string s;
s=sign;
if (s.compare("add") == 0) funcptr=add;
else if (s.compare("sub") == 0) funcptr=sub;
else if (s.compare("mul") == 0) funcptr=mul;
//以function pointer將function當作參數傳遞
mergearray((int*)arr1,(int*)arr2,inputLength,funcptr);
}
解題觀念&思路
reference : https://www.javatpoint.com/function-pointer-in-cpp
1.建立初始變數
int inputLength;
cin >> inputLength;
int arr1[inputLength];
int arr2[inputLength];
int (*funcptr)(int,int); // function pointer declaration
char sign[10]; //add/sub/mul
for(int i=0;i<inputLength;i++){
cin >> arr1[i];
}
for(int i=0;i<inputLength;i++){
cin >> arr2[i];
}
array1,array2存好輸入的元素值
並定義好函數指標變數 funcptr
和輸入add/sub/mul的char[] sign
2.以''函數的指標''型態來定義變數
定義語法
[回傳值型態] (*函數名稱) (datatype arg1, datatype arg2,...);
e.g.
int (*funcptr)(int,int);
標示funcptr可以為function的變數
這個function的返回值為int , 輸入值為兩個int
所以假設
int add(int a,int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
int mul(int a,int b){
return a*b;
}
int main(){
int (*funcptr)(int,int);
funcptr=add;
int num = funcptr(5,5); //return 10
funcptr=sub;
int num = funcptr(5,5); //return 0
funcptr=mul;
int num = funcptr(5,5); //return 25
}
函數指數帶入參數
用跟上面宣告一樣的型態:
void func(int n1,int n2,int (*ptr)(int,int)){
int ans = ptr(5,5); //return 10
}
int main(){
int n1;
int n2;
...
int (*funcptr)(int,int);
funcptr = add;
func(n1,n2,funcptr);
}
因此我們的mergearray接到已經定義好的函數變數(add/sub/mul)
就能以ptr去使用傳進來的函數
int* mergearray(int* arr1, int* arr2, int length, int(*ptr)(int,int)){
for(int i=0;i<length;i++){
int num1 = *(arr1+i);
int num2 = *(arr2+i);
printf("%d ",ptr(num1,num2));
}
cout << endl ;
}