2016-07-22 6 views
1

Я пытаюсь перенаправить ссылку на (вложенную) структуру, в C.Структуры прямой передачи - 1) должны быть с указателем? 2) должны быть инициализированы?

Это означает, что у меня есть структура и в ней я ссылаюсь на другую структуру, которая объявлена ​​позже.

Если я объявляю вложенную структуру как указатель и инициализирую ее значениями, она работает.

Следующий код работает:

#include <stdio.h> 

struct computer{ 
    double cost; 
    int year; 
    char cpu_type[16]; 
    struct cpu_speed *sp; //this is the question (1) 
}; 

struct cpu_speed{ 
    int num; 
    char type[16]; 
}; 

typedef struct computer SC; 
typedef struct cpu_speed SS; 

void DataR(SC *s); 
void DataP(SC *s); 

int main(){ 
    // this is question (2) 
    SS speed = {4,"giga"};  
    SC model[2] = { 
    { 0,1990, "intel", &speed}, 
    { 0,1990, "intel", &speed} 
    }; 

    int i; 
    for(i=0;i<2;i++) { 
     printf("computer no. %d \n", i+1); 
     DataR(&model[i]); 
    } 
    printf("here's what you entered: \n"); 
    for(i=0;i<2;i++) { 
     printf("computer no. %d \n", i+1); 
     DataP(&model[i]); 
    } 
    return 0; 
} 

void DataR(SC *s){ 
    printf("the cost of your computer: "); 
    scanf("%lf", &s->cost); 
    printf("the year of your computer: "); 
    scanf("%d", &s->year); 
    printf("the type of cpu inside your computer: "); 
    scanf("%s", s->cpu_type); 
    printf("the speed of the cpu: "); 
    scanf("%d %s", &(s->sp->num), s->sp->type); 

} 

void DataP(SC *s){ 

    printf("the cost: %.2lf\n",s->cost); 
    printf("the year: %d\n",s->year); 
    printf("the cpu type: %s\n",s->cpu_type); 
    printf("the cpu speed: %d %s\n",s->sp->num, s->sp->type); 
} 

Если я объявляю вложенную-структуру (т.е. struct cpu_speed{...};) перед родителем структура, мне не нужно использовать указатель, и я тоже не нужно (?) для инициализации.

Значение:

(1) можно использовать struct cpu_speed speed; вместо struct cpu_speed *sp;. (2) Мне не нужно давать инициализированные значения структурным переменным.

Мои вопросы снова - в структуре прямой ссылки - (1) вам нужно объявить его указателем? и (2) вам нужно инициализировать значения?

+0

Просто подумайте: как бы восстановительная работа 'struct'? (в то время как это связано, это не касается вложенности) – Olaf

ответ

5

Структуры используются только компилятором для выравнивания вашей памяти. Таким образом, он должен знать размер элементов структуры.

struct foo { 
    struct bar *pointer; 
}; 

В этом случае sizeof(pointer) не имеет никакого отношения к bar структуры и, таким образом, компилятор не нужно знать ничего больше.

Однако, если вы хотите добавить структуру bar в структуру foo, это необходимо знать о ее отдельных членах.

struct bar { 
    const char *string; 
    uint64_t integer; 
}; 

struct foo { 
    struct bar sub; 
}; 

Вы должны объявить bar-структуру, прежде чем foo, потому что компилятор должен знать, что вы имеете в виду. В противном случае, как бы он знал, что делать с этим (незаконным) кодом:

struct bar { 
    struct foo sub; 
}; 

struct foo { 
    struct bar sub; 
}; 
+0

ОК, поэтому в основном вы не должны использовать структуры с прямой привязкой, и если вы это делаете - вам нужно использовать указатели и инициализировать их. Это верно? –

+0

Ну, нет ничего плохого в структурах с прямой ссылкой. Например, это здорово, когда вы используете их для защиты членов структуры от публичных API. Но если вы это делаете, вам всегда нужно использовать указатели и 'malloc' для создания нового экземпляра, да. – elslooo