這邊我直接舉一個例子
下例中,我生成十個學生的原始成績(score),並將所有學生的原始成績都加上五(num) 變為 new_score ( new_score = score + 5)
#include "stdio.h"
#include "stdlib.h"
#define numberStudent 10
#define Num 5
typedef struct _Student{
int No;
int score;
int (*calScore_func)(int, int);/* function pointer 注意括弧的位置,不可更動否則含義不同*/
int new_score;
}Student, *PTR_Student;
/*function prototype 此函數後續用來提供 Student 內的 (*calScore_func) 註冊使用 */
int calScore(int score, int AddNum);
int main()
{
PTR_Student studentTemp = NULL;
studentTemp = (PTR_Student)calloc(sizeof(Student)*numberStudent, 1);
if (studentTemp == NULL){ /* 確定記憶體空間足夠配置 */
printf("Allocate the memory fail.");
return -1;
}
else { printf("Allocate the memory success.\r\n\n"); }
int* memoryBeginAddr = studentTemp; /*儲存一下 calloc 回傳的位址,隨意用一個一般的指標變數儲存即可*/
for (int i = 1; i <= numberStudent; i++){
studentTemp->No = i;
studentTemp->score = i*10;
studentTemp->calScore_func = calScore; /* 註冊 calScore_func 指向函數 calScore*/
/* PS : 函數的名稱與陣列的名稱相同,事實上都被 C 語言單純的視為一個記憶體位址 */
studentTemp->new_score = studentTemp->calScore_func(studentTemp->score, Num);
studentTemp++;
}
studentTemp = memoryBeginAddr;
for (int i = 1; i <= numberStudent; i++){
printf("student No. %d, score : %d, new_score : %d\r\n\n",
studentTemp->No, studentTemp->score, studentTemp->new_score);
studentTemp++;
}
//free(studentTemp); /* 注意 free 的對象應該要是當初 malloc 回傳的位址*/
free(memoryBeginAddr);
return 0;
}
int calScore(int score, int AddNum){
return (score + AddNum);
}
以前我學到這裡的時候覺得這東西太複雜了,一點實際用處也沒有
但真正去工作後才發現這東西有很大的用處
舉個例子,如果我們要對 No.5 的同學成績做不一樣的處理呢?
在最小幅度改動原本程式碼的前提下(此點尤為重要,因為一個產品的改朝換代是不允許大幅度修改程式的)
我們只需要加一個 if 判斷式就可以直接讓 No.5 同學在成績修改的部份改用另一個算式
#include "stdio.h"
#include "stdlib.h"
#define numberStudent 10
#define Num 5
typedef struct _Student{
int No;
int score;
int (*calScore_func)(int, int);/* function pointer 注意括弧的位置,不可更動否則含義不同*/
int new_score;
}Student, *PTR_Student;
/* function prototype 此函數後續用來提供 Student 內的 (*calScore_func) 註冊使用 */
int calScore(int score, int AddNum);
/* 新增一個函數,其與 calScore 有著一模一樣的輸入變數型態(皆為兩個 int),但在計算的時候我們動點手腳*/
int calScore_special(int score, int muti_Num);
int main()
{
PTR_Student studentTemp = NULL;
studentTemp = (PTR_Student)calloc(sizeof(Student)*numberStudent, 1);
if (studentTemp == NULL){ /* 確定記憶體空間足夠配置 */
printf("Allocate the memory fail.");
return -1;
}
else { printf("Allocate the memory success.\r\n\n"); }
int* memoryBeginAddr = studentTemp; /*儲存一下 calloc 回傳的位址,隨意用一個一般的指標變數儲存即可*/
for (int i = 1; i <= numberStudent; i++){
studentTemp->No = i;
studentTemp->score = i*10;
studentTemp->calScore_func = calScore; /* 註冊 calScore_func 指向函數 calScore*/
/* PS : 函數的名稱與陣列的名稱相同,事實上都被 C 語言單純的視為一個記憶體位址 */
if ( i == 5 ) { studentTemp->calScore_func = calScore_special; } /*指向不一樣的函數*/
studentTemp->new_score = studentTemp->calScore_func(studentTemp->score, Num);/*此行完全不變*/
studentTemp++;
}
studentTemp = memoryBeginAddr;
for (int i = 1; i <= numberStudent; i++){
printf("student No. %d, score : %d, new_score : %d\r\n\n",
studentTemp->No, studentTemp->score, studentTemp->new_score);
studentTemp++;
}
//free(studentTemp); /* 注意 free 的對象應該要是當初 malloc 回傳的位址*/
free(memoryBeginAddr);
return 0;
}
int calScore(int score, int AddNum){
return (score + AddNum);
}
int calScore_special(int score, int muti_Num){
return (score * muti_Num);
}
我將定期推出程式語言的新手教學影片