首页 文章

如何将值存储在不同功能的结构中?

提问于
浏览
1

我正在编写一个包含3个函数main的程序:define structure(3个变量)和array(存储结果)function1:从用户获取数据 . 功能2:计算 .

我知道如何在main中使用结构,但在function1中存储值后,值不会传递给main函数 . 如何将值从函数1传递给main?

#include <stdio.h>

#define G 9.8

typedef struct
{
    double weight;
    double drag;
    double time;
}USER_INPUT;

void getInput(USER_INPUT);
double calculatevelocities(USER_INPUT*);

void main(void)
{
    USER_INPUT input;

    getInput(input);

    printf("%f %f %f\n", input.weight, input.drag, input.time);
}

void getInput(USER_INPUT input)
{
    printf("Please enter weight, drag and time: ");
    scanf("%lf %lf %lf", &input.weight, &input.drag, &input.time);
}

double calculatevelocities(USER_INPUT *data)
{

}

2 回答

  • 2

    您正在通过值将结构 input 传递给函数 getInput() ,而不是通过引用 . 这意味着 getInput() 正在处理 input 的副本,而不是修改 main() 正在使用的原始 input .

    试试这个 getInput() 实现:

    void getInput(USER_INPUT *input)
    {
        printf("Please enter weight, drag and time: ");
        scanf("%lf %lf %lf", &input->weight, &input->drag, &input->time);
    }
    
  • 2
    • 变量输入在main中声明,实际内存在此处保留 .

    • address 输入传递给函数getInput()

    • getInput()然后将值直接存储到该内存位置 . 在此示例中,此处编写代码的方式不需要从此函数传递值 .

    • for calculatevelocites 如果您将输入的内存地址传递给它,那么您可以在编写该代码时使用 -> ,并且可以使其更容易编写和读取 .

    • 知道为 struct 传递变量的地址更好,因为你只需要该变量的4或8个字节,这是一个内存地址 . 如果你没有使用 & 传递地址,那么接收该变量的任何函数都需要那么多内存 on the stack 来保存结构的全部内容 . 你的权重,拖动,时间的例子只有三个4字节整数=总共12个字节,但如果你的 Attribute 结构有10,000个成员占用XXX个字节,那么你可以很容易地看到它如何迅速变得浪费和糟糕 . 默认的Linux安全设置通常会对stacksize施加8MB的限制,因此如果内核根本没有在没有错误消息的情况下杀死它,那么程序运行时可能会崩溃 . 不传递内存地址也会使程序变慢,因为Attribute结构变大,需要保留堆栈上的更多内存,然后在调用函数时释放,然后在函数退出时释放 .

    • 我更新了以下代码以获得 getInputTime_BAD . 此函数在堆栈上为 data 变量传递给它的方式分配内存,并且永远不会在main()中看到 input 变量的原始分配的内存位置 . 当你执行printf时,这就是's really happening when you don't看到你输入的值出现在调用函数中 .

    # include <stdio.h>
    # include <stdlib.h>
    
    # define G               9.8
    
    # define MIN_WEIGHT      0
    # define MAX_WEIGHT      9999
    # define MIN_DRAG        0
    # define MAX_DRAG        9999
    
    /*
         don't do it this way
         typedef struct
         {
            double weight;
            double drag;
            double time;
         }USER_INPUT;
    */
    
    /*
       do a simple structure definition like this:
    
       struct [structure tag]
       {
          member definition;
          member definition;
          ...
          member definition;
       } [one or more structure variables optional here];
    */
    
    
    /* declaring structure named Attribute globally outside of main() */
    /* makes it available to all functions in the file                */
    /* I do not allocate any variables of type Attribute here         */
    /* it is done in main() for this example                          */
    
    
    struct Attribute
    {
       double weight;
       double drag;
       double time;
    };
    
    
    void getInput ( struct Attribute *data )
    {
       char line[128];
       int not_valid;
       int n;
    
       /* FYI your use of scanf without error checking would result  */
       /* in program crash if user did not enter all numbers         */
       /* so i did it this way as an example                         */
    
       /* note the various ways of correct syntax for deferencing    */
       /* the "data" variable                                        */
    
       /* when using   data->membername   then data has to be a pointer !               */
       /* using ->  causes pointer to first be dereferenced, then access the membername */
    
    
       not_valid = 1;
       while ( not_valid )
       {
          printf("enter weight : ");
          fflush( stdout );
          fgets( line, 120, stdin );
          if ( sscanf( line, "%lf", &data->weight ) == 1 )
          {
             if (( data->weight > MIN_WEIGHT ) && ( data->weight <= MAX_WEIGHT ))
             {
                not_valid = 0;
             }
          }
       }
    
    
       not_valid = 1;
       while ( not_valid )
       {       
          printf("enter drag: ");
          fflush( stdout );
          fgets( line, 120, stdin );
    
          n = sscanf( line, "%lf",    &((*data).drag)     );
    
          if ( n == 1 )
          {
             if (( (*data).drag > MIN_DRAG ) && ( data->drag <= MAX_DRAG ))
             {
                not_valid = 0;
             }
          }
       }
    }
    
    
    void getInputTime_BAD ( struct Attribute data )
    {
       char line[128];       
       int n, not_valid = 1;
    
       while ( not_valid )
       {
          printf("enter time: ");
          fflush( stdout );
          fgets( line, 120, stdin );
    
          n = sscanf( line, "%lf",    &(data.drag)     );
    
          if ( n == 1 )
          {
             if (( data.drag > MIN_DRAG ) && ( data.drag <= MAX_DRAG ))
             {
                not_valid = 0;
             }
          }
       }
       printf("just read %lf for time\n", data.drag );
    
    }
    
    
    double calculatevelocities(struct Attribute *data)
    {
    
    }
    
    
    int main ( void )
    {
       struct Attribute input;
    
       input.weight = -1;
       input.drag   = -1;
       input.time   = -1;
    
       getInput(&input);   /* pass address of variable input */
    
       printf("weight = %lf\n", input.weight );
       printf("drag   = %lf\n", input.drag );
    
       getInputTime_BAD( input );  /* not passing address */
    
       printf("time in main() = %lf\n", input.time );
    
       return 0;
    }
    

    以上输出:

    sles:~ # ./new1.x
    enter weight : 1212
    enter drag: 2323
    weight = 1212.000000
    drag   = 2323.000000
    enter time: 4545
    just read 4545.000000 for time
    time in main() = -1.000000
    

相关问题