gpt4 book ai didi

c - 如何将结构体的数组变量传递给另一个函数?

转载 作者:行者123 更新时间:2023-11-30 19:57:09 25 4
gpt4 key购买 nike

我对使用 typedef struct 还很陌生,所以我希望你能够给出非常基本的解释,以便我可以更好地理解。

我声明了一个名为 ExpNum[3] 的数组变量对于我的 typedef 结构。我希望能够通过ExpNum[0].ValueofParamOne[0]依此类推到另一个名为 myfunction() 的函数。但是,我无法做到

pstInputs->ExpNum[0].ValueofParamOne[0]

当我运行如下所示的代码时,此处初始化的值甚至没有被传递。我明白这一点是因为我 printf ExpNum[0].ValueofParamOne[0]在主函数和 myfunction()并且值(value)观不同。 main函数中的正确,而myfunction()中的正确。打印随机长数字,错误。我知道为什么会出现错误。我的问题是我应该如何传递这个数组?首先这有可能吗?

我知道一个更简单的方法是传递结构而不声明 ExpNum[3] 。然而,这很重要,因为我的实际程序涉及更多实验,我需要 ExpNum[3]帮助用户确保他们不会混淆ValueofParamOne , ValueofParamTwo对应ExperimentResults

或者也许我应该完全改变我的方法?我的主要重点是确保用户准确分配他们的值。

myfunction()是高度技术性和数学性的。其目的是计算优化的参数值。当然,在我的实际函数中,实验数据不止3个。

typedef struct
{
unsigned int NumofParam;
double ExperimentResults[3];
double ValueofParamOne[3];
double ValueofParamTwo[3];
}EXP_CONDITION;

int main()
{
EXP_CONDITION stInputs;
EXP_CONDITION* pstInputs;
pstInputs = &stInputs;

pstInputs->NumofParam = 2U;
EXP_CONDITION ExpNum[3];

/*assign values to Experiment 1*/
ExpNum[0].ValueofParamOne[0]=200;
ExpNum[0].ValueofParamTwo[0]=400;
ExpNum[0].ExperimentResults[0]=1000;

/*assign values to Experiment 2*/
ExpNum[1].ValueofParamOne[1]=210;
ExpNum[1].ValueofParamTwo[1]=440;
ExpNum[1].ExperimentResults[1]=2000;

/*assign values to Experiment 3*/
ExpNum[2].ValueofParamOne[2]=220;
ExpNum[2].ValueofParamTwo[2]=480;
ExpNum[2].ExperimentResults[2]=3000;

myfunction(&stInputs);
return 0;
}

根据 @MaxVollmer 和 @aschepler 的评论进行编辑:)

最佳答案

很明显,您对如何将这些值组合到一个结构中以同时使用所有值感到有点困惑。

在你的代码中。您为 stInputs.NumofParam 分配了一个值 - 但没有分配其他值。

然后,您在 ExpNum 中声明了一个 3 结构体数组,但随后莫名其妙地在每个结构体中仅分配了一行值?

从您的问题的要点来看,您似乎正在尝试用所有值填充一个结构,以便您可以将该结构传递给 myfunction (我们假设它会执行类似输出中的所有值之类的操作)结构)

在查看修复之前,让我们先看看一些常见的编码问题。

首先,不要在代码中使用魔数(Magic Number)(除非绝对需要,例如使用 scanf field-width 修饰符)。您的 3 是一个神奇数字。相反,如果您需要一个常量,#define 一个(或多个),或使用全局enum 来执行相同的操作。这样,您就可以在代码顶部有一个位置来根据需要更改内容,并且无需通过声明或循环限制来进行更改,例如

#include <stdio.h>

#define MAXV 3 /* if you need a constant, #define one (or more) */

typedef struct {
unsigned int NumofParam;
double ExperimentResults[MAXV];
double ValueofParamOne[MAXV];
double ValueofParamTwo[MAXV];
} EXP_CONDITION;

接下来,C 避免使用 camelCaseMixedCase 变量名称,转而使用所有小写,同时保留大写 -与宏和常量一起使用的大小写名称。这是一个风格问题 - 所以这完全取决于你,但不遵循它可能会导致某些圈子中错误的第一印象。

现在来看看你的代码。首先(特别是如果您将循环遍历数组中的元素)在声明时将结构初始化为全零。这将消除因无意中尝试读取未初始化值而调用未定义行为的机会。您可以为第一个成员使用命名初始化程序(默认情况下所有其他成员将设置为零),也可以使用通用初始化程序(例如{0 })来完成同样的事情。示例:

int main (void)
{
/* initialize your struct to all zero using a named initializer
* or the universal intializer {0}
*/
EXP_CONDITION stInputs = { .NumofParam = 0 };
EXP_CONDITION* pstInputs;
pstInputs = &stInputs;
...
EXP_CONDITION ExpNum[MAXV] = {{ .NumofParam = 0 }};

现在看看你的作业的逻辑。您在数组 ExpNum 中声明了 3 个结构。每个结构体中都有 3 个数组,每个数组有 3 个值,例如

    double     ExperimentResults[MAXV];
double ValueofParamOne[MAXV];
double ValueofParamTwo[MAXV];

当您尝试填充 ExpNum[0] ExpNum[1]ExpNum[2] 中的每一个时,您只是在填充一个元素,例如

    /*assign values to Experiment 1*/
ExpNum[0].ValueofParamOne[0]=200;
ExpNum[0].ValueofParamTwo[0]=400;
ExpNum[0].ExperimentResults[0]=1000;

/*assign values to Experiment 2*/
ExpNum[1].ValueofParamOne[1]=210;
ExpNum[1].ValueofParamTwo[1]=440;
ExpNum[1].ExperimentResults[1]=2000;
...

要完全填充您需要的单个结构

    /*assign values to Experiment 1*/
ExpNum[0].ValueofParamOne[0]=200;
ExpNum[0].ValueofParamTwo[0]=400;
ExpNum[0].ExperimentResults[0]=1000;

ExpNum[0].ValueofParamOne[1]=210;
ExpNum[0].ValueofParamTwo[1]=440;
ExpNum[0].ExperimentResults[1]=2000;

ExpNum[0].ValueofParamOne[2]=220;
ExpNum[0].ValueofParamTwo[2]=480;
ExpNum[0].ExperimentResults[2]=3000;

现在让我们看看 myfunction ,我们假设它只输出存储在每个结构中的值(这只是示例):

void myfunction (EXP_CONDITION *exp)
{
printf ("\nNumofParam: %u\n", exp->NumofParam);

for (int i = 0; i < MAXV; i++)
printf (" %7.1lf %7.1lf %7.1lf\n", exp->ExperimentResults[i],
exp->ValueofParamOne[i], exp->ValueofParamTwo[i]);

putchar ('\n'); /* tidy up with newline */
}

想想如果我们调用myfunction (pstInputs)会打印什么?如果我们调用 myfunction (&ExpNum[0]) 会打印什么?或者myfunction (&ExpNum[1])

提示:

Initial stInputs struct

NumofParam: 2
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0

Content of each of ExpNum structs

NumofParam: 0
1000.0 200.0 400.0
0.0 0.0 0.0
0.0 0.0 0.0


NumofParam: 0
0.0 0.0 0.0
2000.0 210.0 440.0
0.0 0.0 0.0


NumofParam: 0
0.0 0.0 0.0
0.0 0.0 0.0
3000.0 220.0 480.0

我可能是错的,但从逻辑上讲,您似乎打算将所有实验都放在 stInputs 结构中,而不是在 ExpNum 数组中将每个实验分散为一行。编码和结构的美妙之处在于,您可以轻松地将数据打乱在一起,现在将其放在一个位置,以便您可以正确管理数据。对 ExpNum 数组进行简单循环,并将所有数据复制到 stInputs 结构的适当位置,例如

    /* now put all values in your stInputs struct like it appears
* you intended to do?
*/
for (int i = 0; i < MAXV; i++) {
pstInputs->ExperimentResults[i] = ExpNum[i].ExperimentResults[i];
pstInputs->ValueofParamOne[i] = ExpNum[i].ValueofParamOne[i];
pstInputs->ValueofParamTwo[i] = ExpNum[i].ValueofParamTwo[i];
}

现在,当您调用 myfunction (pstInputs) 时,您将获得所有数据,例如

Output of the completely filled stInputs struct

NumofParam: 2
1000.0 200.0 400.0
2000.0 210.0 440.0
3000.0 220.0 480.0

将所有部分放在一起,您的最终示例可能如下所示:

#include <stdio.h>

#define MAXV 3 /* if you need a constant, #define one (or more) */

typedef struct {
unsigned int NumofParam;
double ExperimentResults[MAXV];
double ValueofParamOne[MAXV];
double ValueofParamTwo[MAXV];
} EXP_CONDITION;

void myfunction (EXP_CONDITION *exp)
{
printf ("\nNumofParam: %u\n", exp->NumofParam);

for (int i = 0; i < MAXV; i++)
printf (" %7.1lf %7.1lf %7.1lf\n", exp->ExperimentResults[i],
exp->ValueofParamOne[i], exp->ValueofParamTwo[i]);

putchar ('\n'); /* tidy up with newline */
}

int main (void)
{
/* initialize your struct to all zero using a named initializer
* or the universal intializer {0}
*/
EXP_CONDITION stInputs = { .NumofParam = 0 };
EXP_CONDITION* pstInputs;
pstInputs = &stInputs;

pstInputs->NumofParam = 2U;
EXP_CONDITION ExpNum[MAXV] = {{ .NumofParam = 0 }};

/*assign values to Experiment 1*/
ExpNum[0].ValueofParamOne[0]=200;
ExpNum[0].ValueofParamTwo[0]=400;
ExpNum[0].ExperimentResults[0]=1000;

/*assign values to Experiment 2*/
ExpNum[1].ValueofParamOne[1]=210;
ExpNum[1].ValueofParamTwo[1]=440;
ExpNum[1].ExperimentResults[1]=2000;

/*assign values to Experiment 3*/
ExpNum[2].ValueofParamOne[2]=220;
ExpNum[2].ValueofParamTwo[2]=480;
ExpNum[2].ExperimentResults[2]=3000;

/* output your first stInputs struct */
puts ("Initial stInputs struct");
myfunction (&stInputs);

/* output values in each of your ExpNum array of struct
* (but note, you only assign one-row in each struct)
*/
puts ("Content of each of ExpNum structs");
for (int i = 0; i < MAXV; i++)
myfunction (&ExpNum[i]);

/* now put all values in your stInputs struct like it appears
* you intended to do?
*/
for (int i = 0; i < MAXV; i++) {
pstInputs->ExperimentResults[i] = ExpNum[i].ExperimentResults[i];
pstInputs->ValueofParamOne[i] = ExpNum[i].ValueofParamOne[i];
pstInputs->ValueofParamTwo[i] = ExpNum[i].ValueofParamTwo[i];
}

/* output the completely filled stInputs struct */
puts ("Output of the completely filled stInputs struct");
myfunction (pstInputs);

return 0;
}

完整示例使用/输出

$ ./bin/expstruct
Initial stInputs struct

NumofParam: 2
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0

Content of each of ExpNum structs

NumofParam: 0
1000.0 200.0 400.0
0.0 0.0 0.0
0.0 0.0 0.0


NumofParam: 0
0.0 0.0 0.0
2000.0 210.0 440.0
0.0 0.0 0.0


NumofParam: 0
0.0 0.0 0.0
0.0 0.0 0.0
3000.0 220.0 480.0

Output of the completely filled stInputs struct

NumofParam: 2
1000.0 200.0 400.0
2000.0 210.0 440.0
3000.0 220.0 480.0

仔细检查一下,如果您还有其他问题,请告诉我。如果我误解了您的问题,请发表评论或编辑您的问题并告诉我。

关于c - 如何将结构体的数组变量传递给另一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52434975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com