「C言語/関数」の版間の差分
削除された内容 追加された内容
647 行
#include "stdio.h"
// グロ-バル変数を使って、交換用の変数をswap外部と共有しようと意図しているが・・・
void swap(int a, int b){▼
int a;
int b;
void swap(int a,int b) {
x = a;
a = b;
671 ⟶ 675行目:
こう失敗する原因は、呼び出され側のswap()の引数で用いられている値を格納する変数(上記コード例の<code> swap(int a,int b) </code> のaおよびb )は、必ず型をつけて再宣言しないといけないのでローカル変数になってしまうので、その変数をグローバル変数に出来ないから、である。
たとえグローバル領域で「a」「b」と同名の変数があっても、swap関数内では同名なだけの別変数としてのローカル変数「a」「b」が新たに関数swap内では用意されてしまう。
なお、swap関数の引数を定義する際に、(再宣言しないつもり等で)型をつけない事はできない。
ユーザ定義関数内で変数の値を交換させるためには、一例として、下記のようにポインタを使ってmain関数の変数a,bを書き換える方法がある。
<syntaxhighlight lang="C">
700 ⟶ 703行目:
</syntaxhighlight>
この例は意図通りに動作す
<pre>
swap前のa=1, b=2
707 ⟶ 710行目:
と表示される。
ポインタを使うと成功する理由は、main実引数のアドレスが仮引数にコピーされたため、swap関数がmain関数の変数a,bにアクセスできているからである。(つまり、ポインタを介したswap関数内のa,bはもはやローカル変数ではなく、グローバル変数などにアクセスできる。)
例6のように実引数の値を仮引数にコピーすることを''値渡し''と呼ぶ。▼
例7のように実引数のアドレスを仮引数にコピーすることを''参照渡し''と呼ぶ。▼
なお、
<ref>値渡しと参照渡しという用語はよく使われるが、『JISX3010:2003』には出てこない。</ref>
----
なお、ユーザ定義関数を何も書かずに全てmain関数に書く方法を使えば、ポインタを使わずとも交換できる。
<syntaxhighlight lang="C">
//例 誤ったswap関数
#include "stdio.h"
int main(){
int a = 1, b = 2;
printf("swap前のa=%d, b=%d\n", a, b);
int x;
x = a;
a = b;
b = x;
printf("swap後のa=%d, b=%d\n", a, b);
}
</syntaxhighlight>
<pre>
swap前のa=1, b=2
swap後のa=2, b=1
</pre>
なお、ポインタも使わず、グローバル変数を使わずに下記のようにswap関数を書いても、交換できない。
<syntaxhighlight lang="C">
//例 誤ったswap関数
#include "stdio.h"
▲void swap(int a, int b){
int x;
x = a;
a = b;
b = x;
}
int main(){
int a = 1, b = 2;
printf("swap前のa=%d, b=%d\n", a, b);
swap(a, b);
printf("swap後のa=%d, b=%d\n", a, b);
}
</syntaxhighlight>
<pre>
swap前のa=1, b=2
swap後のa=1, b=2
</pre>
----
=== 関数の引数として配列を渡す ===
|