繁体   English   中英

定义一个返回结构指针的函数

[英]define a function returning struct pointer

请接受我的帮助,我是来自其他语言的初学者,也是来自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函数返回结构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调用函数时,会在调用堆栈上为其添加一条记录。 调用堆栈的底部是您正在运行的程序的main功能,顶部是当前正在执行的功能。 堆栈上的记录包含信息,例如传递给函数的参数值以及函数的所有局部变量。

您的程序还可以访问另一种类型的内存:堆内存。 在这里,您可以使用malloc分配空间,并且该空间未连接到调用堆栈。

从函数返回时,将弹出调用堆栈,并且所有与函数调用相关的信息都将丢失。 如果要返回一个结构,则有两个选择:在将数据从调用堆栈中弹出之前,将数据复制到该结构中,或者将数据保留在堆内存中并返回指向它的指针。 一个字节一个字节地复制数据比简单地返回一个指针要昂贵得多,因此您通常希望这样做以节省资源(包括内存和CPU周期)。 但是,这并非没有代价。 当您将数据保留在堆内存中时,必须记住在停止使用数据时将其free ,否则程序将泄漏内存。

在C / C ++中,结构默认不是指针(或引用),例如在Java中。 因此,结构人Function()将返回结构本身(按值,进行复制)而不是指针。

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

复制整个结构,而不仅仅是指针是效率较低,因为指针的sizeof通常比小很多sizeof整体结构本身。

同样,一个结构可能包含指向内存中其他数据的指针,并且盲目复制可能会对动态分配的数据造成危险(如果处理一个副本的代码将释放它,则另一个副本将保留无效的指针)。

因此,浅复制几乎总是一个坏主意,除非您确定原始副本不在范围内-然后为什么不直接返回指向该结构的指针(当然,该结构是在堆上动态分配的,所以不会像从函数返回时销毁堆栈分配的实体一样销毁)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM