嗯,首先要说的是,我已尝试通过进行最少的更改来使您的代码正常工作,并指出您犯错误(或无法理解)的地方。首先,您已经在程序中为您的书籍预订了空间,因为您已经在 main 中创建并初始化了三个 struct book 类型的实例,因此您可以将它们的引用分配给您的 lib 对象,而无需为它们,也不是数组,它已经分配在lib结构中,所以当你在main中创建lib对象时,你也可以只用这些实例的地址初始化数组,这样:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXBOOKS 10
typedef struct books
{
char* title;
char* author;
int id;
}book;
typedef struct library
{
int number_of_books;
book* booklist [MAXBOOKS];
}lib;
void storeBook(lib library,book CurrentBook)
{
library.booklist[0] = &CurrentBook;
}
void printLibrary(lib library)
{
for(int i = 0; i < library.number_of_books; i++)
{
printf("Author:%s\n",library.booklist[i]->title);
}
}
int main()
{
book b_1 = {"The trial","Kafka",101};
book b_2 = {"The lurking fear","Lovecraft",102};
book b_3 = {"Dora's storytime collection","Valdes",103};
/* book* list = (book*)malloc(3*sizeof(book)); // no need to call malloc, you have already reserved memory above (and intialized it) */
/* just use the addresses of the books in the library array of pointers */
lib CurrentLibrary = { 3, { &b_1, &b_2, &b_3 }};
/* list[0] = b_1; list[1] = b_2; list[2] = b_3; */
/* lib CurrentLibrary = {3,{list}}; */
printLibrary(CurrentLibrary); /* BEWARE: you are making a copy of the library structure and passing it by value, it is cheaper to pass a reference */
return 0;
}
BEWARE: 注释指出您通过值传递lib 结构(将lib 对象复制到函数,并在函数中使用副本)声明效率更高只是对 printLibrary() 函数中对象的引用,将其声明为:
void printLibrary(lib *library)
{
...
然后调用它:
...
printLibrary(&CurrentLibrary);
因为这将只复制引用(它小于您传递的整个内容,并且必须复制)
如果你想使用动态分配的内存,调用 malloc 来完成所有这些,那么你最好使用这种方法:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXBOOKS 10
typedef struct books {
char* title;
char* author;
int id;
} book;
typedef struct library {
int number_of_books;
book* booklist [MAXBOOKS];
} lib;
void panic(char *str)
{
fprintf(stderr, "PANIC: %s\n", str);
exit(EXIT_FAILURE);
}
book *createBook(char *title, char *author, int id)
{
/* don't cast the value returned by malloc() */
/* first create the structure */
book *ret_val = malloc(sizeof *ret_val);
if (ret_val == NULL) {
panic("couldn't allocate memory for book");
}
/* strdup makes a dynamic memory copy of the string
* you passed as parameter */
/* allocate memory and copy the string title to it */
ret_val->title = strdup(title);
if (ret_val->title == NULL) {
panic("couldn't allocate memory for book's title");
}
/* allocate memory and copy the string author to it */
ret_val->author = strdup(author);
if (ret_val->author == NULL) {
panic("couldn't allocate memory for book's author");
}
ret_val->id = id;
return ret_val;
}
lib *createLibrary()
{
lib *ret_val = malloc(sizeof *ret_val);
if (ret_val == NULL) {
panic("couldn't allocate memory for library");
}
/* initialize the number of books to 0 */
ret_val->number_of_books = 0;
return ret_val;
}
void storeBook(lib *library, book *book)
{
/* check that we can add more books */
if (library->number_of_books >= MAXBOOKS) {
panic("No space left on library for another book");
}
/* then add it (BEWARE that, as the books are freed as part of the
* library destruction, you have only to add books created by
* createBook() */
library->booklist[library->number_of_books++] = book;
}
void printLibrary(lib *library)
{
for(int i = 0; i < library->number_of_books; i++)
{
/* we are using this reference three times below, so we save it
* to facilitate things and calculations. */
book *b = library->booklist[i];
/* separate the books with an empty line after the first. */
if (i > 0) printf("\n");
printf("Id: %d\n", b->id);
printf("Title: %s\n", b->title);
printf("Author: %s\n", b->author);
}
}
void freeBook(book *b)
{
/* first free the references ***INSIDE*** book */
free(b->title);
free(b->author);
/* only after that, we can free() the book instance */
free(b);
}
void freeLibrary(lib *library)
{
/* as above, we need to first free() the references to the books,
* calling freeBook() above, then we are able to free the library
* reference */
for(int i = 0; i < library->number_of_books; i++) {
freeBook(library->booklist[i]);
}
free(library);
}
int main()
{
lib *CurrentLibrary = createLibrary();
/* create the book and store it in a shot */
storeBook(CurrentLibrary,
createBook("The trial", "Kafka", 101));
storeBook(CurrentLibrary,
createBook("The lurking fear", "Lovecraft", 102));
storeBook(CurrentLibrary,
createBook("Dora's storytime collection", "Valdes", 103));
printLibrary(CurrentLibrary);
freeLibrary(CurrentLibrary);
return EXIT_SUCCESS;
}