【问题标题】:Outputting returning a struct from a function输出从函数返回的结构
【发布时间】:2014-04-03 18:26:18
【问题描述】:

所以我试图从 C 中的函数输出一个结构。到目前为止的代码是:

//Step 1: Create a volume function that outputs a volume structure
//Step 2: Input boat dimensions from main
//Step 3: Use outputted volume values to calculate centre of gravity/buoyancy
//Step 4: Use values 

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

//Struct to fill with the values calculated in the submerged_volume function
struct vol {
    double V, Uc, Vc;
    };

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

    double C, delta, a, b, d;
    double theta, theta_rad, theta_min, 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_lim2 = 0;

    //Calling the structure to fill with values
    struct vol volume;


    double V_sub, Uc_sub, Vc_sub;
    V_sub = 0;

    //Volume calculations

    for (theta == 0; theta <= 10; theta = theta + 0.5) {
        theta_rad = (theta * pi)/180.0;
        //if (H > L2) { 
        printf(" H > L2\n");                          //Case where H > L2
            if (theta_rad > theta_lim) {
                V_sub = Lavg * L2 * (L2/(2.0 * tan(theta_rad)) + L1 - H/sin(theta_rad));
                //Case of triangle plus rectangle
                V1 = Lavg * L2 * L2/(2.0 * tan(theta_rad));     
                V2 = Lavg * L2 * (L1 - H/sin(theta_rad));
                Ug1 = -(H/sin(theta_rad) - L2/tan(theta_rad) + L2 * (cos(theta_rad)/(3.0*sin(theta_rad/2.0))));
                Vg1 = -(L2 - sin(theta_rad/2.0) * (L2/(3.0 * sin(theta_rad/2.0))));
                Ug2 = -(L1 + H/sin(theta_rad))/2.0;
                Vg2 = -L2/2.0;           //b 
                }
            else if (theta_rad > theta_min) {
                V_sub = Lavg * tan(theta_rad)/2.0 * pow((L1 - L2 * tan(theta_rad) - ((H - L2/cos(theta_rad))/sin(theta_rad))), 2);
                //Case of a triangle only 
                V1 = V_sub;
                V2 = 0; 
                Ug1 = -1.0/3.0 * (2.0 * L1 + L2 * tan(theta_rad) + (H - L2/cos(theta_rad))/sin(theta_rad));
                Vg1 = -(L2 - tan(theta_rad)/3.0 * (L1 - (H - L2/cos(theta_rad))/sin(theta_rad) - L2 * tan(theta_rad)));
                }
            else {
                V_sub = 0; 
                }
            //}

            if (V_sub != 0) {
            Uc_sub = Ug2 - V1/(V1 + V2) * (Ug2 - Ug1);
            Vc_sub = Vg2 - V1/(V1 + V2) * (Vg2 - Vg1);
            //moment = m * g * (b*sin(theta_rad) - a*cos(theta_rad)) + (Uc * cos(theta_rad) - Vc * sin(theta_rad)) * Fa - d * Fm;
            //fN = -(f * Fm * cos(theta_rad));
            //friction = m * g - Fa - Fm * sin(theta_rad);
            }
        }
    volume.V = V_sub;
    volume.Uc = Uc_sub;
    volume.Vc = Vc_sub;



    /*
    volume.V = 110;
    volume.Uc = 10;
    volume.Vc = 10;
    */

    return volume;
    }

int main() {

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

    printf("Enter L1: \n");
    scanf("%lf", &L1);
    printf("Enter L2: \n");
    scanf("%lf", &L2);
    printf("Enter Lavg: \n");
    scanf("%lf", &Lavg);
    printf("Enter H: \n");
    scanf("%lf", &H); 

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

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

    return 0;
    }

我第一次尝试只使用一个设定的 theta 值 (theta == 5),效果很好。我不知道我是否能做到这一点,但我基本上想在通过 for 循环时为 theta 的每个值设置一个 V、Uc 和 Vc 的值。这可能吗?我希望这可以解释清楚,如果需要更多详细信息,请告诉我。提前致谢!

【问题讨论】:

  • 只是一个注释,在 C 中,您通常只需将指针传递给要“返回”的结构,这是为了避免在堆栈上传递返回值所需的内存副本(因为结构通常更大比基本类型)。
  • 您的期望是结果将是struct vol 的数组,每个数组都包含给定值theta 的结果?他们应该如何相互映射/索引?如果theta == 0, volume_array[0] 包含生成的struct vol 是否足够?
  • 对不起,我不明白你的意思?我是 C 的新手,所以所有这一切对我来说都很陌生……你能解释一下吗?
  • 只需返回struct。正如@Joseph 所指出的,“编译器可能会消除不必要的复制”。

标签: c function struct


【解决方案1】:

我相信实现这一点的正确方法是通过引用或指针将输出结构传递给函数:

// Declare
void submerged_volume(double L1, double L2, double Lavg, double H, struct vol& out);

// Use
struct vol volume;
submerged_volume(L1, L2, Lavg, H, volume);

或者通过指针:

// Declare
void submerged_volume(double L1, double L2, double Lavg, double H, struct vol *out);

// Use
struct vol volume;
submerged_volume(L1, L2, Lavg, H, &volume);

【讨论】:

  • 使用对结构的引用调用函数或让函数返回指向(不同)结构的指针。
【解决方案2】:

第 1 点:您的代码至少有一个错误,这可能是您的问题的原因。快速编译给了我以下警告:

 In function 'submerged_volume':
40: warning: statement with no effect
40: warning: 'theta' is used uninitialized in this function
35: warning: 'Vc_sub' may be used uninitialized in this function
35: warning: 'Uc_sub' may be used uninitialized in this function
19: warning: 'Vg2' may be used uninitialized in this function
19: warning: 'Ug2' may be used uninitialized in this function

特别是第 40 行:

for (theta == 0; theta <= 10; theta = theta + 0.5) {
           ^^
           want "=" here

第 2 点:顺便说一句,您应该忽略有关 submerged_volume 使用指针而不是返回 struct 的建议,原因有两个。

  • 这里的结构很小,没有任何区别。
  • 编译器可能会消除不必要的复制(例如,通过隐式使用指针)。

第 3 点: OP 澄清说他/她希望返回一个 array 结构。在这种情况下,我们确实需要添加指针,因为数组不是 C 中的“第一类对象”。类似于:

main():

 struct vol volume[21];
 // ...
 submerged_volume(L1, L2, Lavg, H, volume);
 // ...

submerged_volume():

 void submerged_volume(double L1, double L2, double Lavg, double H, struct vol out[])
 // ...
 int i = theta * 2;
 // ...
 out[i].V  = V_sub;  // at bottom of loop
 out[i].Uc = Uc_sub;
 out[i].Vc = Vc_sub;

或者使用可能更常见的成语:

 void submerged_volume(double L1, double L2, double Lavg, double H, struct vol *out)
 // ...
 out->V  = V_sub;  // at bottom of loop
 out->Uc = Uc_sub;
 out->Vc = Vc_sub;
 out++;

(注意我在这里使用硬编码的21 是个坏主意。)

【讨论】:

  • 编辑:顺便说一句,您应该忽略有关使用指针而不是返回struct 的建议,原因有两个。 1)这里的结构很小,没有区别。 2) 编译器可能会消除不必要的复制。
  • 您好,抱歉,我离开了,现在才看到这个……我不太明白您的意思。基本上,我试图返回一个结构数组。
猜你喜欢
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 2020-03-03
相关资源
最近更新 更多