C言語入門|構造体に使える演算子・使えない演算子

構造体を使い始めると、こんなことを考えたくなりませんか?

  • 数値が入ってるんだから、足せるんじゃない?
  • 中身が同じかどうか、== で比べたい!
  • まとめてコピーできたら楽なのに

気持ちはとってもよく分かります 😊
でも、構造体は 基本型とはまったく違うルール で扱われます。

ここでは、
構造体に使える演算子・使えない演算子 を整理しながら、
「なぜそうなっているのか」までしっかり解説していきます。

構造体は「値」ではなく「データの集合」

まず大前提として、構造体は

複数の値をひとまとめにしたデータの集合

です。

たとえば次のような構造体を考えてみましょう。

typedef struct {
    int x;
    int y;
} Position;

Position 型の変数は、

  • x 座標
  • y 座標

という 2つの値を同時に持つ箱 です。

この時点で、
「int と同じようには扱えなさそうだな」
という気配がしますよね。

構造体に算術演算子は使えない

ではまず、計算について見てみましょう。

やりたくなるコード

Position p = {10, 20};
p++;   // xもyも1ずつ増やしたい!

人間が読むと、

  • x を 11
  • y を 21

にしたいのだな、とすぐ分かります。

しかし、これは コンパイルエラー になります ❌

なぜ + や ++ が使えないのか

算術演算子(+, -, ++ など)は、

  • 1つの値
  • 明確な計算ルール

を前提に作られています。

ところが構造体の場合、

  • x だけ増やす?
  • y だけ?
  • 両方?
  • 比率は?

と、判断の余地が多すぎる のです。

C言語は、

曖昧なことは一切しない

という設計思想を持っています。

そのため、

  • 構造体に対する算術演算子は使えない

というルールが採用されています。

正しい計算方法:メンバごとに操作する

構造体を計算したい場合は、
メンバを1つずつ操作します。

p.x++;
p.y++;

少し手間ですが、

  • 何をどうしたいのかが明確
  • バグが入りにくい

という大きなメリットがあります 😊

構造体は比較演算子も使えない

次によくやりたくなるのが、比較です。

やってしまいがちなコード

Position a = {10, 20};
Position b = {10, 20};

if (a == b) {
    printf("同じ位置です\n");
}

これも残念ながら コンパイルエラー になります ❌

なぜ == や > が使えないのか

== 演算子は、

  • 左と右の値が等しいか

を調べる演算子です。

しかし構造体の場合、

  • x が同じならOK?
  • y も同じ必要がある?
  • 両方同じときだけ?

といった 比較ルールを自動で決められません

そのため、C言語では

  • 構造体同士の比較は禁止

となっています。

構造体を比較したいときの正しい方法

比較したい場合も、
すべてのメンバを1つずつ比較します。

if (a.x == b.x && a.y == b.y) {
    printf("同じ位置です\n");
}

少しコードは長くなりますが、

  • 比較条件がはっきりする
  • 読んだ人にも意図が伝わる

という利点があります。

唯一の例外:構造体の代入(コピー)

ここまで読むと、

「じゃあ構造体って何もできないじゃん…」

と思うかもしれませんが、
1つだけ特別な演算子 があります。

それが 代入演算子 = です。

構造体は丸ごとコピーできる

Position p1 = {5, 8};
Position p2;

p2 = p1;   // OK

この1行で、

  • x
  • y

すべてのメンバがコピーされます。

文字列メンバがあっても問題ない理由

「でも、中に文字列配列があったら危なくない?」

と心配になるのは、とても良い着眼点です 👍

構造体の代入は、

  • メンバごとの代入
  • 文字列代入

ではなく、

メモリ領域そのものを丸ごとコピー

する特別な動作になっています。

そのため、

  • 文字列型メンバを含んでいてもOK
  • 第3の約束(文字列代入禁止)には違反しない

という扱いになります。

構造体と演算子の関係まとめ

ここまでの内容を、表で整理しておきましょう。

演算子の種類使用可否理由
算術演算子 + - ++×計算ルールが定義できない。
比較演算子 == >×比較基準を自動判断できない。
代入演算子 =丸ごとコピーできるため

構造体は「箱」、演算は「中身」

構造体を扱うときは、次の感覚がとても大切です。

  • 構造体そのもの → 操作できない。
  • 構造体のメンバ → 操作できる。

つまり、

箱は触れない
中身を取り出して操作する

という考え方です 😊

この感覚が身につくと、
構造体で迷うことが一気に減ります。

ここまで理解できれば、
構造体と演算子の関係はもう完璧です 👍

次は、

  • 構造体を関数に渡す。
  • 構造体配列
  • ポインタと構造体

へ進むと、実践力が一気に伸びますよ 😊