-
Notifications
You must be signed in to change notification settings - Fork 113
Revise pass-by-value and pass-by-reference documentation #1033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
82896af
7678cf7
9f9af04
a97e64e
8cd9569
8f61ada
52be9d4
6ac20ea
da9af81
b180605
c7a7af2
9f76506
f28a79f
c71f932
87d3226
9b1e6c5
26c3892
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,54 @@ | ||
| # 値渡しと参照渡し | ||
|
|
||
| プログラミング言語によっては、引数の渡し方に値渡し(pass-by-value)と参照渡し(pass-by-reference)の2種類が存在するものがあります。 | ||
| 関数の実引数(関数呼び出し元引数)に変数を指定したとき、仮引数(関数側引数)への渡し方に値渡し(pass-by-value)と参照渡し(pass-by-reference)の2種類があります(値渡しは更に細かく分けることもできます)。 | ||
| 参照渡しできないプログラミング言語もあります。 | ||
|
|
||
| - 参照渡しできる言語:C++, C#, VB.NET, PHP, Swift など | ||
| - 参照渡しできない言語:C, Java, JavaScript, Python, Ruby など | ||
|
|
||
| ## 値渡し | ||
|
|
||
| 値渡しは、変数が関数に渡るタイミングで、変数が別の変数にコピーされます。元々同じ変数でも、関数の呼び出し元と関数の内部処理では、独立した値になります。そのため、関数の処理で引数に値を代入しても、関数呼び出し元の変数に影響しません。次は、C言語の値渡しの例です。変数`a`は`1`で初期化され、関数`change`に`a`が渡されます。`change`では引数に`2`を代入しますが、呼び出し元の変数`a`は`1`のままです。 | ||
| 値渡しは、変数の値が渡されます。値型変数であれば値のコピーが渡され、参照型変数であれば参照のコピーが渡され参照先の値はコピーされずに共有されます(値共有)。 | ||
| 実引数と仮引数は、独立した変数、独立した値になります。そのため、関数内で仮引数に値を代入しても、関数呼び出し元の変数に影響しません。 | ||
| 次のコードは、C/C++言語の値渡しの例です。変数`a`は`1`で初期化され、関数`change`に変数`a`の値が渡されます。関数`change`内で仮引数に`2`を代入しても、呼び出し元の変数`a`は`1`のままです。 | ||
|
|
||
| ```c | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #include <stdio.h> | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| void change(int n) { | ||
| void change(int n) { // nは値型変数の値渡し | ||
| n = 2; | ||
| } | ||
|
|
||
| int main() { | ||
| int a = 1; | ||
| change(a); | ||
| printf("%d", a); //=> 1 | ||
| printf("%d\n", a); //=> 1 | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
shiracamus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| ## 参照渡し | ||
|
|
||
| 参照渡しは、関数呼び出し元の変数が関数の処理でも共有されます。もし、関数の処理で引数に値を代入すると、関数呼び出し元の変数も変化します。次のコードはC言語の参照渡しの例です。変数`a`は関数`change`に参照渡しされます。`change`は引数に`2`を代入すると、`change`の呼び出し元の変数`a`の値も`2`になります。 | ||
| 参照渡しは、変数自体が渡されます。呼び出し元の変数を参照するようにして変数が共有されます(変数共有)。 | ||
| 実引数と仮引数は、同じ変数、同じ値になります。そのため、関数内で仮引数に値を代入すると、関数呼び出し元の変数に影響します。 | ||
| 次のコードは、C++言語の参照渡しの例です。 変数`a`は`1`で初期化され、関数`change`に変数`a`自体が渡されます(呼び出し元の変数を参照・共有します)。関数`change`内で引数に`2`を代入すると、呼び出し元の変数`a`の値も`2`になります。 | ||
|
|
||
| ```c | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #include <stdio.h> | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| void change(int *n) { | ||
| *n = 2; | ||
| void change(int &n) { // nは値型変数の参照渡し | ||
| n = 2; | ||
| } | ||
|
|
||
| int main() { | ||
| int a = 1; | ||
| change(&a); | ||
| printf("%d", a); //=> 2 | ||
| change(a); | ||
| printf("%d\n", a); //=> 2 | ||
shiracamus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
shiracamus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| ## JavaScriptは値渡し | ||
|
|
||
| JavaScriptではこのような参照渡しをする機能はありません。関数の引数はすべて値渡しになります。したがって、引数に値を代入する処理を関数に書いても、その影響は関数呼び出し元には影響しません。 | ||
| JavaScriptにはこのような参照渡しをする機能はありません。関数の引数はすべて値渡しです。したがって、仮引数に値を代入しても関数呼び出し元には影響しません。 | ||
|
|
||
| ```js twoslash | ||
| function change(n) { | ||
|
|
@@ -52,7 +60,9 @@ console.log(n); | |
| // @log: 1 | ||
| ``` | ||
|
|
||
| ところが、オブジェクトについては少し特殊です。オブジェクトはどこでも参照になります。どういうことかというと、オブジェクトに別の変数名をつけても、オブジェクトが複製されて新たなオブジェクトができるのではなく、異なる変数名同士でひとつのオブジェクトを指すということです。たとえば、次の例のようにオブジェクト`{ n: 1 }`を変数`x`に代入し、さらに`x`を変数`y`に代入すると、`x`と`y`は同じオブジェクトを参照します。もし、`y`のプロパティ`n`を変更すると、`x`の`n`も変化します。 | ||
| ところが、オブジェクトについては少し特殊です。オブジェクトは参照型で変数はオブジェクトを参照します。 | ||
shiracamus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| その変数を別の変数に代入したとき、オブジェクトがコピーされて新たなオブジェクトが作られるのではなく、異なる変数から同じオブジェクトを参照します。 | ||
| たとえば、次のコードのようにオブジェクト`{ n: 1 }`を変数`x`に代入し、さらに変数`x`を変数`y`に代入すると、変数`x`と変数`y`は同じオブジェクトを参照します。変数`y`のプロパティ`n`を変更すると、変数`x`のプロパティ`n`も変更されます。 | ||
|
|
||
| ```js twoslash | ||
| const x = { n: 1 }; | ||
|
|
@@ -62,7 +72,7 @@ console.log(x); | |
| // @log: { n: 2 } | ||
| ``` | ||
|
|
||
| ただし、`y`に別の値を代入した場合は、`x`と`y`は共通のオブジェクトを参照しなくなり、`y`への変更は`x`には影響しなくなります。 | ||
| ただし、変数`y`に別の値を代入した場合は、変数`x`と変数`y`は同じオブジェクトを参照しなくなり、変数`y`のプロパティの変更は変数`x`には影響しなくなります。 | ||
|
|
||
| ```js twoslash | ||
| const x = { n: 1 }; | ||
|
|
@@ -73,7 +83,9 @@ console.log(x); | |
| // @log: { n: 1 } | ||
| ``` | ||
|
|
||
| 以上のようにJavaScriptでは、あるオブジェクトに別の変数をつけたとき、そのオブジェクトを共有するようになっています。共有されたオブジェクトはプロパティを変更した場合、他の変数にもその変更が影響します。この仕様は引数にも同じことが言えます。たとえば、次の例です。オブジェクト`{ n: 1 }`を変数`x`に代入し、さらに`x`を関数`change`の引数`y`に代入すると、`x`と`y`は同じオブジェクトを参照します。`y`のプロパティを変更すると、その影響は関数呼び出し元の`x`のプロパティにも影響します。 | ||
| 以上のようにJavaScriptでは、オブジェクトが代入されてる変数を別の変数に代入したとき、参照先のオブジェクトを共有するようになっています。 | ||
| 共有されたオブジェクトのプロパティを変更すると他の変数にも影響します。この仕様は関数の引数も同様です。 | ||
| たとえば、次のコードのようにオブジェクト`{ n: 1 }`を変数`x`に代入し、さらに変数`x`を関数`change`の引数`y`に渡すと、変数`x`と変数`y`は同じオブジェクトを参照します。変数`y`のプロパティを変更すると、その影響は関数呼び出し元の変数`x`のプロパティも変更されます。 | ||
|
|
||
| ```js twoslash | ||
| function change(y) { | ||
|
|
@@ -85,7 +97,7 @@ console.log(x); | |
| // @log: { n: 2 } | ||
| ``` | ||
|
|
||
| 引数の場合も、変数の再代入の仕様と同様に、`y`に別の値を代入した場合は、`x`と`y`は同じオブジェクトを参照しなくなるため、`y`への変更は`x`に影響しなくなります。 | ||
| 引数の場合も、変数の再代入の仕様と同様に、変数`y`に別の値を代入した場合は、変数`x`と変数`y`は同じオブジェクトを参照しなくなるため、変数`y`への変更は変数`x`に影響しなくなります。 | ||
|
|
||
| ```js twoslash | ||
| function change(y) { | ||
|
|
@@ -102,10 +114,10 @@ console.log(x); | |
|
|
||
| <PostILearned> | ||
|
|
||
| ・JavaScriptの引数は値渡し | ||
| ・JavaScriptにはC言語の参照渡しと同等の仕組みはない | ||
| ・ただし、オブジェクトは値を共有する | ||
| ・共有したオブジェクトを関数で変更した場合、呼び出し元にも影響する | ||
| ・オブジェクトの共有は引数に限ったことではない | ||
| ・JavaScriptの引数はすべて値渡し | ||
| ・JavaScriptにはC++言語の参照渡しと同等の仕組みはない | ||
| ・ただし、オブジェクトは値を共有する | ||
| ・共有したオブジェクトを関数で変更した場合、呼び出し元にも影響する | ||
| ・オブジェクトの共有は引数に限ったことではない | ||
|
||
|
|
||
| </PostILearned> | ||
Uh oh!
There was an error while loading. Please reload this page.