C中的枚举/字典工具?

时间:2013-03-10 17:48:17

标签: c

我正在阅读K& R第7章here发布的问题解决方案。基本上,程序会根据程序名称(“上”或“下”)将标准输入转换为小写或大写。它似乎将转换函数的名称存储在某种字典中,如下所示:

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

以后访问这些函数取决于程序名称是以u还是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)何时/为何使用这种设置。当你有多个可能的函数调用时,它只是一个快速的类宏工具来节省一些空间吗?

1 个答案:

答案 0 :(得分:3)

  1. convcase是一个包含两个函数指针的数组;它不是指针。当数组表达式在指向期望的位置使用时,它将隐式转换为指针。
  2. 那不是演员。它指定函数接受int参数,如touppertolower函数那样。
  3. 使用函数指针convcasetoupper初始化
  4. tolower
  5. 我认为这个问题与函数指针有关。当您希望抽象函数指针时,请使用函数指针。我建议这个例子不必要地使用函数指针。根据用户输入,将convcase[0]convcase[1]更改为西班牙语或日语的能力更有可能保证在这种情况下使用函数指针。另外,函数指针可以在参数中使用以提供额外的抽象。例如,qsort函数能够对任何类型的数组进行排序,因为它使用了对象的 comparer 的函数指针。以下是使用int函数将int_compare输入排序为 comparer 的示例。
  6. #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;
    }