如何理解typedef void (*pfun)(void)
原文地址:https://www.cnblogs.com/guanguangreat/p/6117988.html
問題:
在剛接觸typedef void (*pfun)(void) 這個結構的時候,存在疑惑,為什麼typedef後只有一“塊”東西,而不是兩“塊”東西呢?那是誰“替代”了誰啊?我總結了一下,一方面是對typedef的概念不清晰,另一方面受了#define的影響,犯了定向思維的錯誤。
概念理解:
typedef 只對已有的型別進行別名定義,不產生新的型別;
#define 只是在預處理過程對程式碼進行簡單的替換。
清晰瞭解兩個概念後,發現它們就是兩個不同的概念,並沒有太多的聯絡。
類比理解:
typedef unsigned int UINT32; // UINT32 型別是unsigned int
UINT32 sum; // 定義一個變數:int sum;
typedef int arr[3]; // arr 型別是 int[3];(存放int型資料的陣列)
arr a; // 定義一個數組:int a[3];
同理:
typedef void (*pfun)(void); // pfun 型別是 void(*)(void)
pfun main; // 定義一個函式:void (*main)(void);
在部落格上看到一個經典的函式指標用例:
為保護原創作者的權益,以下例子程式碼不作修改:
#include<stdio.h>
typedef int (*FP_CALC)(int, int);
//注意這裡不是函式宣告而是函式定義,它是一個地址,你可以直接輸出add看看
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 div(int a, int b)
{
return b? a/b : -1;
}
//定義一個函式,引數為op,返回一個指標。該指標型別為 擁有兩個int引數、
//返回型別為int 的函式指標。它的作用是根據操作符返回相應函式的地址
FP_CALC calc_func(char op)
{
switch (op)
{
case '+' : return add; // 返回函式的地址
case '-' : return sub;
case '*' : return mul;
case '/' : return div;
default:
return NULL;
}
return NULL;
}
//s_calc_func為函式,它的引數是 op,返回值為一個擁有兩個int引數、返回型別為int 的函式指標
int (*s_calc_func(char op)) (int, int)
{
return calc_func(op);
}
//終端使用者直接呼叫的函式,該函式接收兩個int整數,和一個算術運算子,返回兩數的運算結果
int calc(int a, int b, char op)
{
FP_CALC fp = calc_func(op); // 根據預算符得到各種運算的函式的地址
int (*s_fp)(int, int) = s_calc_func(op); // 用於測試
// ASSERT(fp == s_fp); // 可以斷言這倆是相等的
if (fp)
return fp(a, b); //根據上一步得到的函式的地址呼叫相應函式,並返回結果
else
return -1;
}
void main()
{
int a = 100, b = 20;
printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));
printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));
printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/'));
}
結合程式碼理解:
程式碼作者在註釋中表述得很清楚,個人覺得最有意思就是一下這個函式:
FP_CALC calc_func(char op) <--> int (*calc_func(char op)) (int, int)
程式碼作者試圖在斷言中說明這個關係,相比較,還是FP_CALC calc_func(char op)函式更能表達編碼者的意圖:calc_func函式返回FP_CALC型別的指標,是一個函式指標,這個函式的形式是int (函式名)(int, int),程式碼中int add(int a, int b)、int sub(int a, int b)…正是這樣的格式。
(修改於 2016-12-22 19:23:37)
在閱讀《C和指標》的時候,我猛然想起還有一個東西叫“函式指標陣列”,也就是書中所描述的新概念:轉移表。
下面是實現一個簡易計算器的核心程式碼:
1 switch(oper){
2 case ADD:
3 result = add(oper1, oper2);
4 break;
5
6 case SUB:
7 result = sub(oper1, oper2);
8 break;
9
10 case MUL:
11 result = mul(oper1, oper2);
12 break;
13
14 case DIV:
15 result = div(oper1, oper2);
16 break;
17 ……
18 }
這是一種我們常用的實現方式,在書中提到有一個最起碼看起來更高階,更簡潔的方法:
1 double add(double, double);
2 double sub(double, double);
3 double mul(double, double);
4 double div(double, double);
5 ……
6 Double (*oper_fun[])(double, double) = {add, sub,mul,div,…};
7 呼叫時:
8 result = oper_func[oper](oper1, oper2);
為什麼要呼叫函式來執行這些操作呢?把具體操作和選擇操作的程式碼分開是一種良好的設計方案。
——《C和指標》
相關推薦
函式指標-如何理解typedef void (*pfun)(void)
問題: 在剛接觸typedef void (*pfun)(void) 這個結構的時候,存在疑惑,為什麼typedef後只有一“塊”東西,而不是兩“塊”東西呢?那是誰“替代”了誰啊?我總結了一下,一方面是對typedef的概念不清晰,另一方面受了#define的影響,犯了定向思維的錯誤。
如何理解typedef void (*pfun)(void)
原文地址:https://www.cnblogs.com/guanguangreat/p/6117988.html問題: 在剛接觸typedef void (*pfun)(void) 這個結構的時候,存在疑惑,為什麼typedef後只有一“塊”東西,而不是兩“塊”東
關於typedef int (init_fnc_t) (void);理解
來源:http://blog.chinaunix.net/uid-22979746-id-2590215.html 位於lib_arm/board.c typedef int (init_fnc_t) (void); //自定義新的資料型別init_
typedef void (*Fun) (void) 的理解——函式指標——typedef函式指標
首先介紹大家比較熟悉的typedef int i;//定義一個整型變數i typedef int myInt; myInt j;//定義一個整型變數j 上面介紹得是我們常用的比較簡單的typedef的用法,下面首先介紹一下函式指標。 函式指標的形式: 形式1:返回
typedef void (*pFunction)(void);講解的特別好,適合新手學習
剛在網上看到的,講解的特別好,適合新手學習,高手請忽略...轉自:http://blog.csdn.net/zyboy2000/article/details/4202349(*(void(*)())0) () 等同 ((void(*)())0) () ----原因
typedef知識點 和 void* test(void*)這個函式作為引數的知識點
typedef void(*fun)(void); void test(void) { std::cout << "111"; } int main() { fun f = &test; (*f)(); return 0; } //第一個是typed
每日程式設計訓練20150909:typedef void (* unitest_func_t) (void);
#include <stdio.h> #include <string.h> typedef void (* unitest_func_t) (void); typedef
C++ Primer 學習筆記與思考_7 void和void*指針的使用方法
能夠 amp space turn begin member use mem urn (一)void的含義 void的字面意思是“無類型”,void差點兒僅僅有“凝視”和限制程序的作用,由於從來沒有人會定義一個void變量,讓我們試著來定義: void a;
void(*p)(void)和void(*p())(void)的區別
scw www spa blank www. rec left href mgo 0頌姿Y3榮qCK釉籃http://huiyi.docin.com/zgy332 I44盎7WMC17司O械狡http://huiyi.docin.com/lpsii596 9Lv昭賭95
void和void*的用法
1、void的作用 c語言中,void為“不確定型別”,不可以用void來宣告變數。如:void a = 10;如果出現這樣語句編譯器會報錯:variable or field ‘a’ declared void。 在C語言中void 常常用於:對函式返回型別的限定和對函式引數限
[轉]C/C++:學習void與void*詳解
void與void*詳解 void 無型別 void* 無型別指標 可以指向任意型別的資料。 void: 1.函式沒有返回值,宣告為void型別 2.函式無引數。 3.函式的引數可以是任意型別的指標 void*。 【void真正發揮的作用在於】: 1)
Java中 java.lang.Void和void 有什麼作用和區別
答:void關鍵字表示函式沒有返回結果,是java中的一個關鍵字。java.lang.Void是一種型別,例如給Void引用賦值null的程式碼為Void nil=null; 。 通過Void類的原始碼可以看到,Void型別不可以繼承與例項化。 final
Void & void Void用在泛型
public Void setStr(String key,String value)throws Exception{ RetryTemplate retryTemplate=initRetryTemplate(); retryTemplate.execute(new RetryCallba
關於void*與void**的區別
由於void就是不檢查資料型別,所以,對於編譯器來說, void* 和 void** ,甚至後面n個 * ,都是一樣的. 問題的關鍵在於,讓我們這些程式設計的人可以區分. 原則上,void* 可以是一個一級指標,二級指標,甚至是n級指標. 但我們的使用習慣是, 一個 * 代表
關於keil卡在systeminit中,然後出現void HardFault_Handler(void)的幾個問題詳解
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u013184273/article/details/83860802 相信很多程式設計師在用keil的時候都會遇到在模擬除錯時,一直停在SystemInit()中的等待晶
java.lang.Void 與 void的比較及使用
void關鍵字表示函式沒有返回結果,是java中的一個關鍵字。 java.lang.Void是一種型別。例如給Void引用賦值null。 Void nil = null; 通過Void類的程式碼可以看到,Void型別不可以繼承與例項化。 public final cl
void type && void pointer(void *,pointer to void type) && Null pointer
void type void pointer(void *,pointer to void type) 1 ANSI C和C ++支援void指標或void *作為通用指標型別。 指向void的指標可
【Linux開發技術之常見問題】一個建立執行緒時常見的問題:invalid conversion from `void*' to `void*(*)(void*)
void main_thread ( void *ptr ) { char *message1 = "Thread 1"; char *message2 = "Thread 2"; pthread_t thread3, thread4; int iret3, iret4;
C/C++中的void和void*
一、void void關鍵字表示“空型別”的概念。但是,這裡的“空型別”不表示“任意型別”,而是表示不存在的意思,也就是說C/C++不允許你寫語句void a,不存在型別為void的東西. void表示“不存在”的意思,可以從void的兩個應用中加以體現: 1、void作為
void和void*的用法總結和注意點
void的字面意思是空型別,void *的意思是空型別指標,void 不是一個真正的型別,我們在宣告變數的時候從來不會像下面這樣宣告: void a; 如果我們寫了一行這樣的程式碼,某些編譯器會直接報錯,有些則不會,但也沒有任何意義。 void真正的用途在下面兩個