web-dev-qa-db-ja.com

ループ内で変数を定義するのは良いことですか?

講師がループ内で変数を定義するべきではないと言ったことはありますが、正直なところ、なぜかはわかりません。

その欠点は何ですか?

誰かがそれを私に説明できますか?

16
user3260672

ループ内の変数defineは問題ありません。実際、識別子は可能な限り最小のスコープに限定する必要があるため、これは良い習慣です。

悪いのはassignループ内の変数で、ループを実行する前にbefore割り当てることができる場合です。割り当ての右側がどれほど複雑であるかに応じて、これはかなり高価になり、ループの実行時間を支配することさえあります。すべての反復で同じ計算値を使用するループを作成する場合は、ループを確実に計算するループ-スコープを最小化するよりも重要です。

明確にするために、compute()が常に同じ値を返す限り、これは

int value = compute();
while (something) {
    doSomething(value);
}

これより賢いです:

while (something) {
    int value = compute();
    doSomething(value);
}
43
Kilian Foth

複合型には、自明でないコンストラクタとデストラクタがあります。

これらは、ループ本体の開始時と終了時に呼び出されます(初期化されてスコープ外になるため)。一部のメモリを割り当てる必要があるなど、初期化に負荷がかかる場合は、回避する必要があります。

しかし、ささいなタイプの場合は問題ありません。割り当てと割り当て解除自体は、スタックポインタの値を加算および減算するだけです。 (最適化されます)

16
ratchet freak

まあ、彼のアドバイスはやや単純すぎる(それは控えめな表現です)。
その後は良いアイデアから気にかける人および悪いアイデアから不可能までのすべての範囲です。 =。

  1. 古いものを破壊して新しいものを作成するよりも、再利用の方が安価な場合は、必ず従う必要があります。

    #include <iostream>
    #include <string>
    
    int main() {
        std::string s; // Don't needlessly free the buffer
        while ((std::cin >> s))
            std::cout << s;
    }
    
  2. パフォーマンスに影響しない場合は、スタイルの問題として回避する必要があります。

    #include <stdio.h>
    #include <stdlib.h>
    int f(int, int);
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            int x = Rand(); // Declared here so you don't need to hunt it down.
            printf("%d => %d\n", x, f(x-1, x+i));
        }
    }
    
  3. reallyは、パフォーマンスが悪い場合やセマンティクスが間違っている場合は回避する必要があります。

    #include <iostream>
    #include <string>
    std::string generate(int);
    
    int main() {
        for(int i = 0; i < 100; ++i) {
            std::string s = generate(i); // Using copy-ellision here
            std::cout << s;
        }
    }
    
  4. できません使用されているタイプがスワッピングも移動割り当てもコピー割り当ても許可していない場合は、それに従います。

    #include <iostream>
    #include <puzzle>
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            Puzzle x(i); // Puzzle is an immutable class. For whatever reasons.
            std::cout << x;
        }
    }
    
6
Deduplicator