34

Ivor Horton の Beginning C book を使用して、C の学習について少し復習しました。同じ文で変数と混同されているように見える定数の宣言について少し理解しました。

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

4

10 に答える 10

42

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

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

このため、また可読性も重要であるため、可能な限り明示的な定数を使用し、実際に変化する可能性があるもののために変数を残すように努めるべきです。

リテラル数値の代わりに定数が使用される理由については、次のとおりです。

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

2) 変更時の手間が省けます。将来税率が変わると、3.07 から 3.18 ごとに変更するのは面倒です。常に変更を最小限に抑え、理想的には単一の変更を行います。同時に行う変更が多いほど、何かを忘れてエラーにつながるリスクが高くなります。

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

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

変数と「定数変数」に加えて、列挙型の言語もいくつかあることに注意してください。列挙型を使用すると、実際には小さなグループの定数 (戻り値など) の型を定義できるため、それらを使用すると型の安全性が確保されます。

たとえば、曜日と月の列挙がある場合、月を日に割り当てると警告が表示されます。整数定数のみを使用すると、3 日が 3 月に割り当てられたときに警告は表示されません。常にタイプ セーフが必要であり、読みやすさが向上します。列挙は、順序を定義するのにも適しています。曜日の定数があり、週を日曜日ではなく月曜日に開始したいとします。

于 2010-06-01T21:50:23.673 に答える
19

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

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

于 2010-06-01T21:52:01.350 に答える
13

定数には、変数よりもいくつかの利点があります。

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

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

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

于 2010-06-01T21:54:51.010 に答える
10

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

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

const int spaceTimeDimensions = 4;

if(gpsSattelitesAvailable >= spaceTimeDimensions)
  Good();
于 2010-06-01T21:51:22.890 に答える
3

定数は、メモリを共有したいだけの場合であり、変更されません。

于 2010-06-01T21:51:42.337 に答える
3

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

一般的なプログラミング言語の場合、それらは実際には必要ありません。Ruby や JavaScript などの高レベルの動的言語には、それらがありません (または、少なくとも真の一定の意味ではありません)。あなたが提案したように、代わりに変数が使用されます。

于 2010-06-01T21:55:08.813 に答える
2

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

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

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

const int my_magic_no = 54321;

以下よりも優先される場合があります。

#define MY_MAGIC_NO 54321

型安全上の理由から。

于 2010-06-01T21:50:42.547 に答える
1

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

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

于 2011-10-20T05:16:57.443 に答える
1

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

于 2010-06-01T21:52:58.037 に答える
0

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

于 2010-06-01T21:58:03.210 に答える