如何在 C 中使用这个定义的类型?

How to use this defined type in C?

如何使用这个定义的类型?

typedef void (*(workers[2]))(char *, char *, int);

我能理解的是,我会有 workers,它是 two pointersarray,每个指向一个 void,它接受提到的参数。

对吗?

试验#1

void worker1(char * x, char * y, int z) {

}

void worker2(char * x, char * y, int z) {

}

然后在另一个空隙中,我做了:

workers w;
w[0] = worker1;
w[1] = worker2;

编译,我得到: error: cannot convert `void (**)(char*, char*, int)' to `void (* (*)[2])(char*, char*, int)'

假设:

typedef void (*(workers[2]))(char *, char *, int);
workers my_workers;

workers 是一种类型(实际上,是一种类型的别名)。 my_workersworkers 类型的对象。

my_workers 是一个包含两个指针的数组,每个指针指向一个 函数。 每个这样的函数都接受提到的参数和 returns void.

试用

应您的要求,我已经按如下方式尝试了您的代码。

#include <stdio.h>

typedef void (*(workers[2]))(char *, char *, int);

void worker1(char * x, char * y, int z) {
    printf("1: [%s] [%s] [%d]\n", x, y, z);
}

void worker2(char * x, char * y, int z) {
    printf("2: [%s] [%s] [%d]\n", x, y, z);
}

int main() {
    char sa[] = "here";
    char sb[] = "there";
    char sc[] = "everywhere";
    char sd[] = "nowhere";
    workers w;
    w[0] = worker1;
    w[1] = worker2;
    (w[0])(sa, sb, 50);
    (w[1])(sc, sd, 70);
    return 0;
}

试试看。对我来说,它编译和运行时没有警告,没有错误。

workers 是“指向以两个 char * 和一个 int 作为参数并返回 void 的函数的指针的 2 元素数组”类型的别名。

这是这个野兽在实践中的样子的例子。

void f0( char *foo, char *bar, int bletch )
{
  // do something interesting with foo, bar, and bletch
}

void f1( char *foo, char *bar, int bletch )
{
  // do something else interesting with foo, bar, and bletch
}

int main( void )
{
  workers w = { f0, f1 }; // equivalent to void (*w[2])(char *, char *, int ) = { f0, f1 };

  // call f0 through w:
  w[0]( "blah", "blah", 1 );

  // call f1 through w:
  w[1]( "ugh", "blah", 2 );
  ...
}

workers typedef 基本上为复杂的、难以阅读的类型创建了一个较短的名称。实际上,最好只为函数类型创建一个 typedef,然后创建一个数组:

typedef (*worker)(char *, char *, int );
worker w[2] = { f0, f1 };

这样的声明的问题
workers w = { f0, f1 };

是不是很明显w有一个数组类型,所以初始化看起来很混乱。它还依赖于使用此类型的人知道它是特定大小的数组类型。我们称之为 "leaky abstraction",它们会导致混淆和维护问题。

你仍然需要知道每个 w[i] 是一个函数类型,它接受一定数量和类型的参数,所以理想情况下它也应该隐藏在接口后面(即你传递 w[i] 到知道如何调用它的函数,而不是自己调用它)。