(Translated by https://www.hiragana.jp/)
引数 - Wikipedia コンテンツにスキップ

引数ひきすう

出典しゅってん: フリー百科ひゃっか事典じてん『ウィキペディア(Wikipedia)』
かり引数ひきすうから転送てんそう

引数ひきすう(ひきすう、えい: parameter, argument)は、数学すうがくにおける関数かんすうコンピュータプログラムにおける手続てつづにおいて、その外部がいぶをやりとりするための特別とくべつ変数へんすう、あるいはその変数へんすうのことである。

数学すうがく最適さいてき問題もんだいかんするそれ(「パラメータ」とカタカナ表現ひょうげんされることがおおい)については「媒介ばいかい変数へんすう」の記事きじ参照さんしょうのこと。以下いかもっぱコンピュータプログラミングかんして説明せつめいする。

関数かんすうサブルーチンメソッドひとし定義ていぎするときに、外部がいぶからわたされる特別とくべつ変数へんすうとして指定していされるのがかり引数ひきすう関数かんすうひとし)を呼出よびだしきにおいて、かり引数ひきすう対応たいおうするしき(あるいはその)がじつ引数ひきすうである。実行じっこうには、じつ引数ひきすうかり引数ひきすうる。

引数ひきすう」を「いんすう」とかたもある[1][2]が、術語じゅつごとしては変則へんそくてき湯桶読ゆとうよして「ひきすう」としている。数学すうがく分野ぶんや因数いんすう(factor)との取違とりちがえをふせぐためといった理由りゆうもある。

かり引数ひきすう

[編集へんしゅう]

かり引数ひきすう(かりひきすう、かびきすう、parameterformal parameter (formal argument))とは、手続てつづき(プロシージャー)定義ていぎされる変数へんすうのうち、実行じっこうもとからわたされる(じつ引数ひきすうの)けるものをいう。れいとしてC言語げんごけい言語げんごにおける定義ていぎげる:

int sum(int addend1, int addend2)
{
    return addend1 + addend2;
}

うえ定義ていぎでは、

  • int かたかり引数ひきすう addend1
  • int かたかり引数ひきすう addend2

2つをともなった関数かんすう sum定義ていぎしている。定義ていぎなかaddend1addend2変数へんすうのように使用しようされていることに注目ちゅうもくされたい。

じつ引数ひきすう

[編集へんしゅう]

じつ引数ひきすう(じつひきすう、argumentactual argument (actual parameter))とは、プロシージャーをさいわたのことで、プロシージャーの挙動きょどう動作どうさ結果けっか)に作用さようする。変数へんすうリテラルふくしき指定していできる。C言語げんごけい言語げんごにおいてまえしめしたれいちゅう関数かんすう sumもちいたれいげる:

 sum(123, 456);

うえぶんは、

  • かり引数ひきすう addend1対応たいおうするじつ引数ひきすう 123
  • かり引数ひきすう addend2対応たいおうするじつ引数ひきすう 456

2つを関数かんすう sumわたしている[3]

評価ひょうか戦略せんりゃく

[編集へんしゅう]

わた

[編集へんしゅう]

わた(あたいわたし、call by value)は右辺うへんわた方法ほうほうで、じつ引数ひきすうとして変数へんすうわたしたとしても、そののみがわたされる。もちろん即値そくち複雑ふくざつしきわたすこともでき、しき評価ひょうか結果けっかわたされる。その仕組しくみとしては、独立どくりつしたあらたな変数へんすう関数かんすうない用意よういされ、もとがコピーされる。そのため変数へんすうわたしたとしても、もと変数へんすう変更へんこうされるということはない。

これは「関数かんすう副作用ふくさようたない」という観点かんてんから、計算けいさん中心ちゅうしんとする言語げんごではのぞましい動作どうさといえる。またそもそも代入だいにゅう概念がいねんのない関数かんすうがた言語げんごでは、引数ひきすうかならわたされるとかんがえられる(ただし、代入だいにゅう存在そんざいしない以上いじょうコピーをとる必要ひつようもない)。

わたしを採用さいようした言語げんごとしてはC言語げんごMLAPLSchemeJavaひとしげられる。

ポインタわた

[編集へんしゅう]

アドレスわた(call-by-adress)ともぶ。 C言語げんごC++ポインタ保持ほじするはオブジェクトにたいする参照さんしょうメモリアドレス)であり、後述こうじゅつ参照さんしょうわた参照さんしょう性質せいしつつ。このため、ポインタ変数へんすうわたしすると、わたしでありながら参照さんしょうわたしとたような効果こうかることができる。このため、ポインタ(=メモリアドレス)をわたしすることたんなるわたしと区別くべつしてぞくポインタわたなどとこともある。

名前なまえわた

[編集へんしゅう]

ALGOL採用さいようされていた特徴とくちょうてき機能きのうひとつである。名前なまえわたしではでも参照さんしょうでもなく、しきがそのままわたされる。基本きほんてきには参照さんしょうわたしのようにうが、しき参照さんしょうするごとに計算けいさんしてこと特徴とくちょうである。C言語げんごのプリプロセッサのマクロ展開てんかいているが、引数ひきすうと、ローカル変数へんすう衝突しょうとつしないように配慮はいりょはされる。 つぎのようなれい名前なまえわたしに特徴とくちょうてき動作どうさわれる。

swap(x,y) {
 tmp = x;
 x = y;
 y = tmp;
}

このれいたいし、x=i, y=a[i]という"しき"をわたすとする。かりi=2だったとすると、

tmp = x;
x=i=2 なのでtmp2になる。
x = y;
xiわたされているのでiyになる。ya[i]だから、iaの2番目ばんめになる。
y = tmp;
yaiばんだが、ぜん手順てじゅんによりia[2]になっている。したがってy=a[a[2]]になる。

このような複雑ふくざつさもあって、ALGOL以外いがい名前なまえわたしが採用さいようされた事例じれいはほとんどない[4]

変数へんすうわた

[編集へんしゅう]

変数へんすうわた(へんすうわたし、call by variable)は、変数へんすうそのもの(左辺さへん)をわた方法ほうほうで、この場合ばあいかり引数ひきすうたいする操作そうさがそのままじつ引数ひきすうわたされた変数へんすう)に影響えいきょうする。 おおくの言語げんごでは(とくに配列はいれつのようなデータ構造こうぞうもどにできない場合ばあいもどはひとつのだけしかかえせないが、データベース検索けんさくなどでつかったかどうかと、つかったならそのらせるような場合ばあいに、つかったかどうかをもどにして、検索けんさく結果けっか適当てきとう引数ひきすう変更へんこうするといった使つかかたができる。

参照さんしょうわた(さんしょうわたし、call by reference)はその実装じっそう手段しゅだんひとつ(とることもできる[5])。変数へんすうたいする参照さんしょう(アドレス情報じょうほう)をわた方法ほうほうである(これは言語げんごがわ勝手かっておこなう。C言語げんごのように明示めいじてきにアドレス演算えんざん使つかうものは参照さんしょうわたしとはばない)。

そのわたしとおなじようにコピーをわたしておいて、関数かんすう/サブルーチンからのリターンもと変数へんすう変更へんこう結果けっかをコピーしなおす方法ほうほうもある(これは変数へんすう共有きょうゆう(エイリアス)や再帰さいき呼出よびだしがあると奇妙きみょう結果けっかになることがある)。PL/Iでは、どちらの方法ほうほう実装じっそうしてもいと規定きていされている。

原始げんしてき言語げんごであるFORTRAN機械きかいのアドレス操作そうさ反映はんえいした参照さんしょうわたししかたなかった。これはとくにcall by indexとばれている。

変数へんすうわたしをサポートする言語げんごとしては、PascalPerlC++C#Quick BASICひとし構造こうぞうBASICなどがげられる。

なお変数へんすうわたしの関数かんすう・サブルーチンに、じつ引数ひきすうとして変数へんすう以外いがい右辺うへん)をわたした場合ばあいにどうなるかは、言語げんごによってことなる。そのような操作そうさ禁止きんしされており、エラーが発生はっせいする言語げんご(Pascalとう)、テンポラリな変数へんすう作成さくせいし、リターンにそれをててしまうため、わたしとおなじことができる言語げんご(Quick BASICとう)、「未定義みていぎ動作どうさ」をひきおこし、なにこるかまった予測よそくがつかない言語げんご(FORTRANとう)がある。C++ではconst修飾しゅうしょくされていないかたへの参照さんしょう右辺うへんわたすとエラーになるが、const修飾しゅうしょくされていれば一時いちじオブジェクトが作成さくせいされ、また右辺うへんのみを参照さんしょうできる「右辺うへん参照さんしょう」が存在そんざいする。

わたしによる引数ひきすう変更へんこう

[編集へんしゅう]

C言語げんごわたしのみをサポートするが、変数へんすうのポインタ(メモリアドレス)を取得しゅとくすることが可能かのうであるため、変数へんすうへのポインタをわたこともと変数へんすう変更へんこうできる。オフセット計算けいさんにより配列はいれつ構造こうぞうたい一部分いちぶぶん参照さんしょうするコードも容易ようい記述きじゅつできる。

しかしこれは、実際じっさい変数へんすう領域りょういき逸脱いつだつした部分ぶぶんをも参照さんしょうできるので、あくまでもわたしによる参照さんしょうわたしのエミュレートである。参照さんしょうわたしをサポートする言語げんごでも内部ないぶてきには同様どうよう操作そうさおこなっているが、それはなんらかの意味いみ言語げんご保護ほごにある参照さんしょうとなる。

参照さんしょうわた

[編集へんしゅう]

参照さんしょうわたしでうところの「参照さんしょう」とばれているものと、特定とくてい言語げんごで「参照さんしょう」とばれているものがかならずしもおなじでないことには注意ちゅうい必要ひつようたとえば、Java参照さんしょうがたあつかうための『Javaの「参照さんしょう」』をつが、これはPascalとうのポインタ相当そうとうで、『参照さんしょうわたしの「参照さんしょう」』とは概念がいねんちがうため、『Javaの「参照さんしょう」』をわたしても参照さんしょうわたしであるとはえない。C言語げんごの「ポインタのわたし」とおなじである[6] 。これは、Javaの参照さんしょうがた参照さんしょうがたと、JavaのプリミティブがたちかがたC#ると理解りかいしやすいだろう。C#では、とく指定していしなければ参照さんしょうがたがたわたしされるが、引数ひきすうref もしくは out使用しようすることによって参照さんしょうわたしにすることができる。『C#のがた』をわたすからわたし、『C#の参照さんしょうがた』をわたすから参照さんしょうわたしとはならない。

れい:Pascalの変数へんすうわた

[編集へんしゅう]

Pascalの手続てつづ(procedure)や関数かんすう(function)では、原始げんしがた(integer, realなど) のわたしと変数へんすうわたしのどちらでもおこなえる。変数へんすうわたしの場合ばあい手続てつづき・関数かんすう引数ひきすうvarける。

{ 手続てつづき swap ないで a,b のえる。
  sampleの i,j は変数へんすうわたしされ、aとi、bとjはおなじアドレスをして
  いるので、i,jのわる。 }

procedure swap(var a,b:integer);  { var をつけると変数へんすうわたし }
  var tmp:integer;
  begin
    tmp := a; a := b; b := tmp
  end;

procedure sample();
  var i, j:integer;
  begin
    i := 5;
    j := 10;
    swap(i, j);
    ... { iは10, jは5になる }
  end;

遅延ちえん評価ひょうか

[編集へんしゅう]

Haskellなどの遅延ちえん評価ひょうかがた関数かんすう言語げんごられる形態けいたいで、実際じっさい必要ひつようになるまで計算けいさんおこなわない方法ほうほう概念がいねんじょうは、計算けいさん方法ほうほう遅延ちえんしたthunkばれるオブジェクトがわたっているとかんがえられる。

脚注きゃくちゅう

[編集へんしゅう]
  1. ^ KAKASI (Kanji Kana Simple inversion program) MIT
  2. ^ Javascript練習れんしゅう 09 京都産業大学きょうとさんぎょうだいがく
  3. ^ ちなみに、うえぶん結果けっかは 579 である
  4. ^ とはいえ中島なかじま秀之ひでゆきによれば、DEC 10 Prolog移植いしょくさいして、「修羅場しゅらばた」とべている。
  5. ^ 変数へんすう以外いがいから任意にんいしきたいして、その左辺さへんというものはかんがえづらいため。あたかも名前なまえのない変数へんすうがテンポラリにつくられるかのように振舞ふるまうものもある。
  6. ^ JavaHouse-Brewers の議論ぎろん

関連かんれん項目こうもく

[編集へんしゅう]