7

重複の可能性:
C での関数呼び出し前のパラメーター評価順序

以下のコードでは、出力が 20 と 76 になると予想していましたが、代わりに 75 と 21 が出力されています。なぜそうなのか説明してください。

    #include<stdio.h>

    unsigned func(unsigned n)
    {

       unsigned int a =1 ;        
       static unsigned int b=2;        
       a+=b; b+=a;        
       {

         unsigned int a=3;        
         a+=b; b+=a;        
       }
       //printf("%d %d ",a,b);
       return (n+a+b);        
    }
    int main()
    {
        printf("%d %d\n",func(4),func(5));
        return 0;
    }
4

8 に答える 8

10

func(4)以前に呼び出されることを期待していますfunc(5)が、コンパイラでは逆のことが起こります。関数パラメータの評価の順序は、C標準では指定されていません。したがって、コンパイラは最初に呼び出す関数を自由に選択できます。そのため、同じコンパイラでそのように発生する可能性はほとんどありませんが、実行ごとに関数呼び出しの順序が異なる場合があります。

于 2012-10-25T07:22:21.297 に答える
3

func(4) と func(5) の評価の順序は、C 標準では定義されていません。

于 2012-10-25T07:20:05.120 に答える
2

unspecified behaviour したがってfunc(4)、表現の評価の順序はfunc(5)、あなたが想定したのとは異なる順序で呼び出される可能性があります。

あなたはもっとそれを訪問したいかもしれません

C++でのコンパイラと評価の引数の順序

Cで関数を呼び出す前のパラメーター評価順序

于 2012-10-25T07:20:47.743 に答える
1

引数は逆の順序でスタックにプッシュされます。あなたのコンパイラの実装でfunc(5)は、 before と呼ばれているようfunc(4)です。

于 2012-10-25T07:19:13.267 に答える
1

評価の順序が理由である可能性があります。なぜなら、

//printf("%d %d\n",func(4),func(5));
        printf("%d \n",func(4));
        printf("%d \n",func(5));

版画

20 
76
于 2012-10-25T07:23:23.240 に答える
0

func(5) が最初に実行されます:

func(5) を実行した後の変数の値:

a = 3
b = 13
func(5) = 21

b は static であるため、func(4) を実行した後の値:

a = 14
b = 57
func(4) = 75
于 2012-10-25T07:25:01.757 に答える
0

コードは単純で、static変数は関数呼び出し間で値を保持することを覚えておいてください。

あなたのプログラムでは、コンパイラが原因で(したがって、コンパイラ固有であり、標準では定義されていません):

func(5)が最初に実行されます: 21 を返します.. 説明:

    unsigned func(unsigned n) /*first with 5*/
    {

       unsigned int a =1 ;        
       static unsigned int b=2;        
       a+=b; b+=a;        // a = 3, b = 5
       {

         unsigned int a=3;        
         a+=b; b+=a;        // a = 8, b = 13
       }
       //printf("%d %d ",a,b);
       return (n+a+b);        // 5 + 3 + 13 = 21. 
    }

次に func(4) が実行され、

説明:

    unsigned func(unsigned n) /*first with 5*/
    {

       unsigned int a =1 ;        
       static unsigned int b=2;        
       a+=b; b+=a;        // a = 14, b = 27
       {

         unsigned int a=3;        
         a+=b; b+=a;        // a = 30, b = 57
       }
       //printf("%d %d ",a,b);
       return (n+a+b);        // 4 + 57 + 14 = 75(which is printed first). 
    }

したがって、出力。

于 2012-10-25T07:31:48.733 に答える
0

これには、「関数の副作用」と呼ばれるよく知られた用語があります。関数内の変数を変更し、関数を呼び出し、変数が既に変更されていることを期待して、変数を使用するステートメントに依存します。通常、これは避けるべきであり、良い方法ではありません。

このようなシナリオでは、関数を呼び出して戻り値を保存し、それらを printf で使用するか、2 つの異なる printf 呼び出しを行うことをお勧めします。

副作用

于 2012-10-25T07:31:57.273 に答える