-2

C の学習を始めたばかりで、スワップ関数を実装するためにポインターを使用する必要があるのはなぜですか?

スワップが機能しないバージョン:

#include <stdio.h>

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

int main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(a,b);
   printf("After.  a: %d, b: %d\n", a, b);
   return 0;
}

スワップが機能するバージョン:

#include <stdio.h>

void swap(int *i, int *j) {
   int t = *i;
   *i = *j;
   *j = t;
}

void main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(&a, &b);
   printf("After . a: %d, b: %d\n", a, b);
}
4

4 に答える 4

3

デフォルトでは、関数の引数はC および C++ で値渡しされます。これは基本的に、渡された引数のコピーが関数で受信されることを意味します。このコピーは渡された変数とは異なり、このコピーの変更は渡された引数に反映されません。

したがって、最初のスニペットは、引数自体ではなく、渡された引数のコピーを実際に交換します。

スワップが渡される引数に反映されるようにするには, 参照渡しする必要があります. C ではポインタを使用してこれを実現します. 引数のアドレスが関数に渡され、関数が実際に渡されたメモリアドレスで動作する場所、つまり、値が渡される元の変数。

于 2013-04-23T05:21:41.657 に答える
1
swap(a,b);

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

上記のコードは、変数 i と j がfunctionに対してローカルswapであるため失敗します。つまり、変数のスコープは function に限定されておりswap、関数が終了するとその寿命が失われます。

1 つの回避策は、以下のコードに示すように、アドレスによるパスを使用することです...

swap(&a,&b);

void swap(int* i, int* j) {
   int t = *i;
   i* = *j;
   j* = t;
}

現在、変数 i と j は元の変数 a と b へのポインターです。つまり、それらは a と b の代わりに動作しているため、ポインターの範囲が関数内で制限されていても、変数 a と変数を間接的に変更できます。 b.

于 2013-04-23T05:31:13.177 に答える
0

この方法でスワップを行うことはできません:

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

ijは値で渡されるためです。つまり、ローカル変数と同じですtmp。したがって、 and を変更ijても、実際には渡した変数は変更されません。これは、iand のローカル コピーがjfunction の外に存在しないためですswap()

iそのため、とjfromを変更する必要がある場合は、とのアドレスmain()に渡す必要があります。そのため、次のバージョンが実際に機能します。swap()ijmain()

void swap(int *i, int *j) {
    int t = *i;
    *i = *j;
    *j = t;
}

編集:これらのことをよりよく理解するためにProgramming Paradigms、YouTube で利用できる Stanford Lectures をお勧めします。

于 2013-04-23T06:05:36.407 に答える
0

void main()2 つのプログラムを連続して提示したのはなぜですか?これらは 2 つの別個のプログラムです。には整数変数のaコピーbが渡されますpass-by-value.ローカル変数では、値の変更は に表示されません。pass-by-valueprintf()swap()main()

void swap(int i, int j) {
int t = i;
i = j;
j = t;
printf("After. a:%d,b:%d",i,j);
}

彼が を使用していると主張するかもしれない 2 番目のプログラムはpass-by-reference、本質的pass-by-valueに変数のアドレスのコピーが渡される場所であり、実際のアドレス自体ではありませvoid main()ん。ab

void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}

出力前。a:23 b:47 その後。a:47 b:23

私はそれを実行しました。CodeBlocksしかし、あなたの作者Mr.Void Mainは、16 ビットの Turbo C を使用するように提案したに違いありません。

于 2013-04-23T05:32:24.017 に答える