2016-07-22 6 views
1

Cで参照(ネストされた)構造体を転送しようとしています。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)Iはstruct cpu_speed speed;代わりにstruct cpu_speed *sp;を使用することができます。 (2)構造変数に初期化された値を与える必要はありません。

私の質問は、前方参照構造で - (1)ポインタで宣言する必要がありますか? (2)値を初期化する必要がありますか?

+0

どう思いますか? (これは関連していますが、これはネストに関するものではありません) – Olaf

答えて

5

構造体は、メモリを整列するためにコンパイラによってのみ使用されます。したがって、構造体メンバのサイズを知る必要があります。この場合

struct foo { 
    struct bar *pointer; 
}; 

sizeof(pointer)bar構造体には無関係であるため、コンパイラはより多くの何を知っている必要はありません。

ただし、構造体fooに構造体を追加する場合は、構造体の個々のメンバーについて知る必要があります。

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

struct foo { 
    struct bar sub; 
}; 

コンパイラは、あなたが参照しているかを知る必要があるので、あなたはfoobar構造体を宣言する必要があります。それ以外の場合は、この(違法な)コードをどうすればいいのかを知ることができます:

struct bar { 
    struct foo sub; 
}; 

struct foo { 
    struct bar sub; 
}; 
+0

okですので、基本的に前方参照構造は使用しないことをお勧めします。そうした場合、ポインタを使用して初期化する必要があります。あれは正しいですか? –

+0

前方参照構造には何も問題ありません。たとえば、パブリックフェーシングAPIから構造体メンバーを保護するために使用すると効果的です。しかし、そうすれば、ポインタと 'malloc'を使って新しいインスタンスを作成する必要があります。 – elslooo

関連する問題