
C言語のプログラムは、型(type)、演算子(operator)、式(expression)の三つを組み合わせて作られる。型は値の範囲や扱い方を決めるもので、整数型(integer)、浮動小数点型(floating point)、文字型(character)などがある。演算子は加算や比較といった処理を行う記号で、式はそれらをつなげて計算や判断を行う構成要素である。
変数(variable)や定数(constant)といったデータは必ず型を持ち、その型によって扱える値が決まる。例えば、整数型は小数を扱えず、浮動小数点型は広い範囲の数値を扱える。プログラムを正しく動かすためには、変数をどの型で宣言するかを意識することが欠かせない。
演算子は型と組み合わせて使うことで意味を持つ。足し算や引き算といった算術演算子(arithmetic operator)、大小を比較する関係演算子(relational operator)、条件分岐に使う論理演算子(logical operator)などがある。これらを活用することで、単純な計算だけでなく条件に応じた処理も実現できる。
式は変数や定数と演算子を組み合わせて新しい値を生み出す仕組みである。式が評価されることで、プログラムの中で実際の処理が進む。C言語を理解する第一歩は、この「型・演算子・式」の関係を正しく押さえることにある。
変数名・データ型・定数の基本
C言語では、プログラム中で使う値に変数名(variable name)を付けて扱う。変数名はアルファベット・数字・アンダースコアを組み合わせて作れるが、最初に数字は使えない。大文字と小文字は区別され、予約語(keyword)は使用できない。読みやすさのために、変数には小文字、定数には大文字を使う習慣がある。
int score; // 整数の変数
float height; // 浮動小数点の変数C言語の基本的なデータ型には、整数を扱うint(integer)、文字を扱うchar(character)、単精度の浮動小数点数を扱うfloat(floating point)、倍精度を扱うdouble(double precision floating point)がある。これらを基準にして、さらに修飾を加えることで幅を調整できる。
char c = 'A'; // 文字
int age = 25; // 整数
float pi = 3.14F; // 単精度浮動小数点
double e = 2.718; // 倍精度浮動小数点整数型には修飾子(type modifier)を付けられる。shortは小さい範囲、longは大きな範囲を扱う。signedは符号付き整数、unsignedは非負整数だけを扱う。環境に応じて最適な範囲やメモリを選べる。
unsigned int u = 100; // 非負の整数
long n = 1234567890L; // 大きな整数値を固定する場合は定数(constant)を使う。整数定数(integer constant)はそのまま数字で書き、Lを付ければlong型、Uを付ければunsigned型になる。小数を含む値は浮動小数点定数(floating constant)で、Fを付ければfloat、Lを付ければlong doubleを示す。
const int MAX = 100; // 変更できない整数
unsigned n = 42U; // unsigned型
float x = 1.23F; // float型
long double y = 4.56L; // long double型文字定数(character constant)はシングルクォートで囲んだ1文字で表す。例えば’A’は文字コードとして扱われる。文字列定数(string literal)はダブルクォートで囲んだ複数文字で、末尾に自動でヌル文字(’0’)が追加される。
char ch = 'A'; // 文字定数
char str[] = "Hello"; // 文字列定数(末尾に'0'が入る)宣言と初期化の仕組み
C言語では、変数や配列を使う前に宣言を行う。宣言では型(type)と名前(name)を指定し、プログラム中でどのように使うかを明示する。
int count; // 整数の変数
char line[100]; // 100文字を格納できる配列変数は初期化(initialization)によって最初の値を与えられる。宣言と同時に代入することで、未定義のまま使うリスクを避けられる。
int i = 0; // iを0で初期化
char c = 'A'; // cを文字'A'で初期化外部変数(external variable)や静的変数(static variable)は、初期化を省略しても自動的に0で初期化される。これに対して、自動変数(automatic variable)は明示的に初期化しなければ不定の値を持つ。
static int counter; // 自動的に0で初期化される
int temp; // 値は未定義(そのまま使うと危険)変更を禁止したい値にはconst修飾子(const qualifier)を付ける。これにより誤って値を書き換えることを防げる。関数の引数に使うと、安全性が高まる。
const double PI = 3.14; // 定数として使う
void print(const char *msg); // 関数内で文字列を書き換えられない算術・論理・ビット演算子の概要
C言語には多様な演算子があり、計算や条件分岐、低レベル操作に使われる。まず基本となるのが算術演算子である。
算術演算子
- +(加算 addition)
- -(減算 subtraction)
- *(乗算 multiplication)
- /(除算 division)
- %(剰余 remainder)
が含まれる。整数の除算では小数点以下が切り捨てられ、剰余演算子は整数にのみ使える。
次に、値の大小や等しさを比べる関係演算子(relational operator)と、条件分岐で使う論理演算子(logical operator)がある。
関係演算子
- >(より大きい greater than)
- <(より小さい less than)
- >=(以上 greater or equal)
- <=(以下 less or equal)
- ==(等しい equal)
- !=(等しくない not equal)
論理演算子
- &&(AND)
- ||(OR)
- !(NOT)
これらは条件を組み合わせて評価する。論理演算子は左から右に評価され、結果が決まった時点で処理を打ち切る「短絡評価(short-circuit evaluation)」が行われる。
さらに、ハードウェアに近い処理を可能にするのがビット演算子(bitwise operator)である。これは整数の各ビットを直接操作する。
ビット演算子
- &(AND)
- |(OR)
- ^(XOR)
- ~(NOT)
- <<(左シフト left shift)
- >>(右シフト right shift)
算術・論理・ビット演算子の活用と注意点
ビット演算子(bitwise operator)は整数の各ビットを直接操作する。例えば n & 0x7F と書くと、変数nの下位7ビットだけを取り出せる。これはマスク処理と呼ばれ、組み込み開発やフラグ管理でよく使われる。
int n = 0b11010110; // 2進数で11010110(214)
int masked = n & 0x7F; // 下位7ビットを取り出す → 86シフト演算子(shift operator)は数値を2の累乗で拡大縮小できる。左シフト<<は値を2倍にし、右シフト>>は2で割った効果になる。
int x = 5;
int y = x << 1; // 左シフトで10(5×2)
int z = x >> 1; // 右シフトで2 (5÷2の整数部分)算術演算子(arithmetic)、関係演算子(relational)、論理演算子(logical)、ビット演算子(bitwise)は組み合わせて使われることが多い。しかし、演算子には優先順位(precedence)があり、括弧を付けないと意図しない結果になることがある。
int a = 3, b = 5, c = 1;
int result = a & b == c; // 意図と異なる評価をする可能性あり
int safe = (a & b) == c; // 括弧を使い明確化ビット演算子と比較演算子の組み合わせは誤解を招きやすい。そのため、評価順序を明示するために括弧を積極的に使うことが安全である。
型変換とインクリメント・代入・条件式
C言語では、異なる型の値を混ぜて計算すると自動で型変換(type conversion)が行われる。整数と浮動小数点を組み合わせた計算では、整数が浮動小数点に変換される。これを暗黙の型変換(implicit conversion)と呼ぶ。明示的に型を変えたいときはキャスト(cast)を使う。
int n = (int)3.14; // 3が代入される(小数点以下切り捨て)
double d = 5; // 整数5が自動で5.0に変換される変数を1増減させる演算子としてインクリメント(increment)++とデクリメント(decrement)–がある。i++は後置(postfix)で値を返したあとに増える。++iは前置(prefix)で先に増やしてから値を返す。
int i = 5;
printf("%dn", i++); // 5を出力し、その後iは6になる
printf("%dn", ++i); // 7を出力(iが先に増えてから返される)代入には基本の=に加えて複合代入演算子(compound assignment operator)がある。+=、-=、*=、/=などを使えば、左辺の変数に右辺の計算結果を直接反映できる。
int x = 10;
x += 5; // x = x + 5 と同じ → xは15
x *= 2; // x = x * 2 と同じ → xは30条件に応じて値を選ぶときは条件演算子(conditional operator)?:を使う。書式は 式1 ? 式2 : 式3 である。
int a = 8, b = 12;
int max = (a > b) ? a : b; // bが大きいのでmaxは12if文より短く書けるため、単純な条件分岐に便利である。
型変換やこれらの演算子を理解すれば、C言語の式を簡潔に書けて、無駄のないコードにつながる。
演算子の優先順位と評価順序
C言語の演算子には優先順位(precedence)と結合規則(associativity)がある。優先順位はどの演算子を先に処理するかを決め、結合規則は同じ優先順位の演算子をどちらの方向から処理するかを決める。
int x = 2 + 3 * 4; // 掛け算が先に実行され、xは14になる演算子の結合規則には左から右(left to right)と右から左(right to left)がある。代入演算子=や条件演算子?:は右から左に結合する。算術演算子や関係演算子は左から右に結合する。
int a, b, c;
a = b = c = 5; // 右から左に結合するためすべての変数に5が代入される括弧を省略すると意図と異なる結果を招くため、複雑な式では括弧を積極的に使うとよい。
さらに注意が必要なのが評価順序(order of evaluation)である。C言語では、式の中で複数の演算子があるときにオペランドがどの順番で評価されるかが定義されていない場合がある。これを未定義動作(undefined behavior)という。
int i = 1;
i = i++ + ++i; // 未定義動作。処理系によって結果が変わるこのように副作用(side effect)を含む式を一行で書くと、動作が不明確になり予期せぬ結果を招く。安全のためには副作用のある処理を分けて書き、評価順序に依存しないようにすることが重要である。



