2017-09-10 11 views
2

このC++テストがあり、先生はコード内で直接数値を使う代わりに定数を宣言するのが本当に難しいです。下の例では、ZEROを定数として宣言しています。定数を宣言するか、コード内の数字を使用する

これは不要ですか、これはいいですか?この方法でメモリを増やすか、コードを「遅くする」のですか?

int main() { 

    int kmStart, kmEnd; 
    const int ZERO = 0; 

    cout << "Starting Kms? "; 
    cin >> kmStart; 

    cout << "Ending Kms? "; 
    cin >> kmEnd; 

    while (kmStart < ZERO || kmStart > kmEnd) { 
     cout << "Invalid Input!" << endl << endl; 

     cout << "Starting Kms? "; 
     cin >> kmStart; 

     cout << "Ending Kms? "; 
     cin >> kmEnd; 
    } 

} 
+1

定数は、コンパイル時に解決し、最適化されます。実行時に余分なメモリやパフォーマンスを犠牲にすることはありません。 – user0042

+1

もちろんこれは不要です!それは定数のためではありません!実際、Bathshebasの答えに見られるように、これは実際に大きなプログラムで傷つける可能性があります! –

+2

定数 'ZERO'を持つことは、定数' FORTY_FIVE'を持つようなものです。リテラル値 '45'を入力することと変わりありません。定数を使用して、目的を説明する特定でない値を表します。 – Galik

答えて

5

constexpr int ZERO = 0;がほぼ完全にコンパイルされます。

C++ 11以降の新しいキーワードconstexprに注意してください。

現在のコードでは、ZEROがコンパイルされている可能性がありますが、パフォーマンスが低下していない場合でも無視できます。入出力機能。

私は教師が0よりも明確であると考えている理由を教えてください。ZERO0が表示されているときは、誰が何を処理しているかを知っています。例えば、ZEROは、'0'、まったく別の意味では"0"を意味する可能性があります。これをデバッグするときは、コードをチェックしています。

+0

例えば10のような他の数字を扱うときに、あなたが例えば等式で10を除算したり追加したりする場合はどうしますか? –

+0

さて、私は10を使っています。少なくとも、int型の文字列であることはすぐにわかります。 – Bathsheba

+0

@FredrikBurmester:それは**依存しています。たとえば、10進数を2進数に変換する場合、10が明白です。しかし、10が何らかの価値を推測しているときは、名前を付けてください。一般的に、コードの目的は主に人間とのコミュニケーションであることを忘れないでください。どんな具体的なケースでも、10があなたに伝えていることを自分に尋ねるだけです。それが不明な場合は、名前を付けます。 –

2

一般に、コードの数値の代わりに定数を使用すると、コードをより読みやすく保守しやすくなります。

たとえば、あなたが0.1秒のタイムステップでのシミュレーションのいくつかの種類があり、

を使用するために容易になるだろう、あなたのソースコードの異なる場所でこのタイムステップの値が必要になります。

は、次の例を考えてみましょう

const double timesstep = 0.1 

0.1をどこに書きますか?

利点がある:

  • のみ1行は、あなたが タイムステップ
  • の値を変更したい場合は、

を意味する定数を知っていれば、コードは、読みやすくなり、変更する必要があります。しかし、あなたの場合、私は0の代わりに0を使うほうが読みやすいと思うし、 "least_start"などの表現に変更すると...

+1

これは関係ないですが、0.1の連続する増分が浮動小数点のメリー・ヘルルに等しいことに注意してください。 't = T * step/steps'のようなものを使うのが良いでしょう。 – Bathsheba

+0

これは、マジックナンバーの代わりにconstansを使用する必要がある例です。現実の世界の例では、タイムステップ、タイムポイント、タイムディタなどの何かを定義する方法が問題に依存します... – Hatatister

3

長寿命アプリケーションの開発には、適切な名前の定数の使用が必須です。単純な数値リテラルを迅速に管理することは手間がかかります。次の例を考えてみましょう:

foo(42); 
bar(42); 

それはいくつかの問題があります:42値は、両方の機能で42が呼び出すかどうかを推測することはできません

  • どこから来たのかを推測することはできません

    • をちょうど偶然であるか、または意図的に同じ値を渡しています
    • これまでのポイント変更プログラムの動作の結果として、私たちは手動で特定の価値があるすべての場所を特定する必要があるため、調整したいアプリケーションを利用する

    アプリケーションが何百ものファイルで構成されている場合、それは文字通りの悪夢です。

    したがって定数は、例えば、コード片を

    constexpr int const fast_foobing_rate{42}; 
    constexpr int const slow_barring_coeff{42}; 
    
    foo(fast_foobing_rate); 
    bar(slow_barring_coeff); 
    

    又は

    constexpr int const days_in_week_count{7}; 
    constexpr int const frobbing_weeks_count{6}; 
    inline constexpr int get_frob_repetitions_count(void) noexcept 
    { 
        return(days_in_week_count * frobbing_weeks_count); 
    } 
    
    foo(get_frob_repetitions_count()); 
    bar(get_frob_repetitions_count()); 
    

    だから今になることが代わりに使用された場合:我々は値

  • の起源を追跡することができる

    • これらの永続的な値ar eは、我々は簡単にそれらの定義を変更することで、これらの永続的な値を調整することができますし、私たちの変更が自動的に全体のコードベース

    全体に適用され、すべてのこれらの利点を我々は性能低下に苦しむません

  • を使用しました。定数型に応じて、パフォーマンスにもいくつかの利点があります。

  • 0

    Personnalyは、整数定数のために私は列挙(ソース==スコット・マイヤー、効果的なC++)を使用しています:

    int main (int argc, char* argv []) { 
        enum Constant { 
        NTRY = 32, 
        NEQ = 8, 
        SMAX = 200000000, 
        ALERT = 65536 
        }; 
    
        size_t ntry (Constant::NTRY); 
        std::cout << "ntry == " << ntry << std::endl; 
        return 0; 
    } 
    
    関連する問題