我怎样才能在结构中有一个结构数组?

时间:2016-06-24 18:59:38

标签: c arrays structure

让我们说我有一个名为" Film"和一个名为"演员"

的结构
typedef struct actor{
    char *Name;
    char *Surname;
    int year_birth;
    Title_Film * Film_recited;
}Actor;


typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    //array of "Actor" structure
}Film;

我想插入一个结构数组" Actor"在结构内部"电影"因为在一部电影中有很多演员。我能做到吗?怎么样?

4 个答案:

答案 0 :(得分:0)

假设您不知道您需要提前多少个数组元素,那么您可以这样做:

typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    Actor *actor_list;
}Film;

这里,actor_list是一个指针,可以指向动态分配的Actor个对象数组。您可以按照以下方式为当前分配空间:

Film myfilm;
...
myfilm.actor_list = malloc(num_of_actors * sizeof(Actor));

另一方面,如果您 知道在编译时需要多少,您只需直接声明数组成员:

#define ACTOR_LEN 20

typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    Actor actor_list[ACTOR_LEN];
}Film;

答案 1 :(得分:0)

首先,你需要在定义电影之前定义一个演员,否则编译器就不知道如何处理它。

在电影结构中,只需按照我在下面显示的那样声明指针。

typedef struct actor{
    char *Name;
    char *Surname;
    int year_birth;
    Title_Film * Film_recited;
}Actor;


typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    //array of "Actor" structure
    Actor* cast;
}Film;

一旦掌握了指针,就需要弄清楚你将拥有多少个演员。如果你有一个特定的实例,你可以提示这个或硬编码到你的程序中。无论你的船是什么漂浮。

现在你知道你的演员有多大(让我们说你把它保存为变量castSize中的整数,分配内存:

movie.cast = (Actor*)malloc(sizeof(Actor)*castSize);

您现在可以像数组一样访问actor列表,这样您就可以访问其属性。例如:

movie.cast[0]->Name = "Scarlet";
movie.cast[0]->Surname = "Johansson";
movie.cast[0].year_birth = 1984;

答案 2 :(得分:0)

您可以将演员数组插入电影结构

#define ACTORS_MAX_N 10
struct film {
    /* ... */
    struct actor arr[ACTORS_MAX_N];
};

或者你可以将该结构中的指针保存到包含actor的内存中:

struct film {
    /* ... */
    struct actor *arr;
};

如您所见,在第一种情况下(内置数组),您必须事先知道此数组的大小。在第二种情况(指针)中,您可以灵活地进行动态数组分配/释放/重新分配,因此相同的film对象可以引用不同大小的数组。

在C-99标准中,还有可能存储灵活的数组,即动态分配的数组,因此它可以有不同的大小:

struct film {
    /* ... */
    size_t actors_n;
    struct actor arr[]; /* flexible array MUST be last member in struct */
};

sizeof运算符将返回灵活数组的偏移量,因此您可以这样分配:

struct film *allocate_film(size_t actors_n) {
    struct film *film = malloc(sizeof *film + actors_n * sizeof(film->arr[0]));
    if (film == NULL) {
        return NULL;
    }
    film->actors_n = actors_n;
    for (size_t i = 0; i < actors_n; ++i) {
        film->arr[i].Name = /* ...  */
        /* ... allocate actor */
    }
    return film;
}

答案 3 :(得分:0)

对于任何类型T,您可以通过以下两种方式之一获得T数组:

  • 作为数组对象:T arr[N];
  • 作为指向T的指针,您可以为其动态分配内存:T *arr = malloc( sizeof *arr * N );

因此,在Film类型中,您可以执行以下任一操作:

typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    Actor cast[N]; // where N is known at compile time
}Film;

typedef struct film{
    Title_Film * Title; //pointer to structure 
    int year;
    type genre; //enum
    director * director_Film; //pointer to structure
    Actor *cast;
}Film;

在第一种情况下,您只需要创建Film实例,以便也可以创建cast数组:

Film jaws;
jaws.cast[0].name = strdup( "Roy" );         // assumes strdup is available
jaws.cast[0].surname = strdup( "Scheider" ); // otherwise you'll have to use
jaws.cast[1].name = strdup( "Richard" );     // a combination of malloc and
jaws.cast[1].surname = strdup( "Dreyfuss" ); // strcpy

在第二种情况下,为cast数组分配内存需要额外的步骤:

Film jaws2;
jaws2.cast = malloc( sizeof *jaws2.cast * cast_size );

jaws2.cast[0].name = strdup( "Roy" );
jaws2.cast[0].surname = strdup( "Scheider" );

等。

在这两种情况下,完成后,您需要free cast[i].namecast[i].surname。在第二种情况下,您还需要free cast成员本身(每个malloc/calloc应该在某个地方有相应的free

由于铸膜尺寸在薄膜之间变化,因此第二种方法是优选的,因为它可以根据每种薄膜的需要确定尺寸。此外,如果您需要稍后扩展,它还允许您使用realloc 调整数组。一个更好的解决方案是使用链接列表或类似的容器,可以根据需要增长和缩小,但这是一个更多的工作。

目前尚不清楚为什么需要Title_Film类型的Actors成员;由于演员与电影有联系,标题已经存在。

说实话,模拟多对多关系的正确方式(电影有多个演员,演员出现在多部电影中)是Film 而不是包含一个数组Actor或反之亦然;相反,你应该有单独的FilmActor数组(或列表,或树,无论如何),并创建一个附加数组(或列表,或树,无论如何)将单个Actor条目与Film个条目相关联的类型:

struct assoc {
   Actor *actor;
   Film *film;
} ActorFilmAssoc;

Actor *findActor( Actor *list, const char *surname, const char *name ) { ... }
Film *findFilm( Film *list, const char *title ) { ... }

Actor *actors = calloc( num_actors, sizeof *actors );
Film  *films  = calloc( num_films, sizeof *films );

/**
 * Add entries to actors and films
 */

ActorFilmAssoc *map = calloc( someSize, sizeof *map );
size_t entry = 0;
...
map[++entry].actor = findActor( actors, "Scheider", "Roy" );
map[entry].film = findFilm( films, "Jaws" );
map[++entry].actor = findActor( actors, "Scheider", "Roy" );
map[entry].film = findFilm( films, "All That Jazz" );

我们不是在每部电影中为Roy Scheider存储多个Actor条目,而是在actors数组中存储一个条目,并在map中只有多个指针。

这是非常简单化的例子; 想要为地图使用比线性数组更复杂的东西。但它应该说明这个概念。