最佳實踐

使用 typedef

使用 typedef 而不是每次手動宣告函式指標可能很方便。

宣告函式指標的 typedef 的語法是:

typedef returnType (*name)(parameters);

例:

假設我們有一個函式 sort,它需要一個函式指向函式 compare,這樣:

compare - 要提供給 sort 函式的兩個元素的比較函式。

如果兩個元素被認為相等,則 compare 預期返回 0,如果傳遞的第一個元素在某種意義上比後一個元素更大則返回正值,否則函式返回負值(意味著第一個元素是比後者更小

如果沒有 typedef,我們會以下列方式將函式指標作為引數傳遞給函式:

void sort(int (*compare)(const void *elem1, const void *elem2)) { 
    /* inside of this block, the function is named "compare" */
}

有了 typedef,我們寫道:

typedef int (*compare_func)(const void *, const void *);

然後我們可以將 sort 的函式簽名更改為:

void sort(compare_func func) { 
    /* In this block the function is named "func" */
}

sort 的兩個定義都接受該形式的任何功能

int compare(const void *arg1, const void *arg2) {
    /* Note that the variable names do not have to be "elem1" and "elem2" */
}

函式指標是唯一應該包含該型別的指標屬性的地方,例如,不要嘗試定義像 typedef struct something_struct *something_type 這樣的型別。這甚至適用於具有不應由 API 呼叫者直接訪問的成員的結構,例如 stdio.h FILE 型別(你現在將注意到它不是指標)。

採用上下文指標

函式指標幾乎總是將使用者提供的 void *作為上下文指標。

/* function minimiser, details unimportant */
double findminimum( double (*fptr)(double x, double y, void *ctx), void *ctx)
{
    ...
    /* repeatedly make calls like this */
    temp = (*fptr)(testx, testy, ctx);
}

/* the function we are minimising, sums two cubics */
double *cubics(double x, double y, void *ctx)
{
    double *coeffsx = ctx;
    double *coeffsy = coeffx + 4;

    return coeffsx[0] * x * x * x + coeffsx[1] * x * x + coeffsx[2] * x + coeffsx[3] +
           coeffsy[0] * y * y * y + coeffsy[1] * y * y + coeffsy[2] * y + coeffsy[3];

} 

void caller()
{
    /* context, the coefficients of the cubics */
    double coeffs[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    double min;

    min = findminimum(cubics, coeffs);       
}

使用上下文指標意味著額外的引數不需要硬編碼到指向的函式中,或者需要使用全域性變數。

庫函式 qsort() 不遵循這個規則,並且人們經常可以在沒有上下文的情況下來避免瑣碎的比較函式。但對於任何更復雜的事情,上下文指標變得至關重要。

也可以看看

函式指標