gawk関数パラメータの使い方を理解できません。通常、パラメーターは関数のローカル変数を定義します。
しかし、パラメータを関数が使用できる入力として使用できますか?
使い方を見た後、return
実際に呼び出して値を返します。
val=myfunc()
グローバル変数に引き続きアクセスできる場合は、グローバル値を入力パラメータとして関数に渡すことにどのような利点がありますか?
答え1
あなたの質問は間違った前提に基づいています。
通常、パラメーターは関数のローカル変数を定義します。
習慣。通常、引数は関数に渡される値の変数名を定義します。
awk
地域的にスコープ変数を宣言する機能はありません。ただし、すべての関数パラメータはオプションであるため、関数内でローカルに使用されることに加えて、他の目的のない変数で関数パラメータのリストをオーバーロードすることは許容される慣行と見なされます。
したがって、あなたの質問に対する答えは「はい」です。変数を使用して値を関数に渡すことができます。
例えば、
awk '
function factorial(n) { return n>1 ? n*factorial(n-1) : 1 }
BEGIN { print factorial(5) }
'
ここで、関数は毎回異なる値(最初の5つ、その後は値4、3、2の減少)で自分自身を呼び出します。このためにグローバル変数を使用することは非常に難しいでしょう。
答え2
また、関数のスカラー引数は値として渡されますが、配列引数は参照として渡されます。したがって、関数は呼び出しコードで宣言された配列値を関数に変更して複数の値を返すことができます。
これには、最初に空の配列に渡された場合でも、配列パラメータに新しい要素を生成する機能が含まれます。
2つの数値を受け入れる関数が必要で、2つの変数値(1つは合計を含み、もう1つは平均を含む)を出力したいとします。何ができますか?
これを行うことができます。同じ名前の配列に対してグローバルとローカルの範囲があり、長さが異なる可能性があり、データが異なる可能性があり、配列が参照に渡され、複数の値を返す可能性があることを証明します。
#! /bin/bash
Awk='
#.. Define and fill an array X at global scope.
BEGIN { X[1] = 45; X[2] = 98; }
#.. Function that fills in a result array (passed by reference).
function Math (X, v1, v2) {
X[1] = v1 + v2; X[2] = (v1 + v2) / 2; X[3] = v1 * v2;
}
#.. Function that declares an array X at local scope, and reports it.
function Wrapper (a, b, X, j) {
Math( X, a, b);
for (j = 1; j in X; ++j) printf ("Local X[%d] is %f\n", j, X[j]);
}
{
Wrapper( $1, $2);
#.. Prove that the Global X is unaffected, in length or content.
for (j = 1; j in X; ++j) printf ("Global X[%d] is %f\n", j, X[j]);
}
'
echo 3.5 2.7 | awk "${Awk}"
$ ./Heime.awk
Local X[1] is 6.200000
Local X[2] is 3.100000
Local X[3] is 9.450000
Global X[1] is 45.000000
Global X[2] is 98.000000
GNU Awkはうまく動作します。 Xに初めてアクセスするときにXの種類を決定します。nawk
(Solaris Awk)この決定は渡されたときに行われます(そしてSegViolを引き起こす可能性があります)。
Xが参照として関数に渡されるようにするには、nawk
Xを渡す前に長さ0のパターンを使用して長さ0の文字列を分割し、明示的に長さ0の配列にする必要があります。
split ("", X, ""); Math( X, a, b);
答え3
グローバル変数に引き続きアクセスできる場合は、グローバル値を入力パラメータとして関数に渡すことにどのような利点がありますか?
すべてのプログラミング言語のすべての関数と同じです。毎回異なる(グローバル)変数を渡すことができ、関数はタスクを実行するために必要ではないものを知る必要はありません。
簡単な例を見てください:
function sum(a,b) { return a+b; }
{ partial = sum($2, $3); }
$1 == 0 { print sum(partial, $4); }
$1 != 0 { print sum(partial, $5); }
代わりに、より複雑な関数を想像してみてくださいsum()
。その後、両方の分岐で関数を複製することはもはや意味がありません。