Инициализация структуры и печать в C - PullRequest
0 голосов
/ 26 ноября 2018

Я работаю над проблемой, связанной с кодом ниже, и я немного растерялся.Что делает "класс []", и как это меняет то, как я буду печатать элементы?Я никогда раньше не видел подобную инициализацию.

int main(){    
    struct Student {    
        char Initials2[2];    
        int id;    
        struct Student *teammate;    
    };    
    typedef struct Student SType;    
    #define XYpt &class[0]    
    #define ABpt &class[1]    
    #define RSpt &class[2]    
    #define CDpt &class[3]    
    #define JVpt &class[4]    
    #define RYpt &class[5]    
    SType class[6] = {    
        {{'X','Y'},123, RSpt},    
        {{'A','B'},23, RYpt},    
        {{'R','S'},11, XYpt},    
        {{'C','D'},44, JVpt},    
        {{'J','V'},42, CDpt},    
        {{'R','Y'},457, ABpt}    
    };    

    return 0;    
}     

1 Ответ

0 голосов
/ 26 ноября 2018

Что делает код:

  • struct Student немного особенный, так как содержит указатель на объект того же типа struct Student *teammate,Это возможно с помощью указателя на объект со «тегом структуры» Student, который действует как форма прямого объявления.

  • typedef struct Student SType; просто скрывает struct ключевое слово, которое имеет значение для стиля кодирования.Было бы чище написать все это так:

    typedef struct Student {    
        char Initials2[2];    
        int id;    
        struct Student *teammate;    
    } SType;   
    
  • SType class[6] = { {{'X','Y'},123, RSpt}, .... - это просто массив из 6 структур, каждая из которых инициализирована.Группа макросов расширяется до переменных адресов того же массива с именем «class».Это плохой стиль - программист использовал это как грязный способ «назвать» каждый элемент в массиве.Постфикс «pt», по-видимому, означает указатель.


Как код мог бы быть написан:

Вместо использования уродливых макросовможно связать каждый элемент массива с идентификатором, используя union.Например:

typedef union
{
  struct foo
  {
    int foo;
    int bar;
  } foo;
  int array [2];
} foobar;

Здесь к объекту foobar fb; можно получить доступ как fb.foo.foo или fb.array[0], и это означает тот же элемент 0 массива.С современным стандартом C мы можем отбросить имя внутренней структуры ( анонимная структура ) и просто получить доступ к объектам как fb.foo.

Кроме того, это можно комбинировать с назначенными инициализаторами для инициализации определенных именованных членов структуры по их именам: foobar fb { .foo = 1, .bar = 2 };.

Переписав ваш пример с помощью объединений, анонимной структуры и обозначенных инициализаторов, мы получаем вместо этого:

typedef struct student {    
  char initials [2];    
  int id;    
  struct student *teammate;    
} s_type;    

typedef union
{
  struct
  {
    s_type XY;
    s_type AB;
    s_type RS;
    s_type CD;
    s_type JV;
    s_type RY;
  };
  s_type array [6];
} class_t;

class_t class = 
{
  .XY = { .initials={'X','Y'}, .id=123, .teammate = &class.RS},
  .AB = { .initials={'A','B'}, .id= 23, .teammate = &class.RY},    
  .RS = { .initials={'R','S'}, .id= 11, .teammate = &class.XY},    
  .CD = { .initials={'C','D'}, .id= 44, .teammate = &class.JV},    
  .JV = { .initials={'J','V'}, .id= 42, .teammate = &class.CD},    
  .RY = { .initials={'R','Y'}, .id=457, .teammate = &class.AB},
};

Это намного легче читать и понимать.Кроме того, мы можем использовать его как массив с class.array[i], если захотим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...