[英]Passing Struct Members as Parameter to a Function in C
Say I have the following code for taking the average of the class' math and science grade.假设我有以下代码来获取班级数学和科学成绩的平均值。
typedef struct
{
char name[30];
float math;
float science;
}
grade;
int n = 5;
grade grades[n];
float math_average(int n)
{
float run_sum = 0;
for (int i = 0; i < n; i++)
{
run_sum += grades[i].math;
}
return (run_sum / n);
}
float science_average(int n)
{
float run_sum = 0;
for (int i = 0; i < n; i++)
{
run_sum += grades[i].science;
}
return (run_sum / n);
}
Is it possible to create a generalized average function to have the same effect?是否可以创建一个广义平均function 以产生相同的效果? So instead of n of subjects functions, I only have 1. Something like passing the subject as a parameter perhaps?
因此,我只有 1 个主题函数,而不是n 个主题函数。也许像将主题作为参数传递之类的东西? Included example to better visualize of what I want to achieve:
包含的示例可以更好地可视化我想要实现的目标:
float average(int n, /* [SUBJECT] */)
{
float run_sum = 0;
for (int i = 0; i < n; i++)
{
run_sum += grades[i]./*SUBJECT*/;
}
return (run_sum / n);
}
In general, if you have N
variables (fields) of the same nature, you don't have N
declarations, you declare an array of N
elements.一般来说,如果你有
N
个相同性质的变量(字段),你没有N
个声明,你声明一个包含N
个元素的数组。 Hence因此
#define MATH 0
#define SCIENCE 1
#define NUM_SUBJECTS 2
typedef struct
{
char name[30];
float subjects[NUM_SUBJECTS];
} grade;
Instead of writing grades[i].math
you write grades[i].subjects[MATH]
.而不是写
grades[i].math
你写grades[i].subjects[MATH]
。 And of course now you can write a general average routine by referring to grades[i].subjects[j]
.当然,现在您可以通过参考
grades[i].subjects[j]
来编写一般平均例程。
Now if you would've thought that this sequence of #define
s at the beginning is dangerously stupid, you'd be right.现在,如果您认为开头的
#define
序列非常愚蠢,那么您是对的。 I've only put them there for illustration.我把它们放在那里只是为了说明。 In reality, you use a single
enum
declaration instead:实际上,您使用单个
enum
声明来代替:
enum subjects { MATH, SCIENCE, NUM_SUBJECTS };
You just need to keep NUM_SUBJECTS
the last item in the list when you extend your list of subjects.当您扩展主题列表时,您只需将
NUM_SUBJECTS
保留在列表中的最后一项。
This approach naturally extends to the case when your list of subjects is not set in stone, but instead is one of the inputs of your program.当您的主题列表不是一成不变的,而是您的程序的输入之一时,这种方法自然会扩展到这种情况。 You will need a dynamic array in one guise or another, for instance
例如,您将需要一种或另一种形式的动态数组
typedef struct
{
char name[30];
int num_subjects;
float *subjects;
} grade;
but the generic average function code will remain unchanged .但通用平均 function 代码将保持不变。
If you want, you can use offsetof
.如果需要,可以使用
offsetof
。
float average(int n, int offset)
{
float run_sum = 0;
for (int i = 0; i < n; i++)
{
//it's a little ugly, but should work as long as your average fields are float
run_sum += *(float*)(((byte*)&grades[i]) + offset);
}
return (run_sum / n);
}
math_average => average(n, offsetof(grade, math))
and so on... math_average => average(n, offsetof(grade, math))
等等...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.