void (*pFunction)(void);


    typedef  void (*pFunction)(void);


     JumpAddress = *(__IO uint32_t*) (DEF_FLASH_AppStartaddr + 4);
     Jump_To_Application = (pFunction) JumpAddress;
     /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) DEF_FLASH_AppStartaddr);
     Jump_To_Application();


    對函數指針有了初次見面。未能理解,現在做簡要分析。
    1、定義一個指向unsigned char 型的指針:如 unsigned char *p;
    2、將一個指針轉化成指向unsigned char型數據的指針,如:(unsigned char*)p;


    3、定義一個類型,該類型為int,並定義一個指向該類型的指針p如, typedef int INT_Typedef; INT_Typedef *p;


    4、定義一個函數指針,該函數無參數,無返回值。typedef void  (*Func)(void);
    typedef 的作用是把已知的類型定義新類型,所以新類型(*Func)(void)的返回值是void。如常見的main(),括號內是main的參數,所以該函數指針指向的函數無形參。其次(*Func)等同於main的地位。所以 Func就是函數指針了。


    綜上所述就可以理解 typedef  void (*pFunction)(void),是定義了一個新類型,該類型是一個函數指針,它指向的函數的形參為void,返回值為void。

如果要指向有參數或者有返回值的函數,則適當修改void的類型的可以了。如果進行定義和初始化應該為:pFunction pFun = &main;當然實際設計中不會將main函數賦值給其他人,這里只是讓人清楚的知道main是個函數名而已。

    5、誤寫成typedef  (void*) Func(void),則應該解釋為,定義了一個新類型,該類型名為Func,Func是一個函數而不是函數指針,該函數的參數為void,返回值是指向void的指針。如果賦值應為:extern void * Func1(void)(); Func  fun = Func1;

 

整理來源:http://zhidao.baidu.com/link?url=lYBzk1BiYAVy20H4HBOXqAC70E0o616Z0HvvOQeP-2PCoFTjTWZXr-_c1At2OyfyULfUPD4BkVbOFtLSDdzH7q
void (*p)()是一個指向函數的指針,表示是一個指向函數入口的指地變量,該函數的返回類型是void類型。它的用法可參看下例:
例如:有一返加void值的函數swap,(swap用來交換兩個數)
void (*p)();    /*定義指向函數的指針變量p*/
p=swap;    /*使指針變量p指向函數max*/
(*p)(a,b);   /*通過指針變量p調用函數max*/
它等價於:
swap(a,b)

void *p()是一個指針型函數,它的函數名為p,返回了一個指針,因為是void,這個指針沒有定義類型,所以返回的是一個通用型指針。
給你舉一個例子:
#include<stdio.h>
int *max(int *p);
void main()
{
    int a[10]={96,23,45,86,79,63,58,36,29,95};
    int *p;
    p=max(a);
    printf(“max=%d\n”,*p);
}
int *max(int *p)
{
     int i,*q=p;
     for(i=1;i<10;i++)
     if(*(p+i)>*q)
          q=p+1;
     return q;
}
 
         
         
        
 
        
整理自:http://www.cnblogs.com/leon3000/archive/2007/11/15/2037989.html
 
        
 
        
 
        

void (*b[10]) (void (*)());

void (*b[10]) (void (*)());

看到這行代碼,相信程序員們都會倒吸一口冷氣吧。如果非常不幸的在維護的代碼中看到類似的表述,除了想辦法找出寫出這種天書的猛人來,只能自己硬着頭皮搞清楚了。

在C和C++中,構造這類聲明表達式只有一條簡單的規則:按照使用的方式來聲明。

C變量的聲明都是由兩部分組成的:類型,以及一組類似表達式的聲明符(declarator)。聲明符類似於表達式,對它求值應該返回一個聲明中給定類型的結果。例如,我們來看一個簡單的聲明:

float f;

這里f就是聲明符,對其求值,應該得到一個float型的數值。

然后看括號的作用,比如:

float ((f));

很簡單,這個聲明的含義就是,((f))的類型為浮點類型。因為括號和f之間沒有其他的修飾了,所以,我們可以推知,f也是浮點型。

再來看稍微復雜點的:

float f();

我們注意到有一個()表達式出現,這個聲明符的含義是一個函數。所以這個聲明的含義就是,f()的求值結果是一個浮點數,也就是說,f是個返回值為浮點數的函數。

OK,這些都很簡單,再看一個:

float *f();

這個就是表示*f()是個浮點表達式,而()的結合優先級高於*,所以,*f()也就是*(f()),f是個函數,返回值是個指針,這個指針指向一個浮點數。

如果*f是先結合的呢?比如:

float (*f)();

這時,f就不是和()結合而成為一個函數名,而是和*結合成為一個指針名,這個指針,是指向函數入口的函數指針,而這個函數,返回值是浮點型。

現在我們知道怎么聲明一個指定類型的變量了。在這個聲明表達式中,把變量名,和聲明末尾的分號去掉,剩余的部分用一個括號整個括起來,這樣就得到了這個變量的類型聲明了,比如:

float (*f)();

這個表示f是一個指向返回值為浮點型的函數指針。而我們把f這個變量名,和最后的;號去掉,就得到:

( float (*)() )

這個就表示,這個表達式是一個類型,即“指向返回值為浮點型的函數的指針”。如果用這個類型去修飾一個變量名,我們就叫它類型轉換符。

現在有了這些預備知識,我們可以回頭看標題的聲明到底是什么意思了:

void (*b[10]) (void (*)());

首先,表達式的后半部分被兩個()分隔開了,我們分別分析它們。( *b[10] ),其中出現了變量名b,很容易就知道,b是一個有10個元素的數組,每個元素都是一個指針。

然后,看(void(*)()),其中沒有出現變量名,所以它代表了一個類型,即“指向返回值為void型的函數的指針“,而我們知道,C語法中,類型修飾符是必須出現在變量名的左邊的,而在整個表達式中這個類型符是在變量名b的右邊,所以, (void(*)())最外層的這個(),表示了定義了一個函數,這個函數有一個參數,就是一個指針,具體來說,就是“指向返回值為void型的函數的指針“。

這樣就很清楚了,b數組里,每一個指針元素,都是一個函數指針,這個函數有一個參數,這個參數是一個函數指針。整個表達式最左邊的void,則定義了b數組中函數指針所指向函數的返回值類型。

在一串繞口令式的解說后,我們終於看到了事實的真相:這行代碼就是逗你玩...

如果不是故意偷懶,這樣代碼的作者真是在玩弄閱讀者的感情,如果非要實現這樣一個復雜的定義的話,我們也是有更好的方法的,就是使用typedef來進行類型聲明。

在面對void (*b[10]) (void (*)());時,我們可以先聲明后半部分的類型:

typdef void (*pFunParam)();

即表示,類型pFunParam,是一個函數指針。

然后,針對整個表達式聲明一個類型:

typedef void (*pFun)(pFunParam);

即表示,類型pFun,是一個函數指針。此函數的參數類型為pFunParam。

最后,進行變量的聲明:

pFun b[10];

這樣,就清晰許多了吧。最重要的時,利用這樣的方式,將編寫者的設計思路也體現在了代碼中。

最后,介紹一個更快速的閱讀方法:從右向左。

編譯器在進行代碼掃描時是從左向右的,而我們在解讀這個表達式的時候,從右向左的方法會更容易些,如:

從右向左掃描以上表達式,首先我們看到一個“)”,因為其右邊再沒有變量,所以我們知道這是一個函數定義,然后,又看到一對“()“,顯然也是函數定義,在就是(*),顯然和后面的()聯合起來表達了一個函數指針,再左邊的void,即修飾了此指針的類型;然后出現了和最右邊”)"對應的”(”,顯然這個函數定義也完成了,再左邊的[10]表達了一個數組,左邊是它的名字b,而更左邊的“*”和后面的“(“一起表達了一個函數指針,這個函數指針定義了b數組中元素的類型。再往左,指針元素的定義void也出現了。這樣,我們就又看到了此表達式的真相。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM