-1
#include<stdio.h>
void main(void)
{
    int a[5]={90,78,77,98,98}, b[5]={80,45,67,88,57}, c[5]={88,99,65,55,74},total[3],i,j;
    for(j=0;j<=4;j++)
        {
            total[0]+=a[j];
            total[1]+=b[j];
            total[2]+=c[j];
        }

    for(i=1;i<=3;i++)
    {
    printf("%d행의 가로 합 : %d\n",i,total[i-1]);
    }
}

total[0]total[1]は正しい値ですが、total[2]間違った値です。私は自分のせいを見つけることができません。説明できますか?

4

1 に答える 1

7

ここでの最初の問題はコードにあります

        total[0]+=a[j];
        total[1]+=b[j];
        total[2]+=c[j];

total[n]初期化されていない sを使用している場所。それらには不確定な値が含まれており、それらを使用すると未定義の動作が呼び出されます。

詳しく説明するtotalと、初期化されていない自動ローカル変数であるため、配列の要素の初期値は不定です。+=これらの要素で演算子を使用することにより、不確定な値を読み取る(使用する) ことになるため、場合によっては UB が呼び出されます。

からの関連引用C11、章§6.5.16.2、複合代入

形式の複合代入は、左辺値が 1 回だけ評価されることを除いてE1 op= E2、単純な代入式 と同等です。また、不定順序の関数呼び出しに関しては、複合代入の操作は単一の評価です。アトミック型の場合、複合代入は メモリ順序セマンティクスを使用した操作です。E1 = E1 op (E2)E1E1read-modify-writememory_order_seq_cst

したがって、初期化されていない値に対して を使用すると、値が不確定な変数を+=読み取ろうとしている (または使用しようとしている) ため、UB が発生します。

必要に応じて、次のような構文を使用して配列全体を初期化できます

  int total[3] = {0};

これは、配列のすべての要素を 0 に初期化します。これは、基本的に期待していたものです。

とはいえ、仕様によると、ホストされた環境でvoid main(void)の適合署名ではありません。少なくともそうである必要があります。main()int main(void)

于 2016-09-14T13:18:42.530 に答える