1

ポインターに問題があります。

その要点は、1つの関数でポインターを定義し、その関数をメインで呼び出してそれらのポインターを使用しようとしていることです。私の課題の正確な指示は次のとおりです。

キーボードから 3 つの数値を読み取る関数と、これらの 3 つの数値に関する情報を出力する関数の 2 つの関数を作成します。

入力機能

3 つの整数ポインター パラメーターを持ち、ユーザーに 3 つの整数を入力するよう求める関数を作成します。キーボードで入力された値は、ポインタ パラメータに格納されているアドレスに読み込まれる必要があります。

注: scanf には変数のアドレスが必要であり、ポインターはアドレスを格納することを思い出してください。

値の印刷

a2question2 という 2 番目の関数を、戻り値もパラメーターも指定せずに作成します。関数は 3 つの整数変数を宣言し、入力関数を使用してこれらの変数に値を読み込む必要があります。関数は、合計、平均、積、およびこれらの数値の最小値と最大値を出力する必要があります。

これが私がこれまでに持っているものです:

int pntloc (int *x, int *y, int *z){
  int a = 0;
  int b = 0;
  int c = 0;

  printf("Please enter integer #1: ");
  scanf ("%d", & a);
  printf ("Please enter integer #2: ");
  scanf ("%d", & b);
  printf("Please enter integer #3: ");
  scanf ("%d", & c);

  *x = &a;
  *y = &b;
  *z = &c;

  return *x, *y, *z;
}

// Fourth function
main (){
  int x, y, z;
  pntloc(x, y, z);

  int sum = 0;
  int average = 0;
  int product = 0;
  int smallest = 0;
  int largest = 0;

  printf ("%d", x);
}

しかし、プログラムが 3 つの整数を要求した後、何もせずにクラッシュします。

最初の関数はそれ自体で正常に動作します (パラメーターなしでメイン関数にしてテストし、ポインター値を出力しました)。

printf ("%d", *x);

したがって、ある関数から次の関数に値が渡されていないと思います。最初と 2 番目の関数を書くさまざまな方法を試しましたが、何もうまくいかないようです。

私が得た最善の方法は、プログラムがクラッシュしないようにすることでしたが、出力された値は以前に入力したものとはどこにもありませんでした。

これを行う方法はありますか?

4

3 に答える 3

5

次の 2 つのエラーが原因で、プログラムがクラッシュしている可能性があります。

1)変数のローカルアドレスを返しています a, band c:

*x = &a; // This line says follow the 'x' pointer, and set the value there to
         // the address of 'a'

はローカルに (つまり、関数内で) 定義されているためa、関数が戻ると、そのアドレスは無効になります。

あなたがおそらく意味したことは次のとおりです。

*x = a; // Follow the 'x' pointer, and set the value there to the value of 'a'

2)ポインタを渡していませんpntloc()(コンパイラはこれについて警告するはずです)

int x, y, z;
pntloc(x, y, z); // The passes the VALUES of x, y and z

あなたはおそらく次のことを意味していました:

pntloc(&x, &y, &z); // Pass the ADDRESSES of x, y and z

クラッシュを引き起こしていないその他の改善点:

pntloc()ローカル変数を使用しないことで、大幅に短縮できます。

void pntloc (int *x, int *y, int *z){
  printf("Please enter integer #1: ");
  scanf ("%d", x);
  printf ("Please enter integer #2: ");
  scanf ("%d", y);
  printf("Please enter integer #3: ");
  scanf ("%d", z);
}

が呼び出し&内で削除されていることに注意してください。scanf()あなたはコメントでそれについて尋ねたので、ここにもう少し説明&xがあります.「xのアドレス」と言いますが、ポインタがある場合は、すでにアドレスを持っています. 簡単な例:

int a;       // 'a' is an integer variable
int *b = &a; // 'b' is a pointer to the integer variable 'a'

scanf("%d",&a); // This statement reads an integer into 'a'.
                // We pass it the address of 'a', which is written &a
scanf("%d",b);  // This statement also reads an integer into 'a'.
                // We pass it the address of 'a', which is stored 
                // in the pointer 'b'.

関数にポインターが渡されているため、次のようになります。

void pntloc (int *x, int *y, int *z){  // Three pointers to ints

それらを直接 に渡すことができscanf()、使用する必要はありません (使用すべきではありません) &

return ステートメントも削除したことに注意してください。

 return *x, *y, *z; 

このreturnステートメントは、あなたが思っていることをしているとは思いません。C では、関数からの戻り値は 1 つしか許可されないことに注意してください。

しかし、なぜそれはコンパイルされるのでしょうか? さて、ここで何が起こっているのか - しかし、混乱している場合は、このビットを無視してかまいません:コンマ演算子は左から右に評価され、左側の結果は途中で破棄されます。したがって、 return ステートメントは次と同等です。

*x;
*y;
return *z;

コンマ演算子は、左側のステートメントに副作用があり、すべてを 1 行に書きたい場合に便利です。私の意見では、これによりコードが読みにくくなりますが、1 つまたは 2 つの状況でコードがすっきりします。初心者には、次のルールをお勧めします。関数の丸括弧内ではコンマのみを使用してください。

関数を呼び出したときに関数からの戻り値を使用していなかったため、次のようになります。

pntloc(&x,&y,&z);

リターンを完全に削除し、リターン タイプを に設定しましたvoid

于 2013-06-19T01:15:46.130 に答える