実は AWK 自体は、 ユーザ定義関数の引数部に書かれたものはすべて引数 (仮引数) と認識していますが、 AWK の関数は実行時に引数の省略が可能なので、 実際に値が与えられたものだけに代入、 すなわち関数実行時の引数の初期化が行なわれています。
例で説明します。
function f1(a,b,c,d,e,f) { ... }というユーザ定義関数を、
f1(1,2)
と使えば、
a=1, b=2 が代入されますが、
c,d,e,f は初期化されませんから、
暗黙の初期化、すなわち、c="", d="", e="", f=""
(数字として使う場合はいずれも 0) が行われているものと見なされます。
しかし、あくまで仮引数なので、 これらの変数はこの中だけで通用する変数です (これは C 言語と同じです)。 つまり、この関数の外 (例えば実行ブロック) で a,b,c などの変数が使われていても、 それはこの関数の引数の a,b,c とは無関係なものと見なされます。 例えば、
BEGIN{ a=1; b=3; f1() printf "a=%d, b=%d\n",a,b } function f1(a,b){ a=5; b=10 }を実行すると、表示されるのは ``a=1, b=3'' です。
AWK では、変数宣言がないので局所変数の定義ができないのですが、 その代わりに仮引数を局所変数として使っているわけです。
なお、本当に引数を省略する関数 (デフォルトで値を設定する関数) を作りたい場合は、このような状況を利用して、次のようにします。
function f1(a,b,c) { if(a=="") a=1 # a のデフォルトの値 if(b=="") b=2 # b のデフォルトの値 if(c=="") c=3 # c のデフォルトの値 return a+b+c }このようにしておけば、
f1()=6 (=1+2+3), f1(5)=10 (=5+2+3), f1(5,6)=14 (=5+6+3)のようになります。
一方、仮引数に書かれていない変数が使われたときは、それは外部変数 (大域変数) と見なされます。例えば
BEGIN{ a=1; b=3; f1() printf "a=%d, b=%d\n",a,b } function f1(a){ a=5; b=10 }を実行すると、表示されるのは ``a=1, b=10'' となります。 f1() では b は仮引数としては書かれていないので、 BEGIN{} ブロックで使われている変数 b だと思われて、 その値が変更されます。
外部変数 (大域変数)、局所変数は C 言語でもでてくる重要な考え方です。 しっかり把握しておきましょう。