Тип указателя для вложенной структуры в C - PullRequest
0 голосов
/ 03 мая 2019

Можно ли создать указатель на внутреннюю структуру вложенной структуры в C?

#include <stdio.h>
#include <stdint.h>

typedef struct
{
    uint8_t first;
    struct
    {
        uint8_t second;
        uint8_t third[8];
    } inner_struct;
} outer_struct;

int main()
{
    outer_struct foo;
    void * p = &foo.inner_struct;
    printf("%d", sizeof(p->third));
    return 0;
}

Используя пустой указатель, я могу указать на него, но я получаю эту ошибку

main.c: In function 'main':
main.c:26:26: error: request for member 'third' in something not a structure or union
     printf("%d", sizeof(p->third));
                          ^~

при попытке получить размер «третьего» массива. Я также мог бы использовать указатель на external_struct, но реальный пример - это событие, более вложенное и содержащее длинные имена переменных, что затрудняет его чтение. Можно ли создать указатель на внутреннюю структуру напрямую?

Использование struct inner_struct * p = &foo.inner_struct; вместо пустот дает

main.c: In function 'main':
main.c:25:31: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     struct inner_struct * p = &foo.inner_struct;
                               ^
main.c:26:26: error: dereferencing pointer to incomplete type 'struct inner_struct'
     printf("%d", sizeof(p->inner_struct.third));
                          ^~

1 Ответ

3 голосов
/ 03 мая 2019

Тип void * - это общий указатель, который может указывать на что угодно.Но на самом деле компилятор не знает , на что он указывает, поэтому вы должны сказать это с помощью приведения.

Так что для работы p->third вам необходимо привести указатель p на правильный тип указателя.

К сожалению, это невозможно с вашим текущим кодом, поскольку внутренняя структура является анонимной структурой без известного тега (имя структуры).Вам нужно создать тег структуры, который вы можете использовать для приведения.Например,

typedef struct
{
    uint8_t first;
    struct inner_struct
    {
        uint8_t second;
        uint8_t third[8];
    } inner_struct;
} outer_struct;

Теперь вы можете навести указатель p, например ((struct inner_struct *) p)->third.

, или сразу определить p как правильный тип:

struct inner_struct *p = &foo.inner_struct;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...