web-dev-qa-db-ja.com

なぜプログラミングで定数を使用するのですか?

IvorHortonのBeginningCの本を使って、Cの勉強を少しやり直したところです。同じ文の変数と混同されているように見える定数の宣言について少し触れました。

明確にするために、Cで定数と変数を指定することの違いは何ですか、そして実際には、変数の代わりに定数を使用する必要があるのはいつですか?プログラムの実行中に情報が変更されない場合は定数を使用するように言われているのを知っていますが、代わりに変数を使用できなかった時期は考えられません。

28
Adam N

名前から推測できるように、変数は時間とともに変化します。変わらなければ「損失なし」です。値が変更されないことをコンパイラーに指示すると、コンパイラーは、値を直接インライン化し、スタック上の定数にスペースを割り当てないなど、一連の最適化を実行できます。

ただし、コンパイラが、設定後に値が変更されるかどうかを正しく判断できるほど賢いことを常に期待できるとは限りません。コンパイラーが100%の信頼度でこれを判別できない状況では、コンパイラーは安全性の面で誤りを犯し、変更される可能性があると想定します。これにより、インライン化の回避、特定のループの最適化の回避、並列処理に適さないオブジェクトコードの作成など、さまざまなパフォーマンスへの影響が生じる可能性があります。

このため、また読みやすさも重要であるため、可能な限り明示的な定数を使用し、実際に変更される可能性があるものには変数を残しておく必要があります。

リテラル数値の代わりに定数が使用される理由について:

1)コードを読みやすくします。 3.14が(うまくいけば)何であるか誰もが知っていますが、3.07がPAの所得税率であることを誰もが知っているわけではありません。これはドメイン固有の知識の例であり、将来コードを保守するすべての人(税務ソフトウェアなど)がそれを知っているわけではありません。

2)変更を加えると、作業が節約されます。将来的に税率が変更される場合、3.07から3.18ごとに行って変更するのは面倒です。常に変更を最小限に抑え、理想的には1つの変更を加える必要があります。同時に行う必要のある変更が多いほど、何かを忘れてエラーにつながるリスクが高くなります。

3)危険なエラーを回避します。所得税率が3.05の2つの州があり、そのうちの1つが3.18に変更され、他の州は3.07のままであると想像してください。交換するだけでは、重大なエラーが発生する可能性があります。もちろん、多くの整数または文字列定数値は「3.07」よりも一般的です。たとえば、数字の7は、週の日数などを表すことができます。大規模なプログラムでは、各リテラル値が何を意味するのかを判断するのは非常に困難です。

4)文字列テキストの場合、複数の言語をサポートする場合に文字列プールをすばやく変更できるように、文字列に記号名を使用するのが一般的です。

変数と「定数変数」に加えて、列挙型の言語もあることに注意してください。列挙型を使用すると、定数の小さなグループ(戻り値など)のタイプを実際に定義できるため、これらを使用するとタイプセーフになります。

たとえば、曜日と月の列挙がある場合、月を1日に割り当てると警告が表示されます。整数定数を使用するだけの場合、3日目が3か月目に割り当てられても警告は表示されません。常に型の安全性が必要であり、読みやすさが向上します。列挙は、順序を定義するのにも適しています。曜日の定数があり、週を日曜日ではなく月曜日に開始したいとします。

34
Uri

定数を使用することは、午前2時にコーディングしているとき、またはコーヒーを飲む前に、コードのどこかで誤って値を変更することから身を守るための、防御的なプログラミングの方法です。

技術的には、はい、代わりに変数を使用できます。

15
user151323

1つは、パフォーマンスの最適化です。

さらに重要なことに、これは人間の読者向けです。対象読者はコンパイラーだけではないことを忘れないでください。コードで自分を表現し、コメントを避けるのに役立ちます。

const int spaceTimeDimensions = 4;

if(gpsSattelitesAvailable >= spaceTimeDimensions)
  Good();
10

定数には、変数に比べていくつかの利点があります。

定数は、コードが基になる値を変更できないことをある程度保証します。これは、小規模なプロジェクトではそれほど重要ではありませんが、複数の作成者によって作成された複数のコンポーネントを含む大規模なプロジェクトでは重要です。

定数は、最適化のための強力なヒントもコンパイラーに提供します。コンパイラは値が変更できないことを知っているので、メモリから値をロードする必要はなく、定数の正確な値に対してのみ機能するようにコードを最適化できます(たとえば、コンパイラは乗算/除算にシフトを使用できます) constが2の累乗の場合)

定数も本質的に静的です。定数とその値をヘッダーファイルで宣言でき、正確に1か所で定義する必要はありません。

10
Michael

Cのような低水準言語の場合、定数を使用すると、いくつかのコンパイルの最適化が可能になります。

一般的なプログラミング言語の場合、実際には必要ありません。 RubyとJavaScriptのような高水準の動的言語はそれらを備えていません(または、少なくとも本当の意味での定数ではありません)。代わりに変数が使用されます。

3
Jakob

constキーワードは、関数パラメーター、特にポインターによく使用され、ポインターが指すメモリーが関数によって変更されないことを示します。たとえば、strcpyのdeclerationを見てください。

char *strcpy(char *dest, const char *src);

それ以外の場合、たとえば、次のような宣言

const int my_magic_no = 54321;

優先される可能性があります:

#define MY_MAGIC_NO 54321

型安全上の理由から。

2
James Morris

定数とは、メモリを共有したいだけで、変更されない場合です。

2
anon242463

これは、特定の種類のエラーをトラップする非常に簡単な方法です。変数constを宣言し、誤って変数を変更しようとすると、コンパイラーがその変数を呼び出します。

1
crazyscot

ループの開始時、if -elseステートメント内の条件のチェックなどの目的で、変数の宣言と初期化に関して定数が非常に必要です。

詳細については、次のいずれかの記事をお読みください。

1
yogi

Constを使用しないということは、チームプロジェクトの誰かがどこにint FORTY_TWO = 42そしてそれを等しくするFORTY_TWO = 41別のチームメンバーによる別の場所。したがって、世界の終わりが起こり、あなたも人生への答えを失います。 constを使用しますが、これは発生しません。さらに、constは、通常の変数の格納と比較すると、メモリの他の場所に格納されており、より効率的です。

0
thyrgle