Как использовать этот определенный тип в C? - PullRequest
0 голосов
/ 05 февраля 2019

Как я могу использовать этот определенный тип?

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

Что я мог понять, что у меня будет workers, то есть array из two pointers, каждыйуказывает на void, который принимает упомянутые аргументы.

Это правильно?

Trial # 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)'

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

workers - это псевдоним для типа "массив из двух элементов с указателями на функции, принимающий два char * и int в качестве аргументов и возвращающий void".

Вот пример того, как этот зверь может выглядеть на практике.

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 (*worker)(char *, char *, int );
worker w[2] = { f0, f1 };

Проблема с объявлением типа

workers w = { f0, f1 };

что не сразу очевидно, что w имеет тип массива, поэтому инициализация выглядит запутанной.Он также полагается на человека, использующего этот тип, чтобы знал , что это тип массива определенного размера.Мы называем это «утечка абстракции», и они приводят к путанице и головной боли обслуживания.

Вы все еще должны знать, что каждый w[i] является типом функции, который принимает определенное число и тип аргументов, поэтому в идеале он также должен быть скрыт за интерфейсом (т. Е. Вы передаете w[i] вфункция, которая знает, как вызывать ее, а не вызывать ее самостоятельно).

0 голосов
/ 05 февраля 2019

Предположим:

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

workers - это тип (на самом деле, псевдоним для типа).my_workers является объектом типа workers.

my_workers является массивом из двух указателей, каждый из которых указывает на функцию . Каждая такая функция принимает указанные аргументыи возвращает void.

TRIAL

В качестве вашего запроса я попробовал ваш код следующим образом.

#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;
}

Попробуйте это.Для меня он компилируется и запускается без предупреждений и ошибок.

...