C - 这个函数和指针组合是如何工作的?

时间:2016-01-29 23:05:36

标签: c function pointers struct

我想了解一个代码(下面)。我甚至在上面写评论来理解它。

// A structure with four elements (compound data type). Like class in OOP
struct Person {
    char *name;
    int age;
    int height;
    int weight;
}; 

// A function to create above structure
struct Person *Person_create(char *name, int age, int height, int weight)
{
    // Memory allocating. Returns pointer to allocated memory
    struct Person *who = malloc(sizeof(struct Person)); 

    assert(who != NULL); // If false, calling process is terminated
                         // Check if malloc returned NULL memory

    // Initializing each field of struct Person.
    who -> name = strdup(name); // Like malloc. Copy and save the string
                               // Returns a pointer to it
    who -> age = age;
    who -> height = height;
    who -> weight = weight;

    return who;
} 

所以,让我们说我想创建一个叫Joe Alex的人。它会是这样的:

struct Person *joe = Person_create("Joe Alex", 32, 64, 140);

  1. 我不明白的是行

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

    的功能。该行中的struct Person表示返回的类型数据不是?它与宣言不一样吗?

  2. 为什么函数是指针?

  3. 为什么在创建变量joe时,Person_create函数不需要指针?

  4. 最后一件事,为什么函数中有一个指针(如下所示):

    struct Person *who = malloc(sizeof(struct Person)); 
    

    我知道这是为了分配内存,但为什么需要两个(另一个是函数本身)?

  5. 很抱歉,如果这个问题令人困惑。我想尽可能地清楚。

2 个答案:

答案 0 :(得分:2)

代码看起来很好。回答你的问题:

  1. 这是函数Person_create定义的顶部。此函数返回指向struct Person类型对象的指针 - 也就是说,它返回类型struct Person *
  2. 函数返回指针。为什么这样做,这就是程序设置的方式。函数可以返回整个结构(而不​​是指向结构的指针),但通常情况下你想动态分配结构的多个实例并通过指针操作它们,这是代码设置的目的。
  3. 当您编写joe = Person_create(...)时,您实际上是从Person_create函数返回一个指针,并将其指定给变量joe。并且你声明joe也是一个指针(同样,类型为struct Person *),所以这很好,类型匹配,你指定一个指针指针。你没有获取指针的内容(也就是说,你没有看到指针指向的内容),所以你不需要{{1 }} 为了那个原因。 (更多内容见下文。)
  4. '*'就像行struct Person *who = malloc(...)一样。在一个步骤中,您是(a)通过调用返回指针值的函数来声明具有指针类型的变量和(b)初始化
  5. 您混淆的根源可能是当您使用指针时,C会以两种不同的方式使用struct Person *joe = Person_create(...)字符。

    在声明中,'*'表示您正在声明指针。您始终需要'*'来表示您正在声明指针。声明'*'声明了一个int类型的变量。声明int a声明了一个类型为pointer-to-int的变量。

    在表达式中,int *ip表示您正在拍摄内容"指针,或使用指针指向的东西。如果您正在使用指针值本身,则不要使用'*'。如果我说'*',我打印指针指向的东西。如果我说printf("%d\n", *ip),我就打印指针值本身。

    如果你有一个初始化的指针声明,那么这可能会特别令人困惑,因为这最终涉及声明和表达式。你的行

    printf("%p\n", ip)

    很好。但如果你打破了声明和初始化,它将如下所示:

    struct Person *joe = Person_create("Joe Alex", 32, 64, 140);
    

    第二个分配线看起来像这样:

    struct Person *joe;
    joe = Person_create("Joe Alex", 32, 64, 140);
    

    如果你可以"包裹你的头并且#34;最后一个事实,如果对你有意义的话,当你将声明加初始化分解为两行时*joe = Person_create("Joe Alex", 32, 64, 140); /* WRONG */ 类消失了,你就会明白这一点。

答案 1 :(得分:1)

  1. struct Person *Person_create(char *name, int age, int height, int weight)中,返回类型为struct Person *,而非struct Person。 C是免费格式语言,int* hoge()int *hoge()int*hoge()都是等效的。
  2. 函数不是指针。函数自动转换为()(调用函数)运算符和除一元&(获取地址)和sizeof以外的其他运算符的指针。
  3. 创建变量与函数指针无关。如果你想调用Person_create函数,该函数需要一个有效的指针,因为一个参数是一个pointet而函数使用指针参数,所以“Person_create函数不需要指针”真。
  4. 对不起,我不明白你的问题。 (见评论)