我正在编写一个包含3个函数main的程序:define structure(3个变量)和array(存储结果) function1:从用户获取数据。 function2:计算。
我知道如何在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)
{
}
答案 0 :(得分:2)
您正在通过值将结构input
传递给函数getInput()
,而不是通过引用。这意味着getInput()
正在处理input
的副本,而不是修改input
正在使用的原始main()
。
请尝试使用此getInput()
实现:
void getInput(USER_INPUT *input)
{
printf("Please enter weight, drag and time: ");
scanf("%lf %lf %lf", &input->weight, &input->drag, &input->time);
}
答案 1 :(得分:2)
calculatevelocites
,那么您在编写该代码时可以使用->
,并且可以更容易地编写和读取struct
传递变量的地址更好,因为你只需要该变量的4或8个字节,这是一个内存地址。如果你没有使用&
传递地址,那么接收该变量的任何函数都需要那么多的内存来保存结构的全部内容。你的重量,拖动,时间的例子只有三个4字节整数=总共12个字节,但如果你的Attribute
结构有10,000多个成员占用XXX个字节,那么你可以很容易地看到它如何迅速变得浪费,并且坏。默认的linux安全设置通常会对stacksize施加8MB的限制,因此如果内核根本没有在没有错误消息的情况下杀死它,那么程序运行时可能会崩溃。不传递内存地址也会使程序变慢,因为Attribute结构变大,需要保留堆栈上的更多内存,然后在调用函数时释放,然后在函数退出时。getInputTime_BAD
。此函数在堆栈上为data
变量传递给它的方式分配内存,并且永远不会在main()中看到input
变量的原始分配的内存位置。当您执行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;
}
从上面输出:
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