パラメータ(コンピュータプログラミング)

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

コンピュータプログラミングではパラメータまたは 仮引数は、サブルーチンへの入力として提供されるデータの1つを参照するためにサブルーチンで使用される特殊な種類の変数です。[a] [1]これらのデータは、サブルーチンが呼び出される/呼び出される引数(多くの場合、実際の引数または実際のパラメーターと呼ばれる)の値[2] [3] [4]です。パラメータの順序付きリストは通常​​、サブルーチンの定義に含まれています、そのため、サブルーチンが呼び出されるたびに、その呼び出しの引数が評価され、結果の値を対応するパラメーターに割り当てることができます。

通常の数学的使用法の引数とは異なり、コンピュータサイエンスの引数は、呼び出し/呼び出しステートメントの関数、プロシージャ、またはルーチンに渡される/供給される実際の入力式ですが、パラメータはサブルーチンの実装内の変数です。たとえば、addサブルーチンをdef add(x, y): return x + y、と定義すると、x, yはパラメータになり、これがと呼ばれるとadd(2, 3)2, 3は引数になります。呼び出し元のコンテキストからの変数(およびその式)は引数になる可能性があることに注意してください。サブルーチンがとして呼び出されたa = 2; b = 3; add(a, b)場合、変数 a, bは引数であり、 2, 3ではありません。パラメータと引数を参照してください詳細については、セクションを参照してください。

パラメータを宣言する方法と、引数(の値)をサブルーチンのパラメータに渡す方法のセマンティクスは、言語の評価戦略によって定義されます。これが特定のコンピュータシステムでどのように表されるかの詳細は、呼び出し規約によって異なります。そのシステムの規約。最も一般的なケースでは、値による呼び出し、パラメーターは、引数の値(引数が変数の場合は引数のローカル(分離)コピー)に初期化された新しいローカル変数としてサブルーチン内で機能しますが、それ以外の場合はたとえば、参照による呼び出しの場合、呼び出し元によって提供される引数変数は、呼び出されたサブルーチン内のアクションの影響を受ける可能性があります。

次のCプログラミング言語のプログラムは、「SalesTax」という名前の関数を定義し、「price」という名前のパラメーターを1つ持っています。価格のタイプは「倍精度」(つまり、倍精度浮動小数点数)です。関数の戻り型もdoubleです。

ダブルSalesTax ダブル価格  
{{
  0.05 *価格を返します;   
}

関数を定義した後、次のように呼び出すことができます。

消費税10.00 );

この例では、関数は引数10.00で呼び出されています。これが発生すると、10.00が価格に割り当てられ、関数はその結果の計算を開始します。結果を生成する手順は、{}で囲まれて以下に指定されています。0.05 * price最初に行うことは、0.05に価格の値を掛けて0.50を与えることを示します。return関数がの結果を生成することを意味します0.05 * priceしたがって、最終結果(10進数の小数部を2進数の小数部として表すときに発生する可能性のある丸め誤差を無視)は0.50です。

パラメータと引数

パラメータ引数という用語は、プログラミング言語によって意味が異なる場合があります。時々それらは交換可能に使用され、文脈は意味を区別するために使用されます。パラメータ(仮パラメータと呼ばれることもあります)という用語は、関数定義にある変数を指すためによく使用されますが、引数(実際のパラメータと呼ばれることもあります)は、関数呼び出しで提供される実際の入力を指します。たとえば、関数をとして定義する場合、はパラメータであり、def f(x): ...それxによって呼び出されるa = ...; f(a)場合aは引数です。パラメータは(バインドされていない)変数ですが、引数はリテラルにすることができますまたは、リテラルまたは変数を含む変数またはより複雑な式。値による呼び出しの場合、関数に渡されるのは引数の値です(たとえば、f(2)同等a = 2; f(a)の呼び出しです)。参照による呼び出しでは、変数を引数として、渡されるのはその変数への参照です。関数呼び出しの構文は同じままである可​​能性がありますが。[5]参照渡しまたは値渡しの指定は、関数宣言および/または定義で行われます。

パラメータはプロシージャ定義に表示されます。引数はプロシージャ呼び出しに表示されます。関数定義f(x) = x*xでは、変数xはパラメーターです。関数呼び出しf(2)では、値2は関数の引数です。大まかに言うと、パラメータは型であり、引数はインスタンスです。

パラメータは、プロシージャの固有のプロパティであり、その定義に含まれています。たとえば、多くの言語では、提供された2つの整数を足し合わせて合計を計算する手順では、整数ごとに1つずつ、合計2つのパラメーターが必要になります。一般に、プロシージャは、任意の数のパラメータを使用して定義することも、パラメータをまったく使用せずに定義することもできます。プロシージャにパラメータがある場合、パラメータを指定する定義の部分は、パラメータリストと呼ばれます。

対照的に、引数は、プロシージャが呼び出されたときにプロシージャに提供される式[6]であり、通常、1つの式がパラメータの1つに一致します。プロシージャの定義の不変の部分を形成するパラメータとは異なり、引数は呼び出しごとに異なる場合があります。プロシージャが呼び出されるたびに、引数を指定するプロシージャ呼び出しの部分は、引数リストと呼ばれます。

パラメータは一般に引数とも呼ばれますが、引数は、サブルーチンが実行時に呼び出されたときにパラメータ変数に割り当てられた実際の値または参照と見なされる場合があります。サブルーチンを呼び出すコードについて説明する場合、サブルーチンに渡される値または参照はすべて引数であり、これらの値または参照が指定されるコード内の場所はパラメーターリストです。サブルーチン定義内のコードについて説明する場合、サブルーチンのパラメーターリスト内の変数はパラメーターであり、実行時のパラメーターの値は引数です。たとえば、Cでは、スレッドを処理するときに、void *型の引数を渡して、期待される型にキャストするのが一般的です。

void ThreadFunction void * pThreadArgument   
{{
  //'pThreadParameter'ではなく、//最初のパラメータ'pThreadArgument'の名前が正しい
実行時に使用する値は引数です。//上記のように、サブルーチン定義を議論するときのために//パラメータという用語を予約します。}  
  
  

違いをよりよく理解するために、Cで書かれた次の関数を考えてみましょう。

int Sum int addend1 int addend2     
{{
  addend1 + addend2を返す;   
}

関数Sumには、 addend1addend2という名前の2つのパラメーターがありますパラメータに渡された値を追加し、その結果をサブルーチンの呼び出し元に返します(Cコンパイラによって自動的に提供される手法を使用)。

Sum関数を呼び出すコードは次のようになります。

int value1 = 40 ;   
int value2 = 2 ;   
int sum_value = Sum value1 value2 );    

変数value1value2は値で初期化されます。value1value2はどちらも、このコンテキストで はsum関数の引数です。

実行時に、これらの変数に割り当てられた値は、引数として関数Sumに渡されます。Sum関数では、パラメーターaddend1addend2評価され、それぞれ引数40と2が生成されます。引数の値が追加され、結果が呼び出し元に返され、そこで変数sum_valueに割り当てられます。

パラメータと引数の違いにより、プロシージャに不適切な引数を指定する可能性があります。呼び出しは、引数が多すぎたり少なすぎたりする可能性があります。1つ以上の引数が間違ったタイプである可能性があります。または、引数が間違った順序で指定されている可能性があります。これらの状況のいずれかにより、パラメータリストと引数リストの間に不一致が発生し、プロシージャが意図しない回答を返したり、ランタイムエラーを生成したりすることがよくあります。

エッフェルの代替規則

Eiffelソフトウェア開発の方法と言語の中で、引数パラメーターという用語には、慣例によって確立された明確な使用法があります。引数という用語は、ルーチンの入力を参照する場合にのみ使用され[7] 、パラメーターという用語は、ジェネリッククラスの型パラメーター化でのみ使用されます[8]

次のルーチン定義を検討してください。

    sum  addend1  INTEGER ;  addend2  INTEGER ): INTEGER 
        do 
            Result  :=  addend1  +  addend2 
        end

ルーチンsumは2つの引数addend1とを取ります。addend2これらはルーチンの仮引数と呼ばれます。との呼び出しは、以下に示すように、実際の引数sumを指定しますvalue1value2

    sum_value  INTEGER 
    value1  INTEGER  =  40 
    value2  INTEGER  =  2 
                
            sum_value  :=  sum  value1  value2 

パラメータは、正式または実際のいずれかと見なされます。正式なジェネリックパラメーターは、ジェネリッククラスの定義で使用されます。以下の例では、クラスは、対象のデータとデータのハッシュキーを表す 2HASH_TABLE つの正式なジェネリックパラメーターを持つジェネリッククラスとして宣言されています。GK

クラス HASH_TABLE  [ G  K-  >  HASHABLE ]  
            

クラスがのクライアントになると、正式なジェネリックパラメーターはジェネリック派生の実際のジェネリックパラメーターHASH_TABLE置き換えられます次の属性宣言では、は文字列ベースの辞書として使用されます。そのため、データとキーの正式なジェネリックパラメーターの両方が、タイプの実際のジェネリックパラメーターに置き換えられますmy_dictionarySTRING

    my_dictionary  HASH_TABLE  [ STRING  STRING ]

データ型

強く型付けされたプログラミング言語では、各パラメーターのをプロシージャー宣言で指定する必要があります。型推論を使用する言語は、関数の本体と使用法から型を自動的に検出しようとします。動的に型付けされたプログラミング言語は、実行時まで型の解決を延期します。弱く型付けされた言語は、型の解決をほとんどまたはまったく実行せず、代わりにプログラマーに正確さを依存します。

一部の言語では、サブルーチンにパラメーターがないことを示すために特別なキーワード(voidなど)を使用します。正式な型理論では、そのような関数は空のパラメーターリストを取ります(その型はvoidではなく、unitです)。

引数の受け渡し

引数の受け渡しと呼ばれる、パラメーターに引数を割り当てるための正確なメカニズムは、そのパラメーターに使用される評価戦略(通常は値によって呼び出される)に依存します。これは、キーワードを使用して指定できます。

デフォルトの引数

AdaC ++Clojure[引用が必要] Common Lisp[9] Fortran 90[10] PythonRubyTclWindowsPowerShell [引用が必要]などの一部のプログラミング言語ではデフォルトの引数が許可されていますサブルーチンの宣言で明示的または暗黙的に指定されます。これにより、呼び出し元はサブルーチンを呼び出すときにその引数を省略できます。デフォルトの引数が明示的に指定されている場合、呼び出し元から指定されていない場合はその値が使用されます。デフォルトの引数が暗黙的である場合(オプションなどのキーワードを使用する場合もあります)、値が呼び出し元から提供されない場合、言語は既知の値(nullEmpty、zero、空の文字列など)を提供します。 。

PowerShellの例:

function  doc $ g  =  1 .21 { " $ gギガワット?$ gギガワット?グレートスコット!" } 
    

PS> doc 
1.21ギガワット?1.21ギガワット?グレートスコット!

PS> doc  88 
88ギガワット?88ギガワット?グレートスコット!

デフォルトの引数は、可変長引数リストの特殊なケースと見なすことができます。

可変長パラメータリスト

一部の言語では、可変数の引数を受け入れるようにサブルーチンを定義できますこのような言語の場合、サブルーチンは引数のリストを反復処理する必要があります。

PowerShellの例:

関数 marty  { 
    $args  |  foreach  {  "今年に戻る$_"  } 
}
PS>マーティ19851985 
に戻る

PS>マーティ201519851955年に戻る 2015年に戻る 1985年 に戻る1955年
戻る


名前付きパラメータ

AdaWindowsPowerShellなどの一部のプログラミング言語では、サブルーチンに名前付きパラメーターを設定できます。これにより、呼び出し元のコードをより自己文書化することができます。また、呼び出し元に柔軟性を提供し、多くの場合、引数の順序を変更したり、必要に応じて引数を省略したりできます。

PowerShellの例:

function  jennifer $ adjectiveYoung  $ adsjectiveOld  { 
    "若いジェニファー:私は$ adjectiveYoungです!" 
    「オールドジェニファー:私は$ adsjectiveOldです!」
}
PS>ジェニファー '新鮮'  '経験者'
若いジェニファー:私は新鮮です!
Old Jennifer:経験豊富です!

PS> jennifer  -adjectiveOld'experienced  '  -adjectiveYoung'fresh  ' 
Young Jennifer:私は新鮮です!
Old Jennifer:経験豊富です!

関数型言語の複数のパラメーター

ラムダ計算では、各関数には1つのパラメーターがあります。複数のパラメーターを持つ関数として考えられるものは、通常、ラムダ計算では最初の引数を取る関数として表され、残りの引数を取る関数を返します。これはカリー化として知られている変換です。MLHaskellなどの一部のプログラミング言語は、このスキームに従います。これらの言語では、すべての関数に1つのパラメーターがあり、複数のパラメーターの関数の定義のように見えるものは、実際には、関数などを返す関数の定義の構文糖衣です。関数アプリケーション左連想です。これらの言語とラムダ計算では、複数の引数への関数の適用のように見えるものは、最初の引数に適用された関数として正しく評価され、次に結果の関数が2番目の引数に適用されます。

出力パラメータ

出力パラメーターは、出力パラメーターまたは戻りパラメーターとも呼ばれ、通常の入力の使用ではなく、出力に使用されるパラメーターです。一部の言語、特にCおよびC ++では出力パラメーターがイディオムであるため、参照パラメーターによる呼び出し、または値が参照である値パラメーターによる呼び出しを使用します[b]が、他の言語には出力パラメーターのサポートが組み込まれています。出力パラメーターのサポートが組み込まれている言語には、Ada [11]Adaサブプログラムを参照)、FortranFortran 90以降、 Fortranの「インテント」を参照)、PL / SQLなどのSQL PL / SQL関数を参照)[12]およびTransact-SQLC#[13]および.NET Framework[14] Swift[15]およびスクリプト言語TScriptTScript関数宣言を参照) )。

より正確には、3つのタイプのパラメータまたはパラメータモードを区別できます。入力パラメータs出力パラメータ、および入出力パラメータs; これらは、、、、およびまたはで示されることがinよくoutありin outますinout入力引数(入力パラメーターへの引数)は、初期化された変数やリテラルなどの値である必要があり、再定義したり、割り当てたりすることはできません。出力引数は割り当て可能な変数である必要がありますが、初期化する必要はなく、既存の値にアクセスできず、値を割り当てる必要があります。また、入出力引数は初期化された割り当て可能な変数である必要があり、オプションで値を割り当てることができます。正確な要件と適用は言語によって異なります。たとえば、Ada 83出力パラメータは割り当て後でも読み取ることはできず、割り当てることができます(これは、Ada 95補助アキュムレータ変数の必要性を取り除くため)。これらは、式のがr値(値を持つ)、l値(割り当てることができる)、またはr値/ l値(値があり、割り当てることができる)であるという概念に類似しています。 )、ただし、これらの用語はCでは特殊な意味を持っています。

場合によっては、入力と入力/出力のみが区別され、出力は入力/出力の特定の使用と見なされます。また、入力と出力のみがサポートされる場合もあります(入力/出力はサポートされません)。デフォルトのモードは言語によって異なります。Fortran90では入出力がデフォルトですが、C#およびSQL拡張機能では入力がデフォルトであり、TScriptでは各パラメーターが入力または出力として明示的に指定されます。

void f(out int x)構文的には、パラメーターモードは通常、C#などの関数宣言でキーワードを使用して示されます。従来、出力パラメータは、パラメータリストの最後に配置されて明確に区別されることがよくありますが、これが常に守られているわけではありません。TScriptは別のアプローチを使用します。このアプローチでは、関数宣言に入力パラメーターがリストされ、次に出力パラメーターがコロン(:)で区切られ、テキストのサイズを計算するこの関数のように、関数自体への戻り型がありません。断片:

TextExtent WStringテキストフォントフォント整数整数高さ        

パラメーターモードは、プログラマーの意図を示し、コンパイラーがエラーをキャッチして最適化を適用できるようにする表示的意味論の形式です。必ずしも操作的意味論(パラメーターの受け渡しが実際にどのように行われるか)を意味するわけではありません。特に、入力パラメーターは値による呼び出しで実装でき、出力および入出力パラメーターは参照による呼び出しで実装できますが、これは組み込みのサポートがない言語でこれらのモードを実装する簡単な方法ですが、必ずしもそうとは限りません。実装されました。この区別については、Ada '83 Rationaleで詳しく説明されています。この理論では、パラメーターモードが抽象化されており、パラメーター受け渡しメカニズム(参照またはコピーによる)が実際に実装されています。[11]たとえば、C#では入力パラメーター(デフォルト、キーワードなし)は値で渡され、出力および入出力パラメーター(outおよびref)は参照で渡されますが、PL / SQLでは入力パラメーター(IN)は参照で渡され、出力および入出力パラメーター(OUTおよび)は、デフォルトで値によって渡され、結果がコピーされますが、コンパイラー・ヒントIN OUTを使用して参照によって渡すことができます。[16]NOCOPY

出力パラメーターと構文的に類似した構造は、関数と同じ名前の変数に戻り値を割り当てることです。これは、次のPascalの例のように、 PascalFortran66およびFortran77にあります。

関数 f x  y  整数 整数; 
開始
    f  :=  x  +  y ; 
終了;

これは、呼び出されたときに関数が単純に評価されるという点で意味的に異なります。出力を格納するため に呼び出し元のスコープから変数が渡されることはありません。

を使用

出力パラメーターの主な用途は、関数から複数の値を返すことですが、入出力パラメーターの使用は、パラメーターの受け渡しを使用して状態を変更することです(グローバル変数のように共有環境ではありません)。複数の値を返す重要な使用法は、値とエラーステータスの両方を返すという半述語の問題を解決することです。「半述語の問題:複数値の戻り値」を参照してください。

たとえば、Cの関数から2つの変数を返すには、次のように記述します。

int 
intの高さ; 

F x 高さ);  

ここxで、は入力パラメーターでありwidthheightは出力パラメーターです。

Cおよび関連言語の一般的な使用例は、例外処理の場合です。この場合、関数は戻り値を出力変数に配置し、関数が成功したかどうかに対応するブール値を返します。典型的な例は、TryParse.NET、特にC#のメソッドです。これは、文字列を整数に解析し、true成功時とfalse失敗時に戻ります。これには次の署名があります:[17]

public  static  bool  TryParse string  s  out  int  result 

次のように使用できます。

int 結果; 
if  (!int32。TryParse s result { //例外処理}  
    

同様の考慮事項が、いくつかの可能なタイプの1つの値を返す場合にも当てはまります。ここで、戻り値はタイプを指定でき、値はいくつかの出力変数の1つに格納されます。

欠点

最近のプログラミングでは、出力パラメータは、本質的に扱いにくく、混乱し、低レベルであるため、推奨されないことがよくあります。一般的な戻り値は、理解と操作が非常に簡単です。[18]特に、出力パラメーターには副作用のある関数(出力パラメーターの変更)が含まれ、純粋関数や値よりも混乱する参照と意味的に類似しており、出力パラメーターと入出力パラメーターの区別は微妙な場合があります。さらに、一般的なプログラミングスタイルでは、ほとんどのパラメータは単に入力パラメータであるため、出力パラメータと入出力パラメータは異常であり、誤解されやすくなります。

出力は式の値ではなく変数に格納されるため、出力および入出力パラメーターは関数の合成を防ぎます。したがって、最初に変数を宣言する必要があり、次に関数のチェーンの各ステップが個別のステートメントである必要があります。たとえば、C ++では、次の関数合成が行われます。

オブジェクトobj = G y F x ));    

出力および入出力パラメーターを使用して記述した場合、代わりに次のようになります(F出力パラメーターの場合、入出力Gパラメーターの場合)。

オブジェクトobj ; 
F x obj ); 
G y obj ); 

単一の出力または入出力パラメーターがあり、戻り値がない関数の特殊なケースでは、出力または入出力パラメーター(またはC / C ++ではそのアドレス)も関数によって返される場合、関数の合成が可能です。この場合、上記は次のようになります。

オブジェクトobj ; 
G y F x obj ));  

代替案

出力パラメータのユースケースにはさまざまな選択肢があります。

関数から複数の値を返す場合の代替手段は、タプルを返すことです。構文的には、 GoやPythonのように、 自動シーケンスアンパックと並列割り当てを使用できる場合、これはより明確になります。

def  f ):
    return  1、2 a  b = 
f    

いくつかのタイプのいずれかの値を返すために、代わりにタグ付き共用体を使用できます。最も一般的なケースはnull許容型オプション型)であり、戻り値は失敗を示すためにnullになる可能性があります。例外処理の場合、null許容型を返すか、例外を発生させることができます。たとえば、Pythonでは次のいずれかが発生する可能性があります。

result  =  parse s 
if  result  is  None 
    #例外処理

または、より慣用的に:

try 
    result  =  parse s 
ただし 、ParseError 
    #例外処理

ローカル変数を必要とせず、出力変数を使用するときに戻り値をコピーするというマイクロ最適化は、十分に洗練されたコンパイラーによって従来の関数と戻り値に適用することもできます。

Cおよび関連言語での出力パラメーターの通常の代替手段は、すべての戻り値を含む単一のデータ構造を返すことです。[13]たとえば、幅と高さをカプセル化する構造が与えられた場合、次のように書くことができます。

WidthHeight width_and_height = F x );   

オブジェクト指向言語では、入出力パラメーターを使用する代わりに、変数が参照するオブジェクトを変更せずに、共有、オブジェクトへの参照の受け渡し、オブジェクトの変更によって呼び出しを使用できることがよくあります。[18]

も参照してください

メモ

  1. ^ この記事では、「サブルーチン」という用語は、議論されているプログラミング言語に応じて異なる名前とわずかに異なる意味を持つ、サブルーチンのような構造を指します
  2. ^ CおよびC++は値による呼び出しですが、typeが参照(C / C++ポインターまたはC++参照)の場合、参照の値を設定することで、参照による呼び出しスタイルの動作を生成できます。

参照

  1. ^ 「メソッドまたはコンストラクターへの情報の受け渡し(Java™チュートリアル> Java言語の学習>クラスとオブジェクト)」Oracle.com 2021-09-09を取得パラメータは、メソッド宣言内の変数のリストを参照します。引数は、メソッドが呼び出されたときに渡される実際の値です。メソッドを呼び出すとき、使用される引数は、型と順序で宣言のパラメーターと一致する必要があります。
  2. ^ プラータ、スティーブン(2004)。Cプライマープラス(第5版)。サムズ。p。276〜277。ISBN 978-0-672-32696-7
  3. ^ 「ワーキングドラフト、プログラミング言語C ++の標準」(PDF)www.open-std.org 2018年1月1日取得 [永久デッドリンク]
  4. ^ ゴードン、アーロン。「サブプログラムとパラメータの受け渡し」rowdysites.msudenver.edu/~gordona2018年1月1日にオリジナルからアーカイブされました2018年1月1日取得
  5. ^ ダラード、キャスリーン。「値と参照による引数の受け渡し(Visual Basic)」docs.microsoft.com 2018年10月27日取得
  6. ^ 「GNUCプログラミングチュートリアル」crasseux.com 2018年10月27日取得
  7. ^ マイヤー、バートランド。オブジェクト指向ソフトウェア構築、第2版、 Prentice Hall、1997年、444ページ。
  8. ^ マイヤー、p。96。
  9. ^ 「関数」gigamonkeys.com 2021-06-02を取得
  10. ^ 「オプションの引数」www.netlib.org 2021-06-02を取得
  11. ^ a b 8.2パラメータモード、「Ada®プログラミング言語の設計の理論的根拠
  12. ^ 8. PL / SQLサブプログラム:サブプログラムのパラメータ・モードの指定
  13. ^ ab ピーターハラム「C#に「ref」と「out」の両方があるのはなぜですか?」2011年9月26日にオリジナルからアーカイブされました
  14. ^ ParameterDirection列挙
  15. ^ 関数— Swiftプログラミング言語(Swift 4.2)
  16. ^ 8. PL / SQLサブプログラム:NOCOPYコンパイラのヒントを使用した大規模なデータ構造の受け渡し
  17. ^ Int32.TryParseメソッド(文字列、Int32)
  18. ^ a b CA1021:パラメータを回避する