中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【C語言】函數指針與回調函數

發布時間:2020-06-27 11:09:32 來源:網絡 閱讀:833 作者:q381989042 欄目:編程語言

在C語言中:指針是C語言的特色,有著各種各樣的指針,普通的變量指針,常量指針,數組指針,指針數組,函數指針,指針函數。我們就講一下函數指針與回調函數吧


首先關于函數指針,其實很簡單。

    對于一個函數指針來說,顧名思義,就是一個指向函數的指針,需要知道的是,對于指針而言,他總是存儲一塊地址,地址里面有著一個,一組,或者一塊數據,在函數中,函數的存儲是放在代碼段的,每個函數都有著一個函數首地址,調用了這個地址相當于調用的這個函數。

    具體的可以觀看我的這篇博客,其中就通過在內存階段改變棧幀返回值,成功的調用了一個重啟函數。淺談棧幀(一)

    其實C++特性中的虛函數表就有利用這一點。

    所以說呢,函數指針就是一個指向函數首地址的指針,好了,先了解這個定義,然后我們進入下一個階段。

    

對于指針,他不僅僅要指向一個具體的量,他還需要其他的標識符來描述這個量的具體屬性。

  例如:char* str,void *func(int,int);

在指針符號*的左右,都是在描述這個指針的具體信息。

那么對于函數指針而言,這是怎么樣的呢。

    void (*f) ( );雖然()的優先級高于*,但由于有括號存在,首先執行的是解引用,所以f是一個指針;接下來執行( ),表明f指向一個函數,這個函數不返回任何值。現在得出結論:f是一個指向不接受參數且不返回任何值的函數的指針,簡稱函數指針(pointer to function)

<1>.初始化

注意指向函數的指針(函數指針)指向的是函數而非普通的變量,它所指向的函數也是有特定類型的,函數的類型由它的返回值類型以及形參列表確定,和函數名無關。對函數指針初始化時可以采用相同類型函數的函數名或函數指針(當然還有零指針常量)。假如有函數void test ( )int wrong_match (int)和函數指針void (*ptf) ( )

下面的初始化是錯誤的,因為函數指針的類型與函數的類型不匹配:

f = wrong_match;

f = & wrong_match;

ptf = wrong_match;

ptf = & wrong_match;

以下初始化及賦值是合法的:

f = test;

f = &test;

ptf = test;

ptf = &test;

f = pf;

要做出解釋的是test&test都可以用來初始化函數指針。C語言規定函數名會被轉換為指向這個函數的指針,除非這個函數名作為操作符或sizeof操作符的操作數(注意:函數名用于sizeof的操作數是非法的)也就是說f = test;test被自動轉換為&test,而f= &test;中已經顯示使用了&test,所以test就不會再發生轉換了。因此直接引用函數名等效于在函數名上應用 & 運算符,兩種方法都會得到指向該函數的指針。


int (*function(int)) (double*,char);要了解此聲明的含義,首先來看function(int),將function聲明為一個函數,它帶有一個int型的形式參數,這個函數的返回值為一個指針,正是我們本將開頭講過的函數指針int (*) (double*, char);這個指針指向一個函數,此函數返回int型并帶有兩個分別是double*型和char型的形參。如果使用typedef可以將這個聲明簡化:

typedef int (*ptf) (double*, char);

ptf function(int );

總結:

    其實對于函數指針來說。我們只需要記住。從最中間括號開始往外逐步分析,函數指針是(*)

而指針函數是(*()),懂得會分區,就知道函數指針是什么東西了。弄清楚他本身名字,然后弄清楚他的描述情況。


回調函數:

    上面已經說清楚了對于函數指針而言,他有著他自己的名字,有著相對于的描述信息,信息不一樣的無法進行賦值配對,然后既然有函數指針這種東西?那么他出現是干什么用的呢?

    其實對于函數指針,無非就是讓我們在面臨不同情況去使用他。函數指針指向不同的情況,來進行不同的操作,在主題函數處理中提供不同的函數指針借口,借此來處理不同的情況。

    計算機程序設計中,回調函數,或簡稱回調(Callback 即call then back 被主函數調用運算后會返回主函數),是指通過函數參數傳遞到其它代碼的,某一塊可執行代碼引用。這一設計允許了底層代碼調用在高層定義的子程序

    來看一個簡單例子:

#include <stdio.h>

int int_cmp(const void * p1, const void * p2)
{
    if (*( int *)p1 > *(int *) p2)
    {
        return 1;
    }
    else if (*( int *)p1 == *(int *) p2)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

void _swap(void *p1, void * p2, int size)
{
    int i = 0;
    for (i = 0; i< size; i++)
    {
        char tmp = *((char *)p1 + i);
       *(( char *)p1 + i) = *((char *) p2 + i);
       *(( char *)p2 + i) = tmp;
    }
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
    int i = 0;
    int j = 0;
    for (i = 0; i< count - 1; i++)
    {
        for (j = 0; j<count - i - 1; j++)
       {
            if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)
           {
               _swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);
           }
       }
    }
}
int main()
{
    int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
    //char *arr[] = {"aaaa","dddd","cccc","bbbb"};
    int i = 0;
    bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
    for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
    {
       printf( "%d ", arr[i]);
    }
    printf("\n");
    return 0;
}



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宣城市| 类乌齐县| 宣化县| 大冶市| 军事| 甘孜县| 平塘县| 大理市| 阿坝县| 孟津县| 望都县| 嘉峪关市| 大渡口区| 永和县| 武山县| 潼关县| 胶南市| 嘉峪关市| 乌拉特中旗| 麻江县| 绥化市| 正安县| 焉耆| 久治县| 永安市| 洞口县| 清涧县| 阿拉尔市| 屏东市| 改则县| 湖北省| 南康市| 江门市| 和龙市| 大宁县| 红原县| 兴国县| 壶关县| 九龙县| 陈巴尔虎旗| 苗栗县|