2013-03-10 85 views
3

我正在通過K & R的第7章張貼here中的問題的解決方案閱讀。基本上,程序會根據程序的名稱(「上」或「下」)將標準輸入轉換爲小寫或大寫。這似乎轉換函數的名稱保存在某種字典,像這樣:C中的枚舉/字典式工具?

int (*convcase[2])(int) = {toupper, tolower}; 

,並在稍後訪問取決於程序的名稱是否開始與非盟或L以下功能:

if(argc > 0) 
    { 
    if(toupper((unsigned char)argv[0][0]) == 'U') 
    { 
     func = 0; 
    } 
    else 
    { 
     func = 1; 
    } 

    while((ch = getchar()) != EOF) 
    { 
     ch = (*convcase[func])((unsigned char)ch); 
     putchar(ch); 
    } 
    } 

我明白那個代碼塊在做什麼,但我從來沒有見過像convcase的初始聲明那樣的東西。它好像是某種宏觀,枚舉和數組的奇怪組合。任何人都可以解釋(1)爲什麼convcase是一個指針; (2)名字後面的(int)表示什麼; (3)在聲明中究竟是什麼toupper和tolower,因爲它們不是char * s;和(4)何時/爲什麼要使用這種設置。當你有多個可能的函數調用時,它只是一個類似宏的快速工具來節省一些空間嗎?

+0

http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work – 2013-03-10 17:49:52

+1

http://cdecl.ridiculousfish.com/?q=int+%28 %2Aconvcase%5B2%5D%29%28int 29% – 2013-03-10 17:52:27

回答

3
  1. convcase是兩個函數指針的數組;這不是一個指針。當數組表達式在指針所在的位置使用時,會隱式轉換爲指針。
  2. 這不是演員。它指定函數接受int參數,如touppertolower函數所做的那樣。
  3. convcase用函數指針touppertolower初始化。
  4. 我認爲這個問題是關於函數指針的。當你希望抽象函數指針時使用函數指針。我建議這個例子是一個不必要的函數指針的使用。根據用戶輸入,將convcase[0]convcase[1]更改爲西班牙語或日語的能力在這種情況下更有可能保證使用函數指針。另外,函數指針可以用在參數中以提供額外的抽象。例如,qsort函數能夠對任何類型的數組進行排序,因爲它使用對象的比較器的函數指針。下面是一個使用int_compare函數將int輸入分類爲比較器的示例。
#define nelem(array) (sizeof (array)/sizeof *(array)) 

int int_compare(const void *p1, const void *p2) { 
    int x = *(int *)p1, y = *(int *)p2; 
    return (x > y) - (y > x); 
} 

int main(void) { 
    int value[16]; 
    for (size_t x = 0; x < nelem(value); x++) { 
     if (scanf("%d", &value[x]) != 1) { 
      break; 
     } 
    } 

    qsort(value, sizeof *value, x, int_compare); 
    return 0; 
}