2017-02-06 5 views
1

3つの関数を含むプログラムを書く。main:構造体を定義する(3つの変数)と配列(結果を格納する) function1:ユーザーからデータを取得する。 function2:計算。どのようにして異なる機能の構造に値を格納できますか?

私はメインの内部で構造体を使用する方法を知っていますが、 ですが、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

は、私はあなたがそうでないか、getInputにポインタとしてそれを構造体を渡す必要が関数1でポインタを使用カントが、関数2 – user133174

+0

でそれを使用することができます動作しません。 – koper89

答えて

2
  1. 、実際のメモリがここに予約されています。
  2. か、getInputを(機能するアドレスの入力を渡す)
  3. か、getInput()、そのメモリロケーションに直接値を格納します。この例でコードを書く方法は、の値をに戻す必要はありません。
  4. calculatevelocites入力のメモリアドレスを渡すと、そのコードを書くときに->を使用して書き込みと読み取りを容易にすることができます。
  5. structの変数のアドレスを渡す方が、メモリアドレスであるその変数の4バイトまたは8バイトしか必要ないので、より良いことがわかります。 &を使用してアドレスを渡さない場合は、その変数を受け取る関数が何であれ、スタック上に多くのメモリを必要とします。は構造体の内容全体を保持します。あなたの体重、ドラッグ、時間の例は、合計4バイトの整数= 12バイトですが、Attribute構造体に10,000バイト以上のメンバーがある場合、そのデータがどのように素早く無駄になり、悪くなるか簡単に分かります。デフォルトのLinuxセキュリティ設定では、stacksizeに8MBの制限が課されることが多いため、カーネルがエラーメッセージなしでプログラムを強制終了しないと、プログラムがクラッシュする可能性があります。また、メモリアドレスを渡さないと、Attribute構造体が大きくなるにつれてプログラムが遅くなり、スタック上のより多くのメモリが予約され、関数が呼び出されたときに解放され、関数が終了するときに解放されます。
  6. 以下のコードを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 
+0

リファレンスを渡すという概念を理解するのを助けてくれてありがとう! – user133174

2

あなたはない参照することにより、値によって機能getInput()に構造inputを渡しています。つまり、main()で使用されている元のinputを変更する代わりにgetInput()inputのコピーを処理しています。

代わりにこのgetInput()実装を試してみてください:変数入力がメインで宣言されている

void getInput(USER_INPUT *input) 
{ 
    printf("Please enter weight, drag and time: "); 
    scanf("%lf %lf %lf", &input->weight, &input->drag, &input->time); 
} 
関連する問題