關於C之函式指標及typedef簡介

2021-09-29 11:25:46 字數 4228 閱讀 8326

先看乙個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 *)

下面給出乙個使用函式指標的完整例子:

#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;

}

注意, toupper()、 tolower()、 transpose()和 dummy()函式的型別都相同, 所以這 4 個函式都可以賦給pfun指標。

這種情況下, 可以使用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迴圈:

index = showmenu();

while (index >= 0 && index <= 3)

上面提到typedef,下面簡要介紹一下它的用法:

typedef工具是乙個高階資料特性, 利用typedef可以為某一型別自定義名稱。 

1.定義型別別名(包括結構):

typedef unsigned char byte;

可以這樣使用:

byte x, y[10], * z;

typedef struct rect;

可以這樣使用:

rect r1 = ;

rect r2 = r1;

2.定義複雜型別(如陣列、指標、函式):

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 二 指向...