C++でstatic_cast(x)を使うべき理由 ― (int)xとの違いとは?
(int)xはC言語スタイルの型キャストであり、C++ではstatic_cast
Cスタイルキャストの危険性
Cスタイルのキャストでは、ある型のポインタをまったく別の型のデータに向けてキャストできてしまうことがあります。例えば、整数型ポインタは文字型データを指すことも可能です。両者はよく似ており、違いは文字型が1バイト、整数型が4バイトであるという点だけだからです。一方、C++のstatic_cast<>()はCスタイルのキャストよりもはるかに厳格で、互換性のある型同士の変換のみを許可します。
コード例
char c = 65; // 1バイトのデータ。'A'のASCIIコード int *ptr = (int*)&c; // 4バイトのポインタ
この例では、4バイトのポインタが割り当てられたわずか1バイト分のメモリを指しています。そのため、実行時エラーが発生したり、隣接するメモリ領域を上書きしてしまう恐れがあります。
static_castを使った安全な変換
C++のstatic_cast<>()を使用すると、コンパイラがポインタとデータの型が一致しているかどうかを自動的にチェックします。型が一致しない場合は、コンパイル時に不正なポインタ代入としてエラーが報告されます。
char c = 65; // 1バイトのデータ。'A'のASCIIコード int *ptr = static_cast(&c);
このコードはコンパイル時エラーを生成します。つまり、バグを実行前に検出できるため、Cスタイルのキャストに比べてはるかに安全です。
まとめ
C++には、static_castのほかにも、動的な型変換を行うdynamic_cast、const性を除去するconst_cast、ポインタ間の再解釈を行うreinterpret_castといった専用のキャスト演算子が用意されています。それぞれの用途に応じて適切なキャスト演算子を使い分けることで、型の意図が明確になり、コンパイラによるチェックの恩恵も受けられます。C++のコードを書く際は、Cスタイルの(int)xではなく、static_cast
-
C++で範囲加算を効率的に解く方法 ― 差分配列(いもす法)の活用
問題概要 サイズnの整数配列が与えられ、すべての要素が0で初期化されているとします。さらに値kが与えられ、k回の更新操作を行います。各操作は [startIndex, endIndex, inc] という3つ組で表され、部分配列 A[startIndex ... endIndex](startIndexとendIndexを含む)の各要素に inc を加算します。k回の操作をすべて実行した後の、変更後の配列を求めるのがこの問題です。 例えば、入力が length = 5、updates = [[1,3,2],[2,4,3],[0,2,-2]] の場合、出力は [-2, 0, 3, 5, 3]
-
C++で点集合の線対称(ラインリフレクション)を判定するアルゴリズム
問題概要2次元平面上にn個の点が与えられます。このとき、y軸に平行な直線で全ての点を鏡映(反射)した結果が、元の点集合と完全に一致するような直線が存在するかどうかを判定します。言い換えれば、ある直線を対称軸として全ての点を反転させたとき、反転後の点の集合が元の集合と同一になるかを確認する問題です。例えば、入力が points = [[1,1],[-1,1]] の場合を考えてみましょう。この場合、x = 0 の直線(y軸)を対称軸とすると、点 (1,1) は (-1,1) へ、(-1,1) は (1,1) へと移ります。点集合全体としては変化がないため、出力は true となります。解法のポイン