44_関数パラメータの秘密(上)

1562 ワード

1.関数パラメータ

  • 関数パラメータは、本質的に局所変数と同じスタック上に空間を割り当てる.
  • 関数パラメータの初期値は、関数呼び出し時の実パラメータ値
  • である.
  • 関数パラメータの評価順序は、次の面接問題のようなコンパイラの実装に依存する.
  • //  
    #include 
    
    int func(int i, int j)
    {
        printf("i = %d, j = %d
    ", i, j); return 0; } int main() { int k = 1; func(k++, k++); printf("k = %d
    ", k); return 0; }

    出力結果:
    i = 2, j = 1
    k = 3
    

    まとめ:C言語では,関数の評価順序はコンパイラに依存し,左から右への評価順序が規則的ではない.上のプログラムではfunc(k++,k++);まず2番目のk++を求め,次に1番目のk++を求めた.この結論はC言語のオペレータも用いられ,オペレータの評価順序もコンパイラに依存する.

    2.プログラム中の順序点

  • プログラムには一定の順序点
  • が存在する.
  • シーケンスポイントとは、実行中に変数値を変更する最終時刻
  • を指す.
  • プログラムがシーケンスポイントに到達するとき、前に行ったすべての操作は
  • を完了しなければならない.
  • C言語のシーケンスポイント(1)各完全式が終了すると、セミコロン(2)&,|,?:,およびカンマ式の各パラメータ計算後(3)関数呼び出し時のすべての実パラメトリック評価完了後(関数体に入る前)プログラム説明:C言語のシーケンスポイント
  • //  k ?
    #include 
    
    int main()
    {
        int k = 2;
    
        k = k++ + k++;
    
        printf("k = %d
    ", k); return 0; }

    出力結果:
     ubuntu10 :k = 6
     ubuntu14 : k = 5
    

    まとめ:プログラムの実行中には、必ず1つの時点が存在します.この時点までに、すべてのメモリ操作が完了する必要があります.コード内:k=k++k++2つのk++と1つの加算の3つの操作は、kが表すメモリの値を変更し、コードの順序点は「;」、ubuntu 10では、まず加算を行い、その左右の操作数はいずれもkであり、kの自己加算を吊り下げ、加算が終了した後、2つの自己加算を完了するので、結果は6となる.ubuntu 14では,まず2つの自己加算を行い,最後に加算を行うので結果は5である.

    3まとめ

  • 関数のパラメータはスタックに空間を割り当て、本質は局所変数と同じである.
  • 関数の実パラメータは固定的な計算順序を持たず、コンパイラの実現に依存する.
  • シーケンスポイントは、C言語における変数修正の最も遅いタイミングである.