Компактный доступ к переменным во вложенных структурах - PullRequest
1 голос
/ 01 ноября 2011

Учитывая этот простой C-код:

struct { 
    struct a {
        int foo;
    };
    struct b {
        char *bar;
    };
} s;

Мне интересно, есть ли способ получить доступ к переменной в одной из вложенных структур более компактным способом, чем, например, s.a.foo = 5.

Ответы [ 3 ]

3 голосов
/ 01 ноября 2011

Во-первых, обратите внимание, что ваш пример не является стандартным C89 (но он приемлем для некоторых компиляторов, когда вы запрашиваете некоторые языковые расширения. С GCC вам потребуется расширить принятый диалект C с флагом -fms-extensions для компилятора).Вы используете безымянные поля .Более стандартным способом кодирования будет:

struct a {
   int foo;
};
struct b {
   char* bar;
};
struct {
    struct a aa;
    struct b bb;
} s;

Вернемся к вашему вопросу, нет, другого пути нет.Однако вы можете использовать макросы препроцессора, которые могут помочь.Например, предполагая вышеупомянутые объявления, вы можете

#define afoo aa.foo
#define bbar bb.bar

, а затем вы можете кодировать s.afoo вместо s.aa.foo

Вы также можете определить макросы как

#define AFOO(X) (X).aa.foo

, а затем код AFOO(s)

Использование таких макросов препроцессора вызывает некоторое раздражение: в моем примере вы больше не можете объявлять переменную (или формальный аргумент, или поле, или функцию) с именем afoo

Но я не уверен, что вам стоит беспокоиться.Мой личный совет и привычка - давать более длинные и часто уникальные имена полям (а также называть struct a_st my struct -ures).Воспользуйтесь возможностями автозаполнения вашего редактора.Не забывайте, что ваш код читается чаще, чем пишется, поэтому используйте в нем значимые имена.

1 голос
/ 01 ноября 2011

Там нет. Вы должны указать путь к адресу памяти, на который хотите ссылаться.

0 голосов
/ 01 ноября 2011

Вы не можете напрямую создавать структуры, но вы можете использовать указатели на структуры.Поэтому, если у вас есть эта структура:

typedef struct { 
    struct {
        int foo;
    } a;
    struct {
            char bar;
        } b;
} s;

Вы можете создать структуру, подобную этой:

typedef struct {
    int foo;
    char bar;
} sa;

Теперь, когда вы создаете структуру, сохраните указатель на нее:

s myS;
myS.a.foo = 123;
myS.b.bar = 10;

sa *mySA = (sa *)&myS;

Тогда вы можете сделать это:

printf("I'm really a s.a.bar %d", (*mySA).bar);

, который выведет соответствующее значение.

Так что теперь вы можете сделать:

(*mySA).bar = 22;
printf("%d", myS.b.bar); 

Выхотя на самом деле не так уж много набираешь.

...