簡體   English   中英

無法理解 C 中指向函數的指針

[英]Unable to understand pointers to functions in C

我正在閱讀 K&R 的“C 編程語言”,但無法理解函數指針的概念。 為了解釋指向函數的指針,它以一個程序為例,如果給出了可選參數 -n,則該程序按數字而不是按字典順序對輸入行進行排序。 這是程序:

  #include <stdio.h>
    #include <string.h>
    #define MAXLINES 5000     /* max #lines to be sorted */
    char *lineptr[MAXLINES];  /* pointers to text lines */
    int readlines(char *lineptr[], int nlines);
    void writelines(char *lineptr[], int nlines);
    void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
    int numcmp(char *, char *);
    /*sort input lines */
    main(int argc, char *argv[])
    {
      int nlines;  /*number of input lines read */
      int numeric =0;  /* 1 if numeric sort */
      if (argc>1 && strcmp(argv[1], "-n")==0)
      numeric=1;
      if ((nlines= readlines(lineptr, MAXLINES))>=0)
      {
         qsort((void **) lineptr,0,nlines-1, ***(int (*)(void*,void*))(numeric?numcmp:strcmp));***
         writelines(lineptr, nlines);
         return 0;
}
      else
      {
        printf("input too big to sort\n");
        return 1;
       }


}

我的問題是:

1) 在對 qsort 的調用中,為什么沒有傳遞 void* 類型的參數(在粗體和斜體部分)?

2)在對qsort的調用(在粗體和斜體部分)中,那個(*)在做什么,它正在取消引用的函數在哪里?

有人可以澄清我的疑問。

當您調用qsort您只傳遞一個指向函數的指針,而不是調用函數本身。 numericstrcmp的調用發生在qsort函數內部(您不應該聲明自己,而是包括<stdlib.h>如在這個qsort參考中所示,如果它是您正在調用的標准qsort )。

為了更好地解釋它,讓我們制作一個小示例程序,展示如何使用和調用函數指針:

#include <stdio.h>

void hello(const char *name)
{
    printf("Hello %s\n", name);
}

void get_name_and_greet(void (*hello_function)(const char *))
{
    char name[256];
    printf("Please enter name: ");
    scanf("%255s", name);

    hello_function(name);  // Use the function pointer
}

int main(void)
{
    get_name_and_greet(&hello);  // Pass a pointer to the function
}

如您所見,將指針傳遞給函數與將指針傳遞給int變量沒有什么不同。

如果你做了例如

get_name_and_greet(hello("foo"));

您將調用hello函數,並使用hello返回的內容作為get_name_and_greet參數。 這當然不起作用,因為hello不返回任何內容,並且會導致編譯錯誤。


至於(int (*)(void*,void*))部分,它是一個簡單的類型轉換。

至於回答你的問題 1. 和 2. 我認為你可能會從閱讀螺旋規則中受益:

http://c-faq.com/decl/spiral.anderson.html

它有助於將看似復雜的 C 語句(如函數指針)翻譯成簡單的英語:

void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));

'qsort' 是一個帶四個參數的函數,返回 void

參數 0 - lineptr - 一個空指針數組。

參數 1 - left - 一個整數。

參數 2 - right - 一個整數。

參數 3 - comp - 一個指向函數的指針,該函數帶有兩個參數,每個參數都是一個 void 指針,並返回一個 int。

然后在您對“qsort”的調用中:

qsort((void **) lineptr,0,nlines-1, (int (*)(void*,void*))(numeric?numcmp:strcmp));

您提供了這些必要的參數,更具體地說,讓我們看看第三個參數:

(int (*)(void*,void*))(numeric?numcmp:strcmp)

最后一個括號計算為 'numcmp' 或 'stcmp'。 在任何一種情況下,這都是一個返回 int 的函數,唯一的區別是傳入參數的數據類型。不失一般性,讓我們選擇 'numcmp'。

那么我們有:

(int (*)(void*,void*))(numcmp)

我們在 'numcmp' 的左側是一個強制轉換,它負責處理函數 'numcmp' 和 'strcmp' 之間參數數據類型的差異。 在 K&R2 中,它實際上解釋了這一點:

“函數參數的精心轉換會轉換比較函數的參數。這些通常不會對實際表示產生影響,但可以向編譯器保證一切正常。”

此外,'stcmp' 和 'numcmp' 是函數的地址,因為它們是函數,所以 & 運算符不是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM