腕時計の沼、オーディオの沼、PCの沼。『タクジの沼』
コンパイラとプログラムが変数にアクセスする方法に影響を及ぼします。
変数の型の前にconstが付いていると、その変数はプログラムによって変更できないことを意味します。 しかし、宣言時の初期化で初期値を与えることができます。 関数がパラメータの指しているオブジェクトを変更しないようにすることができます。
[例]
int main(void){
const int i = 10;
printf("%d", i);
return 0;
}
[例]
void pr_str(const char *p){
while(*p) put char(*p++);
}
int main(void){
char str[80];
printf("...");
gets(str);
pr_str(str);
return 0;
}
constポインタのパラメータの最も重要な役割は、それらのパラメータの指す変数をほとんどの標準関数が変更できないようにすることです。
変数の型の前にvolatileを置くことによって、変数の値が明確に定義されていない方法で変更されることをコンパイラに知らせます。
例えば、割り込みを行うルーチンに変数のアドレスを渡すような場合や、変数の値が割り込みごとに変わるような場合です。
volatileの重要性は、Cコンパイラに高度に複雑で洗練された最適化をプログラムに適用し、
高速コンパイラは変数の値が明確に定義されていない方法で変更されることを知らされていれば、変数の内容を参照する度に調べ直します。
[例]
volatile unsigned u;
give_address_to_some_interrupt(&u);
for(;;){
printf("%d", u);
...
...
}
このコードで、uがvolatileとして宣言されていなければ、コンパイラはuの値を呼び出しごとに調べ直しを行わず、
printf()の反復呼び出しを最適化します。
volatileを使用すると、コンパイラは呼び出しごとにuの値を読み直すようにコードを生成します。