C言語のvolatile修飾子とは?意味と使い方をわかりやすく解説
この記事では、C/C++におけるvolatile(揮発性)修飾子の意味と役割について詳しく解説します。
volatileは、変数を宣言するときに付与する修飾子です。コンパイラに対して「この変数の値はいつでも外部から変更される可能性がある」ことを伝えるために使われます。これにより、コンパイラによる最適化を抑制し、意図しない動作を防ぐことができます。
volatile修飾子の主な性質
volatileキーワードが付いた変数には、次のような特徴があります。
- メモリへの割り当てが削除されず、必ず実メモリ上に保持される
- 変数がCPUレジスタにキャッシュされない
- 代入された順序どおりに値が扱われる
基本的な使い方
volatileの指定方法は非常にシンプルです。次の2つの宣言は、どちらも正しく同じ意味を持ちます。
volatile int a; int volatile a;
通常のデータ型と同様に、ポインタ・構造体・共用体にもvolatileを適用できます。volatile付きの構造体や共用体は、それ自体がvolatileであるだけでなく、そのメンバ変数もvolatile型として扱うことができます。
volatileを使うべき場面
volatileは、プログラムの外側から値が書き換えられる可能性がある変数に対して使用します。代表的な使用例は以下のとおりです。
- メモリマップド周辺機器レジスタ:ハードウェアの状態が常に変化するため
- 割り込みサービスルーチン(ISR)や別の関数から更新されるグローバル変数:メイン処理側からは変更が見えないため
- マルチスレッドアプリケーション:他スレッドによって共有変数が更新されるため
コード例で見るvolatileの効果
次の2つのコードブロックを比較してみましょう。
// volatileなしの場合
int main() {
int value;
value++;
}
// volatileありの場合
int main() {
volatile int value;
value++;
}1つ目のコードにはvolatileキーワードがありません。この場合、コンパイラは最適化の一環として、変数valueをメモリからCPUレジスタへコピーし、その上で演算を行います。
一方、2つ目のコードではvolatileが指定されているため、変数はメモリからレジスタへコピーされません。すべての読み書きが直接メモリに対して行われるため、ハードウェアや割り込みなど外部要因による値の変更が確実に反映されます。
このようにvolatileは、組み込みシステム開発などにおいて、ハードウェアとの整合性を保つために欠かせない重要な修飾子です。
-
C++で点集合の線対称(ラインリフレクション)を判定するアルゴリズム
問題概要2次元平面上にn個の点が与えられます。このとき、y軸に平行な直線で全ての点を鏡映(反射)した結果が、元の点集合と完全に一致するような直線が存在するかどうかを判定します。言い換えれば、ある直線を対称軸として全ての点を反転させたとき、反転後の点の集合が元の集合と同一になるかを確認する問題です。例えば、入力が points = [[1,1],[-1,1]] の場合を考えてみましょう。この場合、x = 0 の直線(y軸)を対称軸とすると、点 (1,1) は (-1,1) へ、(-1,1) は (1,1) へと移ります。点集合全体としては変化がないため、出力は true となります。解法のポイン
-
C++で解く対角トラバースII:リストのリストを対角順に出力する方法
問題の概要 「リストのリスト」である nums が与えられたとき、そのすべての要素を対角順(ダイアゴナルオーダー)に並べて出力するのがこの問題の目的です。 たとえば、次のような行ごとに長さの異なる配列(ジャグ配列)が入力として与えられた場合を考えてみましょう。 このとき、期待される出力は次のとおりです。 [1, 6, 2, 8, 7, 3, 9, 4, 12, 10, 5, 13, 11, 14, 15, 16] 解法のアプローチ この問題は、各要素を「値と座標のセット」として一旦記録し、対角線ごとの順序になるようにソートし直すことで解けます。具体的な手順は以下の通りです。 結果を格納す