伙计们,我不明白这两种分配内存的方法有什么区别,第一种方法在我看来要清楚得多。为什么在第二种方法中必须使用结构指针运算符(->),而第一种方法中只有一个点?-> 用于需要访问指针变量所引用的结构的数据时,那么在第一种方法中也需要使用->,而不是点。请解释一下,我真的不明白。
1种方式:
#include <stdio.h>
#include <stdlib.h>
struct BooksInfo
{
char name[50];
char author[50];
int pages;
int year;
};
int main (void)
{
int ctr,quantily;
puts("Сколько книг вы хотите заполнить? ");
scanf (" %d", &quantily);
getchar();
struct BooksInfo *books;
books=(struct BooksInfo*) malloc(quantily*sizeof(struct BooksInfo));
for (ctr=0;ctr<quantily;ctr++)
{
puts ("Какое название у книги? ");
scanf("%s",books[ctr].name);
puts ("Какой автор книги? ");
scanf("%s",books[ctr].author);
puts ("Сколько страниц в книге? ");
scanf("%d",&books[ctr].pages);
puts ("Какого года книжка? ");
scanf("%d",&books[ctr].year);
}
return 0 ;
}
第二种方式:
#include <stdio.h>
#include <stdlib.h>
struct BooksInfo
{
char name[50];
char author[50];
int pages;
int year;
};
int main (void)
{
int ctr,quantily;
puts("Сколько книг вы хотите заполнить? ");
scanf (" %d", &quantily);
getchar();
struct BooksInfo *books[quantily];
for (ctr=0;ctr<quantily;ctr++)
{
books[ctr]=(struct BooksInfo*) malloc(sizeof(struct BooksInfo));
puts ("Какое название у книги? ");
scanf("%s",books[ctr]->name);
puts ("Какой автор книги? ");
scanf("%s",books[ctr]->author);
puts ("Сколько страниц в книге? ");
scanf("%d",&books[ctr]->pages);
puts ("Какого года книжка? ");
scanf("%d",&books[ctr]->year);
}
return 0 ;
}
是的,我知道您需要检查动态内存的分配并清理它。
2:
我稍微更正了代码,即在分配内存时删除了星号

在第一种情况下,分配了一大块内存并将整个对象数组放置在其中。不错,可靠的方法。删除是一个电话
free。由于放置了一组结构,因此访问一个元素就是一个点。在第二种情况下,首先创建一个指向结构的指针数组。但它使用VLA。但由于代码很糟糕,没关系。然后为每个结构分配内存。在 gamedev 中,他们真的不喜欢这样 - 有太多的小对象。另外,必须仔细编写发布代码。
在第二种情况下,指向结构的指针存储在数组中。这就是为什么你需要使用箭头。或者通过显式取消引用
*,然后就可以使用一个点。让我们从操作
.和开始->。访问结构元素的操作.放在结构对象和字段名之间:str.field. 在使用指向结构的指针时,字段引用应该是这样写的:(*str_ptr).field,但是这种方法不是很清楚,操作很常见。因此,他们把它变成了同义词——操作->:。str_ptr->field更多关于内存分配。这两个示例使用两个不同的内存区域。让我们从使用数组的第二个示例开始。视图构造为堆栈
int a[N]上的数组提供空间。堆栈内存是过程的所有临时对象的内存。进入程序时自动分配,程序结束时自动清除。但这里有个窍门。在示例中,它是一个变量,即 数组的大小事先不知道。这是添加到 C99 标准的可变长度数组 (VLA) 的一个例子。对于这样的数组,内存不是在过程入口处分配,而是在数组声明处分配。N在第一种情况下,使用了在堆上
malloc分配内存的过程。堆是仅由程序员控制的动态内存区域。因此,程序完成后,通过分配的内存将存活并可以访问。该操作用于清除此类内存。mallocfree现在让我们继续看具体的例子。考虑第一个例子:
在这里,我们分配了一块内存,其中包含
quantily指向该结构的指针BooksInfo。从这一段内存的进一步使用来看,其实是这样的构造:现在这个内存区域包含
quantily类型的对象BooksInfo。当使用数组元素访问操作时,[]我们指的是括号内给出的元素。那。构造books[ctr]将产生一个类型为 的对象BooksInfo。正如我们已经知道的那样,要访问结构的字段,使用了操作.,它是这样做的:books[ctr].name。现在考虑构造
这里我们说一个对象
books是一个指向结构的指针数组BooksInfo。但是我们需要使用对象,所以在循环中我们为每个指针分配内存:现在考虑构造的结果
books[ctr]。我们记得数组包含指向结构的指针,所以我们会得到一个类型为 的对象BooksInfo *。要引用结构指向的对象的字段,请使用操作->.UPD
您可以
(*).在这篇文章中了解操作的历史差异,感谢@Croessmah 的评论->