定义一个返回struct指针的函数

请耐心等待我,从其他语言和新手到c并从http://c.learncodethehardway.org/book/learn-c-the-hard-way.html学习

struct Person { char *name; int age; int height; int weight; }; struct Person *Person_create(char *name, int age, int height, int weight) { struct Person *who = malloc(sizeof(struct Person)); assert(who != NULL); who->name = strdup(name); who->age = age; who->height = height; who->weight = weight; return who; } 

我理解第二个Person_create函数返回struct Person的指针。 我不明白是(可能是因为我来自其他语言,erlang,ruby),为什么它将其定义为

 struct Person *Person_create(char *name, int age, int height, int weight) 

 struct Person Person_create(char *name, int age, int height, int weight) 

还有其他方法来定义一个返回结构的函数吗?

对不起,如果这个问题太基础了。

它的定义是因为它返回一个指向结构的指针,而不是结构。 您将返回值分配给struct Person * ,而不是struct Person

可以返回一个完整的结构,如下所示:

 struct Person Person_create(char *name, int age, int height, int weight) { struct Person who; who.name = strdup(name); who.age = age; who.height = height; who.weight = weight; return who; } 

但它并没有经常使用。

该函数返回who ,它是一个struct Person * – 一个指向结构的指针。 保存结构的内存由malloc()分配,函数返回指向该内存的指针。

如果声明函数返回struct Person不是指针,那么who也可以声明为结构。 返回后,结构将被复制并返回给调用者。 请注意,复制的效率低于仅返回指向内存的指针。

Person_create函数返回指向struct Person的指针,因此您必须将返回值定义为指针(通过添加*)。 要理解返回指向结构而不是结构本身的指针的原因,必须理解C处理内存的方式。

在C中调用函数时,在调用堆栈中为其添加记录。 在调用堆栈的底部是您正在运行的程序的mainfunction,顶部是当前正在执行的function。 堆栈上的记录包含诸如传递给函数的参数值和函数的所有局部变量之类的信息。

程序可以访问另一种类型的内存:堆内存。 这是使用malloc分配空间的地方,它没有连接到调用堆栈。

当您从函数返回时,将弹出调用堆栈,并且与函数调用关联的所有信息都将丢失。 如果要返回结构,则有两个选项:在从调用堆栈中弹出结构之前复制结构内的数据,或者将数据保存在堆内存中并返回指向它的指针。 复制数据字节的字节比仅返回指针要昂贵,因此通常需要这样做以节省资源(内存和CPU周期)。 但是,它并非没有成本; 当你将数据保存在堆内存中时,你必须记住在你停止使用它时free它,否则你的程序会泄漏内存。

在C / C ++中,缺省情况下,结构不是指针(或引用),因为它们例如在Java中。 结构Person Function()因此返回struct本身(通过值,制作副本)而不是指针。

您通常不希望创建对象的副本(默认情况下为浅副本,或使用复制构造函数创建的副本),因为这很快就会非常耗时。

复制整个结构而不仅仅是指针的效率较低,因为指针的sizeof通常远小于整个结构本身的sizeof

此外,结构可能包含指向内存中其他数据的指针,盲目复制可能对动态分配的数据很危险(如果处理一个副本的代码将释放它,另一个副本将留下无效指针)。

所以浅拷贝几乎总是一个坏主意,除非你确定原来超出了范围 – 然后为什么你不会只返回指向结构的指针(当然是在堆上动态分配的结构,所以它不会被销毁,就像堆栈分配的实体在从函数返回时被销毁一样)。