【问题标题】:define a function returning struct pointer定义一个返回结构指针的函数
【发布时间】:2012-05-05 01:10:38
【问题描述】:

请多多包涵,我来自其他语言,是 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 的指针。我不明白is(可能是因为我来自其他语言,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)

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

抱歉,这个问题太基础了。

【问题讨论】:

  • 了解Person *Person 的区别。 Person * 是指向对象的指针,而 Person 是对象本身。两者都是不同的类型,例如 int *int 的不同之处。
  • 所以,struct Person *Person_createstruct Person * Person_createstruct Person* Person_create 相同吗? *位置无所谓?
  • 是的,* 周围的空格在这里无关紧要。

标签: c


【解决方案1】:

之所以这样定义,是因为它返回一个指向结构的指针,而不是结构。您将返回值分配给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;
}

但它并不经常使用。

【讨论】:

    【解决方案2】:

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

    当您在 C 中调用一个函数时,您会在 call stack 上为它添加一条记录。调用堆栈的底部是您正在运行的程序的main 函数,顶部是当前正在执行的函数。堆栈上的记录包含传递给函数的参数值和函数的所有局部变量等信息。

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        默认情况下,结构在 C/C++ 中不是指针(或引用),例如在 Java 中。因此,Struct Person Function() 将返回 struct 本身(按值,制作副本)而不是指针。

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

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-01-12
            • 2011-02-11
            • 1970-01-01
            • 1970-01-01
            • 2016-04-21
            • 1970-01-01
            相关资源
            最近更新 更多