C言語でコードを書いている際、単純な値の代入において if-else 文が冗長だと感じたことはありませんか。
そのような場面でコードを圧倒的にスッキリさせてくれるのが「三項演算子」です。
記述を短縮できる便利な機能ですが、一方で開発現場では「コードが読みづらくなるから使うな」「禁止すべき」といった議論が交わされることもある、取り扱いに注意が必要な構文でもあります。
この記事では、三項演算子の基本的な書き方から、サジェストキーワードでも注目されている「マクロ」での活用、複数連結(ネスト)する際の書き方、そしてPythonやC#との違いまで、現場で即戦力となる知識を詳しく解説します。
![]() 執筆者:マヒロ |
|
- OS:Windows 11 / macOS Sequoia
- IDE:Visual Studio / VS Code / IntelliJ IDEA
- その他:Chrome DevTools / 各言語最新安定版
※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。
三項演算子の基本構文と使い方
三項演算子は、条件式の真偽に応じて、2つの値のうちどちらか一方を返すという働きをします。
まずはその基本構造を理解しましょう。
基本的な書き方
(条件式) ? 式1 : 式2;
条件式が「真(0以外)」であれば「式1」が評価され、その値が返されます。反対に「偽(0)」であれば「式2」が評価されます。
具体的なサンプルコードで動作を確認してみましょう。
#include <stdio.h>
int main(void) {
int score = 85;
// スコアが80以上なら1(合格)、それ以外は0(不合格)
int is_passed = (score >= 80) ? 1 : 0;
printf("結果: %s\n", is_passed ? "合格" : "不合格");
return 0;
}
実行結果
結果: 合格
まず、int is_passed = (score >= 80) ? 1 : 0; の部分に注目してください。
ここでは score が 80 以上かどうかを判定しています。
今回の例では 85 ですので条件は真となり、コロンの左側にある 1 が変数 is_passed に代入されました。
続く printf の引数内でも三項演算子を直接使用しています。
is_passed が 1 であれば文字列の “合格” を、そうでなければ “不合格” を選択して表示させています。
このように、値を代入する際や関数の引数の中で条件に応じて値を切り替えたい場合に非常に強力な武器となります。
二項演算子との違いと他言語(Python/C#)との比較
プログラミングにおける演算子には、項の数に応じた分類があります。
C言語の多くは「二項演算子」ですが、三項演算子ならではの立ち位置を整理します。
二項演算子と三項演算子の区別
C言語でよく使われる算術演算子(+, -)や比較演算子(==, >)は、演算子の左右に2つの値を必要とするため「二項演算子」と呼ばれます。
それに対して、今回の条件演算子だけが、条件・真の場合の値・偽の場合の値という3つの要素をセットで扱うため、通称として「三項演算子」という名前が定着しています。
Python や C# の三項演算子との違い
他の主要な言語でも三項演算子の概念は存在しますが、書き方が異なる場合があります。
たとえばC#の場合は、C言語と全く同じ記法(? :)を採用しているため、C言語の知識がそのまま通用します。
一方でPythonは書き方が大きく異なり、式1 if 条件 else 式2 という「if」を中央に置く構文を用います。
C言語やC#では記号を使うため数学的・パズル的な印象を与えますが、Pythonでは英語の語順に近い形式をとるため、各言語の設計思想の違いが現れている興味深いポイントといえるでしょう。
三項演算子を使った「マクロ」の定義
C言語のプリプロセッサ機能である「マクロ」と三項演算子は非常に相性が良く、古くからシステム開発の現場で組み合わせて利用されてきました。
マクロでの活用例(最大値・最小値の取得)
特定の処理を高速に行うために、三項演算子を埋め込んだマクロを定義する手法を紹介します。
#include <stdio.h>
// 2つの値のうち、大きい方を返すマクロ
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main(void) {
int x = 10, y = 20;
int max_val = MAX(x, y);
printf("大きい方の値は %d です\n", max_val);
return 0;
}
実行結果
大きい方の値は 20 です
#define MAX(a, b) という定義によって、プログラム内の MAX(x, y) はコンパイルの直前に ((x) > (y) ? (x) : (y)) というコードに置き換わります。
関数を呼び出すオーバーヘッドを避けるために、このようなシンプルな比較処理には三項演算子マクロが適しています。
ただし、マクロ内で三項演算子を使用する際には、すべての引数や全体を必ず括弧 () で囲むことが不可欠です。
これを怠ると、演算子の優先順位の問題によって、意図しない計算結果が導き出されてしまうバグの温床となります。
C言語の安全なコーディング規約において非常に重要なルールです。
複数の条件を連結する(三項演算子のネスト)
三項演算子の「式」の部分に、さらに別の三項演算子を組み込むことで、複数の条件分岐を一行で記述することが可能です。
複数条件のサンプルコード
#include <stdio.h>
int main(void) {
int val = 0;
// 正の数なら1、負の数なら-1、0なら0を返す
int sign = (val > 0) ? 1 :
(val < 0) ? -1 : 0;
printf("符号判定: %d\n", sign);
return 0;
}
実行結果
符号判定: 0
まず (val > 0) という最初の条件をチェックします。
もしこれが偽であれば、次にコロンの右側にある (val < 0) ? -1 : 0 という「2つ目の三項演算子」の評価へと進みます。
このように三項演算子を複数連結することで、if-else if-else 構造と同じ処理を実現できます。
しかし、三つ以上の連結はコードの可読性を著しく損なうため、多くの開発現場では「二段階まで」といったルールが設けられていることも珍しくありません。
なぜ「使うな」「禁止」と言われるのか?可読性の問題
三項演算子について調べると、「三項演算子 使うな」や「三項演算子 禁止」という過激な言葉を目にすることがあるでしょう。
これには明確な技術的理由があります。
可読性と保守性への影響
三項演算子を不適切に使用すると、プログラムの意図を読み取るのが困難になります。
特に、前述した連結(ネスト)が複雑になったり、副作用のある関数を三項演算子の中で呼び出したりすると、後からコードを読む開発者にとって大きな負担となります。
C言語のMISRA-Cなどの厳格なコーディング規格では、条件演算子の使用そのものを制限している場合があります。
これは、ミスを未然に防ぎ、誰が読んでも同じ理解ができるコードを維持するための方針です。
「短く書けるから」という理由だけで乱用するのではなく、「一目で処理が理解できるか」という視点を持つことが、プロフェッショナルなC言語エンジニアには求められます。
GNU拡張:三項演算子の省略形(?:)
標準のC言語仕様ではありませんが、GCC(GNU Compiler Collection)などの主要なコンパイラでは、三項演算子の「真の場合の値」を省略できる便利な拡張機能が備わっています。
省略形の書き方
x = a ?: b;
この記述は x = a ? a : b; とほぼ同じ意味になりますが、変数 a の評価が一度だけで済むという利点があります。
もし a が真として評価可能な値であれば a 自身が返され、そうでなければ b が選ばれます。
Web系の言語(PHPなど)のエルビス演算子に近い挙動ですが、あくまでコンパイラ独自の拡張機能であるため、異なる環境でも動かす必要があるポータブルなプログラムにおいては、標準的な書き方を維持する方が賢明です。
C言語のスキルを活かして年収を上げる方法
以上、C言語での三項演算子の書き方について解説してきました。
C言語を扱えるエンジニアは比較的希少価値が高く、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。
なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。
転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。
| 年収アップにこだわりたい方 (平均アップ額138万円の実績) | テックゴー |
| 未経験・経験者問わず幅広く探したい方 | ユニゾンキャリア |
| 業界に精通した担当者に相談したい方 | キッカケエージェント |
| ゲーム業界への転職を志望する方 | ファミキャリ |
| エンジニア未経験からキャリアを築く方 | イーチキャリア |



