先看乙個c標準庫中的乙個函式qsort(),它的功能是對任何型別的陣列進行排序。
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
引數:
其中形參compar就是乙個函式指標。
我們先看乙個使用qsort()函式的例子:
#include #include int cmpfunc (const void * a, const void * b);
int values = ;
int main()
qsort(values, sizeof(values) - 1, sizeof(int), cmpfunc);
printf("\n排序之後的列表:\n");
for( n = 0 ; n < 5; n++ )
return(0);
}int cmpfunc (const void * a, const void * b)
我們可以看到函式名即是指向函式的指標。排序之前的列表:
88 56 100 2 25
排序之後的列表:
2 25 56 88 100
我們分析一下comfunc()函式的演算法:
由於qsort()函式是可以排序任意型別的陣列的,所以形參是void型別的指標。
關於c之運算子優先順序
查表可知:
優化級:* < (type)純量表示式。所以*(int*)a:先void指標變數a強制轉化為int型別的指標,然後通過*運算子取它的int型值,這樣才可以進行比較。
考慮下面的函式原型:
void toupper(char *); // 把字串中的字元轉換成大寫字元
toupper()函式的型別是「帶char * 型別引數、 返回型別是void的函式」。下面宣告了乙個指標pf指向該函式型別:
void (*pf)(char *); // pf 是乙個指向函式的指標
作為函式的引數是資料指標最常見的用法之一, 函式指標亦如此。 例如, 考慮下面的函式原型:void toupper(char *);
void tolower(char *);
int round(double);
void (*pf)(char *);
pf = toupper; // 有效, toupper是該型別函式的位址
pf = tolower; //有效, toupper是該型別函式的位址
pf = round; // 無效, round與指標型別不匹配
pf = tolower(); // 無效, tolower()不是位址
void show(void (* fp)(char *), char * str);
show()函式有兩個引數:1.fp(指向的函式授受char *型別的引數,返回型別為void),2.str(指向乙個char型別的值)。
有以上宣告,可以這樣呼叫:
可以用函式指標直接呼叫函式:show(tolower, mis); /* show()使用tolower()函式: fp = tolower */
show(pf, mis); /* show()使用pf指向的函式: fp = pf */
下面給出乙個使用函式指標的完整例子:int main()
char * toupper(char *)
注意, toupper()、 tolower()、 transpose()和 dummy()函式的型別都相同, 所以這 4 個函式都可以賦給pfun指標。#include #include #include #define len 81
char* s_gets(char *st, int n);
char showmenu(void);
void eatline(void); // 讀取至行末尾
void show(void (*fp)(char*), char *str);
void toupper(char*); // 把字串轉換為大寫
void tolower(char*); // 把字串轉換為小寫
void transpose(char*); // 大小寫轉置
void dummy(char*); // 不更改字串
int main(void)
strcpy(copy, line); // 為show()函式拷貝乙份
show(pfun, copy); // 根據使用者的選擇, 使用選定的函式
} puts("enter a string (empty line to quit):");
} puts("bye!");
return 0;
}char showmenu(void)
return ans;
}void eatline(void)
void toupper(char *str)
}void tolower(char *str)
}void transpose(char *str)
}void dummy(char *str) {} //不改變字串
void show(void (*fp)(char*), char *str)
char* s_gets(char *st, int n)
return ret_val;
}
這種情況下, 可以使用typedef。 例如, 該程式中可以這樣寫:
如果還想更複雜一些, 可以宣告並初始化乙個函式指標的陣列:typedef void (*v_fp_charp)(char *);
void show (v_fp_charp fp, char *);
v_fp_charp pfun;
v_fp_charp arpf[4] = ;
然後把showmenu()函式的返回型別改為int, 如果使用者輸入u, 則返回0;如果使用者輸入l, 則返回2; 如果使用者輸入t, 則返回2, 以此類推。 可以把程式中的switch語句替換成下面的while迴圈:
上面提到typedef,下面簡要介紹一下它的用法:index = showmenu();
while (index >= 0 && index <= 3)
typedef工具是乙個高階資料特性, 利用typedef可以為某一型別自定義名稱。
1.定義型別別名(包括結構):
2.定義複雜型別(如陣列、指標、函式):typedef unsigned char byte;
可以這樣使用:
byte x, y[10], * z;
typedef struct rect;
可以這樣使用:
rect r1 = ;
rect r2 = r1;
typedef int arr5[5];
typedef arr5 * p_arr5;
typedef p_arr5 arrp10[10];
arr5 togs; // togs 是乙個內含5個int型別值的陣列==【int arr5[5]】
p_arr5 p2; // p2 是乙個指向陣列的指標, 該陣列內含5個int型別的值==【int (*p2)[5]】
arrp10 ap; // ap 是乙個內含10個指標的陣列, 每個指標都指向乙個內含5個int型別值的陣列,
// == 【(*ap[10])[5]】
typedef char (* frptc ()) [5];
註解:把frptc宣告為乙個函式型別, 該函式返回乙個指標, 該指標指向內含5個char型別元素的陣列。
C 之函式指標
首先了解一下基礎知識 學習過c語言之後我們知道,函式是c語言的基本組成單位。函式其實也有他自己 的位址,函式的位址儲存在機器語言的記憶體的開始位址,使用cout來輸出它的位址。如果乙個函式是dosomething 那麼dosomething就是函式的位址。函式指標的申明 方法一 宣告與初始化分開 d...
C 之函式指標
總結 over 文末一句話 函式指標簡介 如果作為乙個屌絲程式設計師,未提到函式指標,則對c或c 函式的不尊重 函式與資料項相似,函式也有位址。函式的位址是儲存其機器語言 的記憶體的開始位址。通常,這些位址對使用者而言,既不重要,也沒有什麼用處,但是對程式而言,卻很有用。例如,可以編寫將另乙個函式的...
C 之函式指標
函式指標常用的有三類 1 指向普通函式的函式指標 2 指向類中靜態成員函式的函式指標 3 指向類的成員函式的函式指標 一 指向普通函式的函式指標 include using namespace std void show typedef void pfun 定義函式指標型別 intmain 二 指向...