简体   繁体   中英

How can i store values into structure from different function?

Im writing a program containing 3 functions main: define structure(3 variables) and array(storing results) function1: get data from user. function2: calculation.

i know how to use structure inside main, but after storing values in function1, values are not passed to the main function. How can i pass values from function 1 to 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)
{

}

You are passing structure input to the function getInput() by value, not by reference. That means getInput() is working on a copy of input instead of modifying the original input that is being used by main() .

Try this getInput() implementation instead:

void getInput(USER_INPUT *input)
{
    printf("Please enter weight, drag and time: ");
    scanf("%lf %lf %lf", &input->weight, &input->drag, &input->time);
}
  1. variable input is declared in main, actual memory is reserved here.
  2. pass the address of input to function getInput()
  3. getInput() then stores values directly into that memory location. The way the code is written here in this example there is no need to pass values back from this function .
  4. for calculatevelocites if you pass the memory address of input to it then you can use -> within when writing that code, and may make it easier to write and read.
  5. know that passing the address of the variable for a struct is better because you only need the 4 or 8 bytes of that variable which is a memory address. If you don't pass the address using & then whatever function receives that variable has to then need that much memory on the stack to hold the entire contents of the struct. Your example of weight,drag,time is just three 4-byte integers = 12 bytes total, but if your Attribute struct has 10,000+ members taking up XXX bytes then you can easily see how that can quickly become wasteful, and bad. Default linux security setting often imposes an 8MB limit on stacksize, so your program could crash when running if the kernel simply doesn't kill it with no error message. Not passing the memory address would also make the program slower as the Attribute struct gets larger, requiring more memory on the stack to be reserved then releases as the function is called and then when the function exits.
  6. I updated the code below to have getInputTime_BAD . this function allocates memory on the stack for the way the data variable is passed to it, and never sees the memory location of the original allocation of the input variable in main(). This is what's really happening when you don't see the value you entered appear back in the calling function when you do the printf.

-

# 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;
}

output from above:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM