5

float の配列の配列のコピーを作成するメソッドを作成しています。これをデバッグした後、いくつかの非常に奇妙な値を取得していたので、C++ 配列の FAQ を読んでもこれを理解できなかったので、これについて質問しようと思いました。

コードの関連部分は次のとおりです (これは巨大なプログラムの一部であり、ほとんどの部分はこの投稿には関係ありません)。

// height and width are integer global variables
void method () {
    float testArray[height][width];
    for(int j = 0; j < height; ++j) {
        for(int i = 0; i < width; ++i) {
            testArray[j][i] -= 0.0;
            std::cout << testArray[j][i] << std::endl;
        }
    }
}

(私のテストでは、高さ = 32、幅 = 256 ですが、それは関係ありません。) testArray を初期化すると、値はすべて 0.0 になるはずですよね? 次に、ループ内で、testArray の特定の要素から 0.0 を減算しますが、これは論理的に値をまったく変更しないはずです。ただし、testArray の値をデバッグ ステップとして出力すると、次のスニペットのように、いくつかの奇妙な値が生成されます。

[...]
0
[...]
-3.23805e-24
[...]
8.40779e-45
[...]
1.79513e+37
[...]
0
[...]
3.19586e+36
[...]

最も気になる値は、上記の 4 番目の数値などの無限の値です。正直なところ、なぜこれが起こっているのかわかりません。これらの値はすべてまだ約 0.0 であるべきではありませんか? 浮動小数点演算の不正確さに関係していると思っていましたが、それは無限値になるはずがありません....

4

4 に答える 4

7

いいえ、そのように配列を宣言すると、組み込み型であるため初期化されません。減算を行う前に、自分でゼロに初期化する必要があります。

ただし、(おそらく非 const 次元で) 配列を宣言することは、コンパイラの拡張機能であり、言語の一部ではないことに注意してください。

vector両方の問題を一度に解決するものを使用します。

std::vector<std::vector<float> > testArray(height, std::vector<float>(width));
于 2012-11-19T20:51:32.487 に答える
3

配列内の値を初期化してみてください。

float testArray[height][width] = {};
于 2012-11-19T20:52:21.127 に答える
2

この行は、初期化されていない配列を作成します要素の値はゴミになる可能性があります。

float testArray[height][width];

float のデフォルト値 (ゼロ) で初期化するには、次の構文を使用します。

float testArray[height][width] = {};
于 2012-11-19T20:53:19.200 に答える
2

この答えは間違っていますが、私はそれを残しているので、誰も試しません!

次の非常に明示的な定義を使用します。

float testArray[height][width] = {{0.0f}};

配列内のすべての値がゼロに初期化されるようにします。それ以外の場合、配列内の値は未定義になります。これが最も「読みやすい」ソリューションだと思います。

なぜ間違っているのですか?

@Dave が以下で言及しているように、この解決策はこのケースでは機能しますが、誤解を招く可能性があります。の最初の要素のみを明示的testArrayに 0.0 に割り当て、配列内の他のすべての要素を値で初期化します。

正しい解決策は確かに次のとおりです。

float testArray[height][width] = {};

0.0fこれは、配列内のすべての要素を値初期化します ( typeのデフォルト値に) float

于 2012-11-19T20:54:07.083 に答える