const使用小結

2134 ワード

const VS enumと#define
C++では、定数にはcosnt、enum、defineの3つの表現がありますが、この3つの表現は何が違いますか?1.defineは、前処理のコンパイル時にデータ置換を行い、記憶領域がない.Enumはコンパイル時定数であり、記憶空間がない.constは、コンパイラがconstant propagationを行うかどうかによってデータ記憶領域を割り当てます.2.#defineは、debugデバッグ時に変数名が表示されません.enumは、デバッグ時に変数名が表示されますが、アドレスが表示されません.constは、デバッグ時に変数名とアドレスが表示されます(したがって、constのみが変数アドレス、転送アドレスを取得できます).3.enumとconstはタイプが安全で、#defineはそうではありません.enumおよびdefineのみがswitchに使用できます.
いくつかの概念
1.constの役割ドメインはファイル全体で、デフォルトは内部接続です.constを外部接続にして別のファイルを参照できるようにするには、externとして明確に定義する必要があります.extern constは強制的にスペース割り当てを行い、externは外部リンクを使用することを意味するため、ストレージスペースを割り当てる必要があります.2.constは運転期間定数で、static constを加えるとコンパイラ定数になります.
コンスタント折りたたみ
まず例を見てみましょう.
#include <iostream>
using namespace std;
int main()
{
    const int a = 2*5; 
    int *b = (int*)&a;
    *b = 20;
    cout << "&a = " << &a << ',' << "b = " << b <<endl
	    << "a = " << a << ',' << "*b = " << *b <<endl;
    return 0;
}
出力結果:
&a = 0x7fffc239893c,b = 0x7fffc239893c
a = 10,*b = 20
では、&aとbの値(アドレス)が同じであり、aと*bの値が異なることがわかります.つまり、同じアドレスのメモリ領域に異なる値があります. 
どうしてですか. 
コンパイル中に最適化、すなわち定数折り畳み(const folding)が行われたため、プログラムはコンパイル中に2つのプロセスを経た:1.const folding; 2.copy propagation.
const folding:前例ではconst int a=2*5;式の値を計算すると、コンパイラは2*5を10に計算します.このプロセスはconst foldingと呼ばれます.
copy propagation:コンパイラは、aという識別子に遭遇すると、対応するアドレスから値を取るのではなく、自動的にaを10に置き換え、このプロセスがcopy propagationである.
上記の例はこの2つのプロセスの結果であり、後でコードの中でaに出会った場所では、コンパイラは自動的にaを10に置き換える.   
定数折り畳み概念:定数折り畳みは、コンパイル時間に定数表現を単純化するプロセスです.簡単に言えば、定数式を計算して評価し、求めた値で式を置き換え、定数表に入れることです. 
コンパイル時定数運転時
コンパイル時定数コンパイル後の変数値が決定され、プログラム実行時定数値は変更されません.たとえば、const int RUN_TIME = 1; ランタイム定数は、プログラムの実行時に毎回値が異なります.例:
int read_at_runtime()
{ 
  int val; 
  std::cin >> val; 
  return val; 
}
const int RUN_TIME = read_at_runtime();

次の場合、コンパイル時定数を使用して実行できない場合があります.
1.配列境界;2.switch case式;3.ビットドメイン長;4.列挙初期化;5.テンプレートの非タイプパラメータの割り当て.