2013-03-10 33 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; 
}