例を見て、値による呼び出しと参照による呼び出しがどのように行われているかを見てみましょう。
メイン関数の 2 つの数値を関数の値による呼び出しで交換できない理由と、この問題を解決する方法について詳しく説明します。
静かに教えてください: 私は main 関数の 2 つの数値が関数の値による呼び出しでは交換できないことしか知りませんでしたが、なぜそれが機能しないのかはまだわかりません。今でもこの疑問を抱くなら、小さなベンチを置いて座って、私が原理を詳しく説明するのを聞いてください。
目次
例: 2 つの変数を交換する
例:
「2 つの整数変数の内容を交換する関数を作成する」
1. 外部関数を書いて交換しない
まず、外部関数を記述して 2 つの数値の値を交換しない場合は、次のようになります。
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = 0;
printf("交换前:a=%d b=%d\n", a, b);
c = a;
a = b;
b = c;
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
出力
交換前:a=10 b=20
交換後:a=20 b=10
しかし今、外部関数を書いて a と b を交換する必要があります。
2.関数を値で呼び出して、 2 つの番号を交換してみます
上記のアイデアに従って、次のコードを作成しました。
#include<stdio.h>
void Swap(int x, int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
int main()
{
int a = 10;
int b = 20;
printf("交换前:a=%d b=%d\n", a, b);
//函数
Swap(a, b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
しかし、それを実行して
、操作の結果が次のようになることを確認しましょう。
交換前:a=10 b=20
交換後:a=10 b=20
a と b の値は変更されていません。
どうしてこれなの?
値による呼び出しの原則
実際には、
実パラメータ a と b が仮パラメータ x と y に渡されると、仮パラメータは実パラメータの一時的なコピーになります. 仮パラメータ
変数 x と y を変更しても、実パラメータ a と b には影響しません。 . (実引数と仮引数の概念とまとめは記事の最後に置いてあります。必要に応じて先に読んでください。) 詳細については、見てみましょう。原理は次のとおり
です
。 10 に値があり、20 の値が b に配置されます;
次に、関数 Swap を介してパラメーターを渡し、変数 x と変数 y を作成し、x に a の 10 を取得し、y に b の 20 を取得します。
次に、変数 z を介して、x と y の値を交換します。x と y は独立したメモリ空間であり、x と y の値を変更しても a と b にはまったく影響しないことを
知っておく必要があります。したがって、a と b の値はまったく交換されません。
#では、上記の問題をどのように解決するのでしょうか?
3.関数を参照で呼び出して2 つの番号を交換する(肯定的な解決策)
上記の例から、スペースの観点から、実パラメータと仮パラメータの間に接続はなく、仮パラメータは上記の方法で実パラメータを変更できないことがわかります。次に、それらを接続する必要があります。
ポインタ変数 pa を介して a のアドレスを取得します。
int a = 10;
int* pa = &a;
a の値を pa で変更する
*pa = 20;//pa が指すアドレスの値 (つまり、a に格納されている値) を 20 に変更します。
このように、a のアドレスが pa に格納され、pa と a が接続されます。a のアドレスは pa で確認でき、a の値を変更できます。
#include<stdio.h>
int main()
{
int a = 10;
int* pa = &a;
*pa = 20;
printf("%d\n", a);
return 0;
}
実行して取得する
20
a の値が実際に変化したことがわかります。この考えに従って、a と b のアドレスを Swap 関数に渡します。
スワップ(&a, &b);
次に、Swap(&a, &b) にアドレスが渡され、アドレスがポインター変数に配置されるため、外部 Swap 関数のパラメーターはポインター変数である必要があります。
スワップ(int* px, int* py)
{ }
a のアドレスはポインタ px に格納され、b のアドレスは py に格納され、
px が指すアドレスの値 (つまり a の値) と py が指すアドレスの値 (つまり、b) の値は、変数 z を介して交換されます。
void Swap(int* px, int* py)
{
int z = 0;
z = *px;//*px相当于是a
*px = *py;//*py相当于是b
*py = z;
}
コード全体はこんな感じ
#include<stdio.h>
void Swap(int* px, int* py)
{
int z = 0;
z = *px;
*px = *py;
*py = z;
}
int main()
{
int a = 10;
int b = 20;
printf("交换前:a=%d b=%d\n", a, b);
//函数
Swap(&a, &b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
まだ理解できなくても、慌てる必要はありません。絵を描いて、それがどのように機能するかを見てみましょう。
アドレスによる呼び出しの原則
最初に、変数 a と b を作成し、その値はそれぞれ 10 と 20 です.
a と b は、a の空間の開始アドレスが 0x0012ff40
空間の開始アドレスであると仮定して、メモリ内の空間を開きますb は 0x0012ff48 です。
次に Swap 関数でパラメータを渡し、a のアドレス (0x0012ff40) を px に渡し、b のアドレス (0x0012ff48) を py に渡します。このとき、a のアドレスは px に配置され、アドレスはa と b の値は px と py を介して検出されるため、
a と b の値を交換します。
値による呼び出しと参照による呼び出しを一緒にします。
関数パラメータの概念
関数パラメーターの概念を見てみましょう:
関数パラメーター
1 実際のパラメータ (実際のパラメータ):
関数に実際に渡されるパラメーターは、実パラメーターと呼ばれます。実際のパラメータは、定数、変数、式、関数などです。
実際のパラメータがどのような量であっても、関数が呼び出されたときにこれらの値を仮パラメータに転送できるように、それらは明確な値を持っている必要があります。
2 つの仮パラメータ (パラメータ):
仮パラメーターは関数名の後の括弧内の変数を参照します。これは、仮パラメーターは関数が呼び出されたときにインスタンス化される (割り当てられたメモリ単位) だけであるため、仮パラメーターと呼ばれます。
関数呼び出しが完了すると、仮パラメーターは自動的に破棄されます。したがって、仮パラメータは関数内でのみ有効です。
上記の Swap1 および Swap2 関数のパラメータ x、y、px、py はすべて仮パラメータです。main 関数で Swap1 に渡される a、b と、Swap2 関数に渡される &a、&b は、実際のパラメーターです。
私の能力が限られているため、間違っている場合は修正してください。
この記事が役に立った場合は、「いいね!」と「注意」を忘れずに!
最近、関連するコンテンツをまとめています。私をフォローして、私の記事をもっと見ることができます。
結局のところ、私たちは一緒に学び、一緒に進歩するつもりです!