【问题标题】:Returning an array of structs from a function - C programming从函数返回结构数组 - C 编程
【发布时间】:2014-04-15 17:50:56
【问题描述】:

所以我正在尝试编写一个函数,该函数将返回一个包含多个值的数组。目前,它运行正常,但只输出最终计算值。我将如何使其输出包含所有计算值?

我的代码如下所示:

//Practice to output an array of structs

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct boat_params {
    double V, Uc, Vc;
    };

struct boat_params submerged_volume(double L1, double L2, double Lavg, double H) {

    struct boat_params volume;

    double V_sub, Uc_sub, Vc_sub;
    V_sub = 0;

    //Boat description
    double C, delta;
    double theta, theta_rad, theta_min, theta_min2, theta_lim, theta_lim2, theta_lim_deg;
    double Ug1, Ug2, Vg1, Vg2, V1, V2;
    double pi; 

    pi = 4*atan(1);
    C = sqrt(L1*L1 + L2*L2);
    delta = acos(L1/C);

    theta_lim = asin(H/L1);
    theta_lim_deg = (theta_lim/pi) * 180.0;
    theta_min = asin(H/C) - delta; 
    theta_min2 = 0;

    //Calculating the submerged volume and centre of gravity for each different angle
    for (theta = 0; theta <= 10; theta ++) {

    //**Note: I've taken out the actual calculations of V_sub, Uc_sub, and Vc_sub for brevity**


        volume.V = V_sub;
        volume.Uc = Uc_sub;
        volume.Vc = Vc_sub;
        }


    return volume; 

    }


int main () {

double L1, L2, Lavg, H;
struct boat_params volume; 

L1 = 17.6; 
L2 = 3; 
Lavg = 4;
H = 4.5;

volume = submerged_volume(L1, L2, Lavg, H);

printf("V = %lf\nUc = %lf\nVc = %lf\n", volume.V, volume.Uc, volume.Vc);

return 0;

}

我可以让它正确输出最后计算的值(对于 theta = 10),但这是我得到的唯一值。我将如何计算每个 theta 值的 V_sub、Uc_sub 和 Vc_sub?并输出每个值。我假设这意味着将结构转换为数组并用该结构的值填充数组的每个元素,但我不知道该怎么做!

非常感谢任何帮助,并提前感谢您。

另外:如果可能的话,我想避免使用指针,但请理解这可能是不可能的!我还是新手,不擅长使用它们!

【问题讨论】:

    标签: c arrays function struct


    【解决方案1】:

    你说的很对,你需要有一个数组。如果数组中的元素数量是恒定的,您还可以创建一个包含该数量元素的结构,但请不要这样做。
    要对数组进行操作,您将 - 不幸的是 - 需要指针。在 C 中执行此操作的一种非常常见的方法是不返回指针,而是传递一个“结果”指针。这意味着由函数的用户分配空间和释放它,他也可以使用数组的语法。在您的代码中,值的数量似乎是恒定的,这使得上述解决方案成为可能。或者,您可以在堆上分配空间(使用malloc)并返回一个指针,但这意味着用户需要释放他从未分配过的内存,这与直觉相反,如果他忘记这样做可能会导致内存泄漏。考虑以下解决方案:

    void submerged_volume(double L1, double L2, double Lavg, double H, struct boat_params *result) {
        // your calculations here
        for (theta = 0; theta <= 10; theta ++) {
            (result+theta)->V = V_sub;
            (result+theta)->Uc = Uc_sub;
            (result+theta)->Vc = Vc_sub;
        }
    }
    
    // somewhere in your code where you want to use your function
    struct boat_params values[11];
    unsigned char i = 0;
    submerged_values(/* parameters */, values);
    for (; i <= 10; ++i) {
        printf("V = %lf\nUc = %lf\nVc = %lf\n", values[i].V, values[i].Uc, values[i].Vc);
    }
    

    【讨论】:

    • 你需要通过values而不是&amp;values
    • 你说的很对,我不知道当时我脑子里在想什么。
    • 我之前没见过result+theta语法……这是什么?还是这只是渐进式的?
    • 好吧,再经历一下(抱歉,我花了点时间!)。我想澄清一些事情......你在哪里调用结构是作为函数的输入。这与我在代码中所做的相同吗?另外,我是否不需要在我的 theta for 循环中使用计数器 (i) 和 printf 语句来打印计算的值,然后再重新分配它?
    • 这里的结果是一个指针,所以result+theta也是一个指针。 C 中的指针算法确保它是数组中的 thetath 值,指针指向其第一个元素。它相当于result[theta].V = V_sub;。我不太确定为什么我选择了不同的语法,请随意使用任何适合您的语法。
    【解决方案2】:

    试试这个,只需将你的逻辑添加到循环和数学中:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define ARRSIZE 100
    
    typedef struct boat_params {
      double  V, Uc, Vc;
    } Volume;
    
    struct boat_params submerged_volume(double L1, double L2, double Lavg, double H, Volume *volumes[]) {
      double theta;
    
      int i = 0; /* only example, change as needed */
      Volume *p;
      for (theta = 0; theta <= 10; theta ++) {
        p = malloc(sizeof(* p)); 
        if (p == NULL) {
          printf("malloc failed to allocate a new space");
          exit(0);
        }                   
    
        p->V = 1; //V_sub;
        p->Uc = 2; //Uc_sub;
        p->Vc = 3; //Vc_sub;
    
        volumes[i] = p;
        i++;
      }
    
    }
    
    
    int main () {
      double L1, L2, Lavg, H;
    
      L1 = 17.6; 
      L2 = 3; 
      Lavg = 4;
      H = 4.5;
    
      Volume *volumes[ARRSIZE];
    
      submerged_volume(L1, L2, Lavg, H, volumes);
      printf("V = %lf\nUc = %lf\nVc = %lf\n", volumes[0]->V, volumes[0]->Uc, volumes[0]->Vc); /* first element for example */
    
      return 0;
    }
    

    如果事先不知道volumes数组的大小,可以考虑使用链表。

    【讨论】:

    • 我不是反对者,但您的代码不返回任何数组,它将值放入全局数组中。另外,不要强制转换 malloc。
    • 谢谢!我得到它并修复了。
    猜你喜欢
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 2016-12-09
    • 2019-08-21
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多