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

#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];  // ... }