【问题标题】:Passing struct to function将结构传递给函数
【发布时间】:2012-05-09 08:20:48
【问题描述】:

我是一名新的 C 程序员,我想知道如何将 struct 传递给函数。我遇到了一个错误,无法找出正确的语法来做到这一点。这是它的代码......

结构:

struct student{
    char firstname[30];
    char surname[30];
};

struct student person;

呼叫:

addStudent(person);

原型:

void addStudent(struct student);

以及实际功能:

void addStudent(person)
{
    return;
}

编译器错误:

第 21 行:警告:可疑标签声明:struct student
第 223 行:参数 #1 与原型不兼容:

【问题讨论】:

  • 你在哪里声明你的结构?在您的实际实现文件中,您的struct student { /* ... */ }; 代码在哪里?看起来它在错误的范围内(例如在您的 main 函数中声明或您尝试从...调用 addStudent 的任何函数...
  • 是的,它在我的功能范围内

标签: c function struct


【解决方案1】:

这是通过引用传递struct 的方法。这意味着您的函数可以访问函数外部的struct 并修改其值。您可以通过将指向结构的指针传递给函数来做到这一点。

#include <stdio.h>
/* card structure definition */
struct card
{
    int face; // define pointer face
}; // end structure card

typedef struct card Card ;

/* prototype */
void passByReference(Card *c) ;

int main(void)
{
    Card c ;
    c.face = 1 ;
    Card *cptr = &c ; // pointer to Card c

    printf("The value of c before function passing = %d\n", c.face);
    printf("The value of cptr before function = %d\n",cptr->face);

    passByReference(cptr);

    printf("The value of c after function passing = %d\n", c.face);

    return 0 ; // successfully ran program
}

void passByReference(Card *c)
{
    c->face = 4;
}

这是您通过值传递struct 的方式,以便您的函数接收struct 的副本并且无法访问外部结构来修改它。外部是指功能之外。

#include <stdio.h>


/* global card structure definition */
struct card
{
    int face ; // define pointer face
};// end structure card

typedef struct card Card ;

/* function prototypes */
void passByValue(Card c);

int main(void)
{
    Card c ;
    c.face = 1;

    printf("c.face before passByValue() = %d\n", c.face);

    passByValue(c);

    printf("c.face after passByValue() = %d\n",c.face);
    printf("As you can see the value of c did not change\n");
    printf("\nand the Card c inside the function has been destroyed"
        "\n(no longer in memory)");
}


void passByValue(Card c)
{
    c.face = 5;
}

【讨论】:

  • 简洁。很整洁。
  • 绝对完美!
  • 问有点晚了,但为什么要将结构类型定义为同名(但大写)?我也想知道为什么你需要创建一个指向结构的指针 (*cptr),然后使用它传递给函数,当你可以使用 &amp;c 通过引用传递原始卡结构时。我是 C 中的结构的新手,所以真的在寻找反馈。
  • 简洁的代码,很好的解释。
【解决方案2】:

线路功能实现应该是:

void addStudent(struct student person) {

}

person不是类型而是变量,不能作为函数参数的类型。

此外,请确保您的结构在函数原型之前定义 addStudent,因为原型使用它。

【讨论】:

  • 一个好主意是使用 typedef 来“命名”结构类型以避免这个问题。见en.wikipedia.org/wiki/Struct_(C_programming_language)
  • 这是否意味着我必须从我的函数中取出整个结构并将其放入原型所在的头文件中?
  • @DanielDC - 我不敢问这个。是的,该结构应该在全局范围内声明,因为它也被其他函数使用。
  • 哦,我以为您可以像使用整数和字符一样使用它。 ;(多么尴尬……谢谢你的帮助
  • 欢迎您,不要太勉强,从语言开始,这不是小事。
【解决方案3】:

当将结构传递给另一个函数时,通常最好按照 Donnell 上面的建议,通过引用传递它。

这样做的一个很好的理由是,如果您想要进行更改,这些更改将在您返回到创建它的实例的函数时反映出来,这会使事情变得更容易。

这是最简单的方法示例:

#include <stdio.h>

typedef struct student {
    int age;
} student;

void addStudent(student *s) {
    /* Here we can use the arrow operator (->) to dereference 
       the pointer and access any of it's members: */
    s->age = 10;
}

int main(void) {

    student aStudent = {0};     /* create an instance of the student struct */
    addStudent(&aStudent);      /* pass a pointer to the instance */

    printf("%d", aStudent.age);

    return 0;
}

在此示例中,addStudent() 函数的参数是指向 student 结构 - student *s 的实例的指针。在main() 中,我们创建student 结构的实例,然后使用引用运算符(&amp;) 将对它的引用传递给addStudent() 函数。

addStudent() 函数中,我们可以使用箭头运算符 (-&gt;) 来取消引用指针,并访问它的任何成员(功能上等同于:(*s).age)。

我们在addStudent() 函数中所做的任何更改都会在我们返回main() 时反映出来,因为指针为我们提供了student 结构实例在内存中存储位置的引用。 printf() 说明了这一点,在本例中将输出“10”。

如果你没有传递一个引用,你实际上会使用你传递给函数的结构的副本,这意味着当你返回 main 时,任何更改都不会反映 - 除非你实现了一种方法将新版本的结构传递回 main 或类似的东西!

虽然指针起初可能看起来令人反感,但一旦你了解它们的工作原理以及它们为何如此方便,它们就会成为第二天性,你会想知道没有它们你是如何应对的!

【讨论】:

    【解决方案4】:

    你需要在 person 上指定一个类型:

    void addStudent(struct student person) {
    ...
    }
    

    此外,您可以 typedef 您的结构以避免每次使用时都必须键入结构:

    typedef struct student{
    ...
    } student_t;
    
    void addStudent(student_t person) {
    ...
    }
    

    【讨论】:

      【解决方案5】:

      代替:

      void addStudent(person)
      {
          return;
      }
      

      试试这个:

      void addStudent(student person)
      {
          return;
      }
      

      由于您已经声明了一个名为“学生”的结构,因此您不必在函数实现中指定,如下所示:

      void addStudent(struct student person)
      {
          return;
      }
      

      【讨论】:

      • 我不这么认为。没有 typedef 就会出错。
      猜你喜欢
      • 2013-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      相关资源
      最近更新 更多