Gawk:配列を関数に渡す

Gawk:配列を関数に渡す

私はGNU awk 3.1.6に固執し、配列のバグが修正されたと思いましたが、まだ600行のawkプログラムに範囲の問題のように見えます。私のエラーを見つけるには、awkの配列範囲の理解を確認する必要があります。

この例示的なawkコードが与えられたら...

function foo(ga) {
  ga[1] = "global result"
}

garray[1] = "global"
foo(garray)

print garray[1]

印刷します...

global result

配列は常に参照として関数に渡されるので、すべての配列は常にグローバル配列です。ローカル配列を作成できません。そうですか?これを明確に説明する文書が見つかりません。

私はデバッグしており、3.1.6自体にもこの領域のバグが知られているので、awkのエラーがどこで始まり、私のエラーがどこで始まるかを確認しようとしています。

追加: ga[] が関数内で動作するのはなぜですか?

まず、関数に配列を渡すことはfoo(ga)実際には必要ありません。garray[]関数内からアクセスできます。ただし、これは顕著なパフォーマンス低下を引き起こさず、デバッグやエラーの報告に役立ちます。

を使用する場合は、foo(ga)グローバルga[]配列と同義語ですgarray[]。これはローカルコピーではなくへgarray[]のポインタですgarray[]。シンボリックリンクがファイルへのポインタであるかのように、複数の名前を使用して同じファイル(または配列)にアクセスできます。

追加: Glenn Jackmanの回答の説明

配列を作成するとき外部関数は関数に対してグローバルであり、関数に渡したり参照したりできます。配列が作成されます。~へ関数は関数に対してローカルに保持され、関数の外側には表示されません。 Mr. Jackmanの例を修正すると、これがわかります。

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: 
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: 

我々は単にx[]配列(実際にはそれへのポインタ)をに渡すことに注意してくださいbar()y[]配列は関数を入力する前に存在しません。

ただし、関数の外部で何も割り当てずにパラメータリストy[]に含めて宣言すると、呼び出し後に表示されます。bar()bar(x,y)

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x,y)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: 
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello

最後に、y[]関数の外部から配列を作成してに渡すと、bar(x,y)関数split()内の割り当てが配列の要素を置き換えます。

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      y[1]="howdy"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x,y)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: howdy
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello

ベストアンサー1

関数パラメータは関数のローカルパラメータです。

awk '
    function foo(x,y) {y=x*x; print "y in function: "y} 
    BEGIN {foo(2); print "y out of function: " y}
'
y in function: 4
y out of function: 

引数より少ない値が関数に渡されると、追加の引数は空になります。時には、次のように定義された関数を見ることもできます。

function foo(a, b, c            d, e, f) {...

スペースの後のパラメータはローカル変数であり、呼び出し時に値を取得することを意図していません。

これがローカル配列で機能しない理由はありません。

awk '
    function bar(x) {
        split("hello world", x)
        print "in: " x[1]
    }
    BEGIN {
        x[1]="world"
        bar()
        print "out: " x[1]}
'
in: hello
out: world

おすすめ記事