Инициализация нескольких структур с одинаковыми именами и количеством членов в одной функции - PullRequest
0 голосов
/ 27 января 2019
typedef struct
{
 int data;
int size;
} s1;

typedef struct
{
 char data;
 int size;
} s2;

typedef struct
{
 float data;
 char size;
} s3;

func(void *p)
{
      /*this should be generic to all structure.*/
      /* Need to do for removing duplicate codes*/
      /* p->data=1; p->size=0; this should be generic */
}
 int main()
{ s1 a;s2 b; s3 c;
   func(a);func(b);func(c);
 }

Здесь нужно инициализировать эту структуру случайным образом.Требование состоит в том, чтобы сохранить «func» как общую функцию для всех типов структур.

Пожалуйста, предложите оптимальный метод в C, а не в C ++

Ответы [ 2 ]

0 голосов
/ 27 января 2019
typedef struct
{
    int data;
    int size;
} s1;

typedef struct
{
     char data;
     int size;
} s2;

typedef struct
{
     float data;
     char size;
} s3;

void func_s1(s1 p)
{
    printf("%s\n", __FUNCTION__);
}

void func_s2(s2 p)
{
    printf("%s\n", __FUNCTION__);
}

void func_s3(s3 p)
{
    printf("%s\n", __FUNCTION__);
}

void func_s1p(s1 *p)
{
    printf("%s\n", __FUNCTION__);
}

void func_s2p(s2 *p)
{
    printf("%s\n", __FUNCTION__);
}

void func_s3p(s3 *p)
{
        printf("%s\n", __FUNCTION__);
}


#define func(p) _Generic((p), \
              s1 *: func_s1p, \
              s2 *: func_s2p, \
              s3 *: func_s3p, \
              s1: func_s1, \
              s2: func_s2, \
              s3: func_s3)(p) \



int main()
{ 
    s1 a;s2 b; s3 c;
    func(&a);
    func(&b);
    func(&c);
    func(a);
    func(b);
    func(c);
}
0 голосов
/ 27 января 2019

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

Например, сохранение значения 1 в dataполе каждого выглядит следующим образом, принимая во внимание порядок байтов с прямым порядком байтов и представление одинарной точности IEEE 754 для float:

a.data
---------------------
| 00 | 00 | 00 | 01 |
---------------------

b.data
------
| 01 |
------

c.data
---------------------
| 3f | 80 | 00 | 00 |
---------------------

Так что, не зная ничего о действительном типе, нет способа сделать именно то, что выищу.

Самое близкое к чему вы хотите - это создать функцию для каждого типа, а затем использовать макрос с _Generic для переноса того, какой из них вызывается.

void func_s1(s1 *p)
{
    ...
}

void func_s2(s2 *p)
{
    ...
}

void func_s3(s3 *p)
{
    ...
}

#define func(p) _Generic((p), \
                         s1: func_s1, \
                         s2: func_s2, \
                         s3: func_s3)(&p)
...