C言語学習ポータル(無料版) 学習コンテンツ 変数・型・演算子 定数——const と constexpr

📦 変数・型・演算子

定数——const と constexpr

無料公開版に収録・読む目安 11分

🎯 constとconstexpr(C23)を使い分け、変わらない値を宣言時に固定できる

プログラムには「絶対に変わってほしくない値」があります。消費税率、円周率、1週間の日数。これを普通の変数にしておくと、どこかで書き換わっても気づけません。値に鍵をかけるのがconstです。

const——書き換え禁止の箱

#include <stdio.h>

int main(void) {
    const double ZEIRITSU = 1.10;
    int honntai = 1200;

    printf("税込 %.0f 円\n", honntai * ZEIRITSU);
    // ZEIRITSU = 1.08;   // ここを有効にするとコンパイルエラー
    return 0;
}

const を付けた変数は、初期化のときにだけ値を持てます。あとから代入しようとすると、コンパイルの時点でエラーになって止まります。実行してから気づくはずだったバグが、書いた時点で防げるわけです。

定数名は大文字で書く習慣があります。読む人に「これは変わらない」と一目で伝わります。

constexpr——C23の「コンパイル時に決まる定数」

#include <stdio.h>

int main(void) {
    constexpr int TSUKI = 12;
    constexpr int NENKAN = 365;
    constexpr int HEIKIN = NENKAN / TSUKI;

    printf("1か月あたり約 %d 日\n", HEIKIN);
    return 0;
}

constexprはC23で入った書き方で、「この値はコンパイルの時点で確定している」という宣言です。const との違いは、コンパイラが値そのものを知っていること。そのおかげで、配列の要素数(トラック8)のような「コンパイル時に決まっていなければならない場所」でも使えます。

#define との違い

#include <stdio.h>
#define ZEI_A 1.10                  // 単なる文字の置き換え。型が無い

int main(void) {
    const double ZEI_B = 1.10;      // 型のある定数
    constexpr double ZEI_C = 1.10;  // 型があり、コンパイル時に確定

    printf("%.2f %.2f %.2f\n", ZEI_A, ZEI_B, ZEI_C);
    return 0;
}

#define はコンパイル前に文字を機械的に置き換えるだけの指示です(トラック16で詳しくやります)。型のチェックが効かず、エラーメッセージも読みにくくなります。C23ではまず constexpr、次に const、#define は最後の手段と考えておけば十分です。

師範変わらぬと分かっているものに、先に鍵をかけておく。それだけで、後日の下手人探しが半日減るのじゃ。

罠・注意

const は宣言と同時に初期化する。 const int N; N = 5; はエラーです。鍵をかけてから中身を入れることはできません。

constexpr の右辺は定数式だけ。 scanf で読んだ値のように、実行時にしか決まらないものは入れられません。

古い環境では constexpr が通らない。 C23対応のコンパイラが必要です(gcc 13以降など)。通らない環境では const で代用します。

まとめ

const は書き換え禁止の変数、constexpr(C23)はコンパイル時に値が確定する定数です。どちらも「変わらないもの」を宣言時に明示して、事故を書いた時点で止めるための道具。型のない #define より、型のある定数を優先します。

要点まとめ

アプリで演習問題まで解く(無料・登録不要)

この項目に出てくる用語

constこんすと

一度値を入れたら変更できないようにする修飾子のこと。うっかり書き換えてしまうミスをコンパイラの側で防いでくれる働きを持つ。定数として扱いたい値には積極的に付けておくと安全性が高まる。

constexprこんすとえくすぷれっしょん

コンパイル時に値が確定する定数を宣言するC23のキーワードのこと。従来のマクロ定数より型安全で、デバッグ情報も残るという利点がある。#defineによるマクロ定数の、より安全な後継として位置づけられている。

型かた

変数に入れられる値の種類と、確保するメモリの大きさを決める分類のこと。箱の形や大きさを決めるルールのようなものだと考えるとよい。int・double・charなど、C言語にはあらかじめ複数の型が用意されている。

コンパイルこんぱいる

ソースコードをコンピュータが直接実行できる機械語に変換する作業。翻訳者が人間の言葉を機械の言葉に訳してくれる工程だとイメージすると分かりやすい。この工程を経なければ、書いたコードはコンピュータの上でまったく動かせない。

同じトラックのほかの項目

変数とは名前付きの箱宣言・代入・初期化を区別し、型のついた変数を正しく作って使える int型と整数の世界intの範囲と限界値の調べ方を知り、long long・unsignedの使いどころが分かる 浮動小数点数 float / doubledoubleを既定として使い分け、小数に必ず誤差があることと比較の作法を理解する char型と文字コードcharが1バイトの小さな整数であることを理解し、文字と数値を相互に変換できる bool型と真偽——C23標準の書き方C23のbool/true/falseをそのまま使い、Cにおける真偽(0が偽・0以外が真)を説明できる 算術演算子と優先順位5つの算術演算子と優先順位を理解し、複合代入・インクリメントを正しく使える 整数の割り算と剰余の罠整数どうしの割り算が切り捨てになる理由を理解し、平均計算などで正しく対処できる 型変換——暗黙と明示暗黙の型変換が起きる方向を知り、キャストで意図を明示できる 2進数・16進数リテラル(0b / 0x / 桁区切り')0b・0x・8進の書き方の違いを理解し、C23の桁区切りで読みやすく数値を書ける sizeofとメモリ上のサイズsizeofで型と変数のバイト数を測り、型ごとに箱の大きさが違うことを実感できる オーバーフローという事件オーバーフローが起きる仕組みと危険性を理解し、桁の見積もりと予防策を実行できる
‹ bool型と真偽——C23標準の書き方 算術演算子と優先順位 ›

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版(BOOTH)を見る

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版 / BOOTH