C语言结构体作为函数参数的3种用法(非常详细)
C语言中使用函数时,其参数也可以是结构体变量,形式有 3 种:
【实例】求语数外 3 科平均分。在本实例中,声明一个简单的结构体类型表示学生成绩,并初始化。编写一个函数,使得该结构体变量作为函数的参数,在函数中显示此学生成绩并计算语数外 3 科的平均分,具体代码如下:
运行程序,结果为:
在传递结构体变量的指针时,只是将结构体变量的首地址进行传递,并没有将变量的副本进行传递。例如,声明一个传递结构体变量指针的函数如下:
【实例】修改英语成绩。对前面的实例做点小改动,使用结构体变量的指针作为函数参数,并在函数中改动结构体成员的数据。通过前后两次输出,比较二者的区别。
程序中为了直观地看出函数传递的参数是结构体变量指针,定义了一个指针变量指向结构体。实际上,可以直接传递结构体变量的地址作为函数参数,如“Display(&student);”。
运行程序,结果为:
运行程序,结果为:
- 使用结构体变量作为函数参数;
- 使用指向结构体变量的指针作为函数参数;
- 使用结构体变量的成员作为函数参数。
使用结构体变量作为函数参数
结构体变量作为函数实参时,采取的是“值传递”方式,即会将结构体变量所占内存单元的内容全部顺序传递给形参,形参也必须是同类型的结构体变量。例如:void Display(struct Student stu);在形参位置使用结构体变量,但是函数调用期间,形参也要占用内存单元。这种传递方式在空间和时间上开销都比较大。另外,根据函数参数传值方式,如果在函数内部修改了变量中成员的值,则改变的值不会返回到主调函数中。
【实例】求语数外 3 科平均分。在本实例中,声明一个简单的结构体类型表示学生成绩,并初始化。编写一个函数,使得该结构体变量作为函数的参数,在函数中显示此学生成绩并计算语数外 3 科的平均分,具体代码如下:
#include<stdio.h> struct Student /*学生结构体*/ { char cName[20]; /*姓名*/ float fScore[3]; /*分数*/ } student={"SuYuQun",98.5f,89.0,93.5f}; /*定义变量*/ void Display(struct Student stu) /*形参为结构体变量*/ { printf("-----信息如下-----\n"); /*提示信息*/ printf("姓名: %s\n",stu.cName); /*引用结构成员*/ printf("语文: %.2f\n",stu.fScore[0]); printf("数学: %.2f\n",stu.fScore[1]); printf("英语: %.2f\n",stu.fScore[2]); printf("平均分: %.2f\n",(stu.fScore[0]+stu.fScore[1]+stu.fScore[2])/3); /*计算平均分数*/ } int main() { Display(student); /*调用函数,结构体变量作为实参进行传递*/ return 0; }程序中:
- 声明一个简单的结构体表示学生分数信息,在其中定义一个字符数组表示名称,再定义一个实型数组表示 3 个学科的分数。声明结构体的同时定义变量,并进行初始化;
- 定义一个名为 Display 的函数,用结构体变量作为函数形参。函数体中,使用参数 stu 引用结构体中的成员,输出学生的姓名和 3 个学科的成绩,并在最后通过表达式计算出平均成绩;
- 在主函数 main() 中,使用 student 结构体变量作为参数,调用 Display() 函数。
运行程序,结果为:
-----信息如下----- 姓名: SuYuQun 语文: 98.50 数学: 89.00 英语: 93.50 平均分: 93.67
使用指向结构体变量的指针作为函数参数
在使用结构体变量作为函数的参数时,在传值的过程中空间和时间的开销比较大,那么有没有一种更好的传递方式呢?有!就是使用结构体变量的指针作为函数的参数进行传递。在传递结构体变量的指针时,只是将结构体变量的首地址进行传递,并没有将变量的副本进行传递。例如,声明一个传递结构体变量指针的函数如下:
void Display(struct Student* stu)这样使用形参 stu 指针就可以引用结构体变量中的成员了。需要注意的是,因为传递的是变量的地址,如果在函数中改变成员中的数据,那么返回主调函数时变量会发生改变。
【实例】修改英语成绩。对前面的实例做点小改动,使用结构体变量的指针作为函数参数,并在函数中改动结构体成员的数据。通过前后两次输出,比较二者的区别。
#include<stdio.h> struct Student /*学生结构体*/ { char cName[20]; /*姓名*/ float fScore[3]; /*分数*/ } student={"SuYuQun",98.5f,89.0,93.5f}; /*定义变量*/ void Display(struct Student* stu) /*形参为结构体变量的指针*/ { printf("-----信息如下-----\n"); /*提示信息*/ printf("姓名: %s\n",stu->cName); /*使用指针引用结构体变量中的成员*/ printf("英语: %.2f\n",stu->fScore[2]); /*输出英语的分数*/ stu->fScore[2]=90.0f; /*更改成员变量的值*/ } int main() { struct Student* pStruct=&student; /*定义结构体变量指针*/ Display(pStruct); /*调用函数,结构变量作为实参进行传递*/ printf("修改之后的英语: %.2f\n",pStruct->fScore[2]); /*输出成员的值*/ return 0; }程序中:
- 函数参数是结构体变量指针,因此函数体中通过“->”引用成员数据。为了简化操作,只将英语成绩进行输出,并且最后更改成员的数据;
- 主函数 main() 中,先定义结构体变量指针,并将结构体变量的地址传递给指针,将指针作为函数参数进行传递。函数调用完后,再显示一次变量中的成员数据。通过结果可以看到,在函数中通过指针改变成员的值,在返回主调用函数中值发生变化。
程序中为了直观地看出函数传递的参数是结构体变量指针,定义了一个指针变量指向结构体。实际上,可以直接传递结构体变量的地址作为函数参数,如“Display(&student);”。
运行程序,结果为:
-----信息如下----- 姓名: SuYuQun 英语: 93.50 修改之后的英语: 90.00
用结构体变量的成员作为函数参数
该方式与普通变量作为实参是一样的,是传值方式传递(实参与形参类型一致)。例如:Display(student.fScore[0]);下面是一个示例,展示如何将结构体成员作为函数参数传递:
#include <stdio.h> // 定义一个结构体,包含学生的姓名和成绩 struct Student { char name[20]; float score; }; // 函数声明,参数为结构体的成员 void DisplayScore(float score); int main() { struct Student student = {"Alice", 92.5}; // 创建一个学生结构体实例 printf("Student: %s, Score: %.2f\n", student.name, student.score); // 将结构体成员作为函数参数传递 DisplayScore(student.score); return 0; } // 函数定义,参数为float类型 void DisplayScore(float score) { printf("Displaying score: %.2f\n", score); }程序中:
- 定义了一个名为 Student 的结构体,包含两个成员:name(姓名)和 score(成绩);
- 定义了一个函数 DisplayScore,它接受一个 float 类型的参数;
- 在 main() 函数中,创建了一个 Student 类型的变量 student,并初始化其姓名和成绩;
- 使用 DisplayScore() 函数,将 student.score 作为参数传递给函数。这里,student.score 是结构体成员,但它是一个 float 类型的值,可以直接作为参数传递;
- 在 DisplayScore() 函数中,打印出传递的成绩。
运行程序,结果为:
Student: Alice, Score: 92.50
Displaying score: 92.50