C言語のconst修飾を使いこなす方法: 定数、不変の値

324, 2021-09-16

目次

C言語のconst修飾とは?

C言語にはconstと呼ばれる修飾子があります。
このconst修飾子は、値を定数にして不変にしたい時に使われます。

この記事ではC言語のconstの使い方を詳細なコードをまじえて解説します。
この記事を読めばC言語のconst修飾を使いこなすことができるようになります。
具体的には↓を見ていきます。

  • C言語のconstの読み方

  • C言語のconstはどんな時に使うのか?

  • 値を不変にすると何が嬉しいのか?

  • C言語のconstは使ったほうが良いのか?

  • コードで見るC言語のconstの使い方

  • C言語のconstをキャストで無理やり外す

C言語のconstの読み方

C言語のconstconstant(定数)の略です。
読み方は「コンスト」や「コンスタ」になります。

C言語のconstはどんな時に使うのか?

C言語のconstはどんな時に使うのでしょうか?
const修飾は変数などの値を定数にして不変にしたい時に使われます。
このconstで修飾された変数は定数扱いになります。

値を不変にしたい時に使う

値を定数にして不変にしたい時というのは、その値を書き換え不能にしたい時ということになります。
書き換え不能にして、今後その値が書き変わることがないようにconstで修飾するわけですね。
そうしておくことで事故防止やミス防止などになるわけです。

事故を防止したい時に使う

「事故」というのは突然おこるものです。
C言語のプロジェクトにおける事故、定義した変数の値がいつのまにか書き変わっていて、プログラムの動作が意図しないものになっていた・・・などがそうです。
こういった事故を防ぎたい場合はconst修飾子が使えます。

値を定数にして不変にすれば、その変数の値が書き変わらなくなるので、こういった事故を防止できるわけですね。

値を不変にすると何が嬉しいのか?

const修飾で変数の値を定数にして不変にすると何がうれしいのでしょうか?
わざわざコストをかけて変数にconstを付ける理由はあるのでしょうか?
constを付けて何か見返りはあるのでしょうか?

結論から言うと、見返りはあります

意図しない値の変更を防げる

繰り返しになりますが、C言語のconstで変数の値を定数にして不変にすれば、意図しない値の変更を防ぐことが出来ます。
たとえば複数人で開発するプロジェクトだった場合、変数にconstを付けておけばほかの開発者の人がうっかり変数の値を書き換えてしまうという事態も防ぐことが出来ます。
このようにあらかじめミスを「予防」しておくことでプロジェクトを円滑に進めることが可能になります。

事故防止になる

繰り返しになりますが、C言語のconstを付けることは事故防止になります。
特に不特定多数の開発者が参加するプロジェクトを考えてみてください。
たとえばconstを禁止にして、すべての変数を書き換え可能にしたらどうなるでしょうか?

きっとそのプロジェクトでは、だれかがだれかの定義した変数をうっかり書き換えるといったミスが連発することでしょう。
そうすると、事故が事故が呼びプロジェクトがあっという間に破綻するなどといったことも起こるかもしれません。

C言語のconstは使ったほうが良いのか?

C言語のconst修飾は使ったほうがいいのでしょうか?
使わないことによるデメリット、使うことによるメリットはどんなものがあるのか?

デメリット、メリットについてはこれまで見てきたようにミスや事故防止の話になります。
でもconstは必ず使わなければいけないものでしょうか?

使わない人も一定数いる

constを使わない開発者も一定数います。
すべて値を書き換え可能にしておくと、デバッグが容易になるからです。
そのためconstを使わずにC言語のコードを書く人もけっこういます。

基本的には使ったほうがいい

しかしC言語のconstは基本的には使ったほうが良いものです。
constは慣れないうちは使いどころがよくわからず、どこで使ったら良いのか悩む場合もあります。
しかし慣れてくると「ここはconstだな」とか「ここにはconstを付けておこう」などとわかるようになります。

ミスや事故による意図しない変数の値の書き換えが起こらないようにconstを付けておくのは設計の基本と言えます。

使うことで設計が複雑になる?

constを使うことでC言語のコードの設計が複雑になるという見方をする人もいます。
たしかにconstをつけないよりはconstをつけたほうが設計は複雑になります。
しかし、その複雑さを補って余りあるのがconstのメリットです。

ただconstを付けないほうが設計はシンプルになります。これは事実です。
しかしミスや事故が起こる可能性が高くなるので、あまりオススメはできません。

しかしPythonなどの言語はそもそもconstなどがないですが、こう言った言語でも大規模開発は可能であることを考えると、constは別に必須ではないという感じもします。

コードで見るC言語のconstの使い方

それでは実際のC言語のコードを見ながらconstについて見ていきたいと思います。
まずconstの基本的な使い方は↓になります。

const 型 変数名 = 値;

基本的には型の前にconstを付けます。
こうすると、constは直後の型を定数にするという意味を持ちます。

また、型の後ろにconstを付けることも出来ます。

型 const 変数名 = 値;

この場合はconstは直前の型を定数にするという意味を持ちます。

このconstの書く位置と言うのは開発者によって異なっています。
前に付けたほうが美しいという人もいますし、後ろに付けたほうが意味が明確でいいという人もいます。
特にこだわりがなければ最初は型の前に付けるようにすればいいでしょう。

constを付けて整数を不変にする

普通の変数定義から見てみましょう。
たとえば整数の変数aは↓のように書きます。

    // 変数aは書き換え可能
    int a = 0;
    a = 1;

このint型の変数aにはconstが付いていないので、この変数は書き換え可能になっています。
ではconstを付けてこの変数を定数にして不変にしてみましょう。
↓のようなコードになります。

    // 変数aは書き換え不可能
    const int a = 0;
    a = 1;  // error: assignment of read-only variable 'a'

↑のように変数aconstをつけると、変数aは定数になります。
その結果、a = 1のように代入しようとするとgccでは「error: assignment of read-only variable 'a'」と言うエラーが出力されてコンパイルエラーになります。

constを付けて文字列を不変にする

constと馴染みが深いのがC言語の文字列です。
C言語では文字列は↓のように書くことが出来ます。

    char *s = "abc";

このような文字列を定数にしたい場合は↓のようにconstを付けます。

    const char *s = "abc";
    s[0] = 'A';  // error: assignment of read-only location '*s'

↑の場合、constcharにかかっています。
そのためcharへの代入がエラーになります。
しかしポインタにはconstはかかっていないため、ポインタ変数の値の変更はエラーになりません。

    const char *s = "abc";
    s = "def";  // ok

もしポインタの再代入も禁止にして、charの値の変更も禁止にしたいとなった場合は↓のようにconstを書きます。

    const char *const s = "abc";
    s = "def";  // error: assignment of read-only variable 's'

↑の1つ目のconstcharにかかっていて、2つ目のconst*にかかっています。
そのためポインタ変数の値の書き換えはエラーになります。
ここがconstの紛らわしい所なのですが、1つ目のconstはconstの後にかかりますが、それ以降のconstはconstの前にかかります。
ですので、この仕様を嫌って↓のようにconstを前にかかるように書く人も一定数います。

    char const *const s = "abc";
    s = "def";  // error: assignment of read-only variable 's'

↑のように書くと、constはいずれも「前」にかかるようになります。

C言語のconstをキャストで無理やり外す

C言語の変数についているconstは外すことができます。
具体的にはキャストで無理やり外します。

    const char *a = "abc";
    char *b = (char *) a;

↑の変数aにはconstがついていますが、(char *)というキャストで無理やりconstを外し、char *bに代入しています。
これはコンパイルエラーにもなりませんし、警告も出力されません。

constを外すのは危険?

このようなconstを無理やり外すキャストは一般的にはあまり好まれていません。
なぜかというと、constを無理やり外すケースと言うのは設計が破綻している場合が多いからです。

設計ミスとconstキャスト

プロジェクトの設計ミスによってこのようなconstを外すキャストはよく起こるようになります。
こういった傾向が出始めたら、設計を見直したほうが良いと言えるでしょう。

おわりに

今回はC言語のconst修飾について見てみました。
constを付けると変数を定数にすることができ、うっかりミスや事故を予防することが出来ます。
また設計にうまく組み込んでいくことで堅牢なアプリを作ることが可能になると言っていいでしょう。
const, ぜひマスターしておきたい修飾子ですね。

コンスタントにconstを使う

constをカンストする