#c #pointers #data-structures #struct #member-function-pointers
#c #указатели #структуры данных #структура #указатели функций-членов
Вопрос:
Рассмотрим следующий фрагмент кода:
typedef struct { int out; struct { int in1; struct { int in_int2; char in_char2; } inner2[3]; } inner1[2]; } outer; outer o1;
Как я могу использовать указатель, чтобы указать на внутренние структуры, скажем o1.inner[0].inner[1]
, и присвоить им одинаковые значения?
т. е. (псевдокод, предоставленный для объяснения. Спрашивается точный синтаксис:
pointer *my_p = o1.inner[0].inner[1]; my_p-gt;in_int2 = 2;
Комментарии:
1.
o1.inner[0].inner[1];
не будет работать, такinner
как внутри вашей структуры нет вызываемых членов. Участники названыinner1
иinner2
.
Ответ №1:
Все ваши внутренние структуры анонимны, поэтому нет возможности ссылаться на них. Вам нужно дать каждой структуре имя:
typedef struct { int out ; struct inner1 { int in1; struct inner2 { int in_int2; char in_char2; }inner2[3]; }inner1[2]; }outer;
Затем вы можете создать указатель на правильный тип:
struct inner2 *my_p = amp;o1.inner1[0].inner2[1];
Ответ №2:
Единственные варианты в чистом c, которые у вас были бы, — это:
1. Дайте внутренним структурам имя
Таким образом, вы можете ссылаться на конкретный тип внутренней структуры для объявления указателя:
typedef struct { int out; struct inner1 { int in1; struct inner2 { int in_int2; char in_char2; } inner2[3]; } inner1[2]; } outer; // Usage: int main() { outer o1; struct inner2 *ptr = amp;o1.inner1[1].inner2[2]; // ... }
2. Определите вторую эквивалентную структуру в качестве типа указателя
Определив структуру с точно такими же членами, вы можете привести указатель к этой известной структуре.
Это может быть вариантом в случае, если вы не можете изменить определение outer
.
typedef struct { int out; struct { int in1; struct { int in_int2; char in_char2; } inner2[3]; } inner1[2]; } outer; // Usage: int main() { outer o1; struct inner_type { int in_int2; char in_char2; }; struct inner_type* ptr = (struct inner_type*)amp;o1.inner1[1].inner2[2]; // ... }
3. Используйте указатели непосредственно на именованные элементы
Вы также можете просто использовать указатели на in_int2
/ in_char2
, таким образом, вам не придется иметь дело с безымянными структурами:
typedef struct { int out; struct { int in1; struct { int in_int2; char in_char2; } inner2[3]; } inner1[2]; } outer; int main() { outer o1; int* ptr_in_int2 = amp;o1.inner1[1].inner2[2].in_int2; char* ptr_in_char2 = amp;o1.inner1[1].inner2[2].in_char2; // ... }
4. нестандартные typeof()
Если вы можете использовать расширения компилятора, как gcc , так и clang предоставляют typeof()
, что позволяет получить тип произвольного выражения.
Вы можете использовать это для создания указателя на безымянную структуру, например:
typedef struct { int out; struct { int in1; struct { int in_int2; char in_char2; } inner2[3]; } inner1[2]; } outer; int main() { outer o1; typeof(o1.inner1[0].inner2[0])* ptr = amp;o1.inner1[1].inner2[2]; // ... }