C言語のきほん|C言語のデータの基本

数字も文字も真偽も、まずは「入れ物」を知ることから。C言語のデータはイメージできると一気にわかる。

3章では、printf で表示したり、scanf で入力を受け取ったりしながら、C言語のプログラムを実際に動かしてきました。
その中で、年齢や月数のような値を扱いましたが、ここからはいよいよその正体をしっかり見ていきます。

C言語では、入力した値や計算結果をそのまま空中に置いておくことはできません。
値を保存しておくための入れ物が必要で、この入れ物を 変数 と呼びます。

そして、変数には「どんな種類の値を入れるか」というルールがあります。
このルールが データ型 です。

この章では、C言語のデータをイメージしながら、次の土台をしっかり作っていきます。

  • 変数とは何か(値の入れ物)
  • データ型とは何か(入れ物の種類)
  • 定数とは何か(固定の値)
  • 論理値型 bool の基本
  • 処理系依存という考え方
  • 浮動小数点の誤差で気をつけること

ここは、C言語を長く使っていくうえでとても大事な部分です。
最初は少し抽象的に感じるかもしれませんが、具体例を見ながら進めれば大丈夫です。
「値をどこにどう入れて、どう扱うか」という感覚を、ここでやさしく身につけていきましょう。

まずは「データ」と「変数」をイメージしよう

3章で作った scanf のプログラムでは、キーボードから入力した数値を表示に使いました。
あのとき、入力した数値はどこかに保存されていましたよね。そこが変数です。

変数のイメージ

変数は、よく「箱」や「入れ物」にたとえられます。

[ age ]            ← 年齢を入れる箱
[ study_months ]   ← 学習月数を入れる箱
[ target_age ]     ← 目標年齢を入れる箱

キーボードから 24 6 35 と入力したら、こんなイメージになります。

[ age ] = 24
[ study_months ] = 6
[ target_age ] = 35

このように、変数は値を一時的に保存して、あとで使うための入れ物です。

データ型は「入れ物の種類」

変数には、何でも自由に入れられるわけではありません。
C言語では、変数を作るときに「この箱にはどんな値を入れるのか」を決めます。これがデータ型です。

たとえばこんな分類

データの種類よく使う型の例
整数10, 25, -3int
小数3.14, 0.5double, float
文字A, xchar
真偽値true, falsebool

つまり、データ型は「箱のラベル」のようなものです。

  • int の箱には整数
  • double の箱には小数
  • bool の箱には真偽

というイメージで見ると分かりやすいです。

サンプルプログラム(データの基本イメージ)

「学習記録のデータ」を扱うシンプルなプログラム例です。

ファイル名:4_1_1.c

// 学習記録のデータを表示するプログラム
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int study_days = 12;          // 学習した日数(整数)
    int solved_count = 35;        // 解いた問題数(整数)
    double study_hours = 18.5;    // 学習時間(小数)
    bool completed = false;       // 目標達成したか(真偽値)

    printf("学習日数: %d日\n", study_days);
    printf("解いた問題数: %d問\n", solved_count);
    printf("学習時間: %.1f時間\n", study_hours);
    printf("目標達成: %d(0=false, 1=true)\n", completed);

    return 0;
}

このサンプルで見てほしいポイント

  • int は整数を入れている
  • double は小数を入れている
  • bool は true / false を入れている
  • 変数は「意味のある名前」で作ると読みやすい

この段階では、細かい表示形式よりも「型ごとに入れ物が違う」ことをつかめればOKです。

論理値型 bool を理解しよう

ここから、本文にもある 論理値型 を丁寧に見ていきます。
論理値型は、真か偽か を表すための型です。

論理値って何?

論理値は、次の2つだけを扱います。

  • true(真)
  • false(偽)

たとえば、こんな判断に使えます。

  • 合格したか → true / false
  • 入力チェックに成功したか → true / false
  • 処理を続けるか → true / false

bool型の特徴(整理)

項目内容
目的真偽を明確に表す
true または false
使う準備#include <stdbool.h> を書く
実体C言語の標準では _Bool(bool は別名)

本文のとおり、C言語の標準の論理型は _Bool です。
ただ、ふつうは stdbool.h をインクルードして bool を使うので、最初は _Bool を直接意識しなくて大丈夫です。

bool を使うために必要なもの

#include <stdbool.h>

これを書かないと、bool、true、false が使えません。

以前のC(C99以前)ではどうしていた?

本文にもあるように、昔は bool が標準でなかったため、int を使って真偽を表していました。

  • 0 → false
  • 0以外 → true

この考え方は今でもC言語の中で重要です。
bool を使っていても、内部的には 0 / 1 のような形で扱われることがあります。

論理値型のシンプルな例

bool を使う場面を、学習の文脈でシンプルに示すとこんな感じです。

ファイル名:4_1_2.c

// 学習目標の達成状態を表示するプログラム
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    bool is_goal_reached = true;   // 目標を達成したかどうか

    printf("目標達成フラグ: %d\n", is_goal_reached);

    return 0;
}

実行結果の見え方(例)

目標達成フラグ: 1

ここでは %d で表示しているので、true は 1、false は 0 として見えます。
このあたりは、まさに「論理値は 0 / 0以外 の考え方とつながっている」部分です。

処理系依存とは何か(とても大事)

本文にある「処理系依存」は、最初は少し難しく感じやすい言葉ですが、意味はシンプルです。

使う環境によって、動作や結果が変わることがある
これが処理系依存です。

ここでいう環境には、たとえば次のようなものが含まれます。

  • コンパイラ(GCC、Visual C++ など)
  • OS(Windows、Linux など)
  • CPUや実行環境

なぜ起こるの?

C言語には標準規格がありますが、すべてを完全に固定しているわけではありません。
一部は「環境に任せる」部分があるため、違いが出ます。

本文にある代表例(整理)

項目何が変わることがある?
データ型のサイズint のバイト数など環境によって 2/4 バイトなど
char の扱い符号あり/なし処理系で異なることがある
文字コード日本語の扱いShift_JIS / UTF-8
ライブラリ関数の挙動細かい仕様や品質rand の性質など

初心者のうちは、まず「環境で違いが出ることがあるんだな」と知っておけば十分です。
この意識があるだけで、将来のトラブル対応がかなり楽になります。

処理系依存への対処法(実践的に)

本文にある対策を、学習しやすい形で整理しておきます。

➀ 標準ライブラリを活用する

自分で環境依存の処理を書かずに、標準ライブラリ関数を使うと安全性が上がります。

たとえば本文にある isalnum のような関数は、文字コードの細かい違いを意識しすぎずに使いやすいです。

➁ サイズが明確な整数型を使う

環境差を減らしたいときは、int よりも幅が決まった整数型が便利です。

  • uint32_t
  • int32_t
  • uint8_t

など(後の章で詳しく学ぶ内容ですね)。

➂ コンパイラや環境のドキュメントを見る

「この環境ではどうなっているか」を確認したいときは、マニュアルがいちばん確実です。
実務ではかなり重要になります。

いまの段階での向き合い方

初心者のうちは、処理系依存を全部覚える必要はありません。
でも、次のひとことは覚えておくと良いです。

同じC言語でも、環境が違うと少し挙動が変わることがある

これだけでも十分価値があります。

浮動小数点型で起きる誤差の話(とても重要)

本文の「注意ポイント」にある内容は、C言語だけでなく、コンピュータ全般で大事なテーマです。

小数(浮動小数点数)は、見た目どおりに計算できそうに見えますが、実は誤差が出ることがあります。

まず知っておきたいこと

浮動小数点の計算結果は、いつも厳密とは限らない

これがいちばん大事なポイントです。

なぜ誤差が出るの?

コンピュータは、数を有限のビット数で保存します。
そのため、小数の中には「ぴったり表せないもの」があります。

本文の例のように、10進数の 0.2 は 2進数にすると循環小数になります。
つまり、メモリ上では近い値に丸めて保存するしかありません。

この「丸め」が、誤差の原因になります。

浮動小数点でよく出る誤差の種類

丸め誤差

保存できる桁数に限界があるので、最も近い値に丸めることで起きる誤差です。

桁落ち

ほぼ同じ値どうしを引き算すると、有効な桁が失われて精度が悪くなる現象です。

情報落ち

とても大きな値と、とても小さな値を足し引きすると、小さい値の影響が消えてしまう現象です。

表で整理

用語どんなときに起きる?イメージ
丸め誤差表現できない小数を保存近い値に丸める
桁落ち近い値どうしの減算有効桁が減る
情報落ち大小差が大きい加減算小さい値が埋もれる

このあたりは今すぐ計算テクニックまで覚えなくて大丈夫です。
まずは「小数は誤差が出る前提で扱う」という感覚を持つことが大切です。

float と double と long double の考え方

本文にもあるように、float より double、double より long double の方が、一般には精度が高いです(処理系依存の部分はあります)。

ざっくりした使い分けの感覚

特徴(ざっくり)
float軽いが精度は低め
double標準的で使いやすい
long doubleより高精度(環境差あり)

ただし、精度が高くなっても 誤差がゼロになるわけではありません
ここがとても大事です。

小数の誤差を意識する簡単な例(学習用)

コメント付きで、イメージをつかむためのシンプルな例を載せておきます。

ファイル名:4_1_3.c

// 浮動小数点の計算を確認するプログラム
#include <stdio.h>

int main(void)
{
    double a = 0.2;   // 小数
    double b = 0.1;   // 小数
    double sum = a + b;

    printf("a + b = %.17f\n", sum);

    return 0;
}

環境によって表示は少し異なりますが、見た目どおりの 0.3 ぴったりではない表示になることがあります。
これが「誤差がありうる」という具体例です。

ここまでの内容をつなげて理解しよう

4章の入口として、今の段階では次の流れが見えていればとても良いです。

学習のつながり

  • 3章:printf と scanf を使って入出力を体験した
  • 4章:そのとき使っていた値の正体(型・変数・定数)を理解する
  • 今後:型の違いを意識して、より正確で安全なコードを書く

つまり、4章は「今まで触っていたものの意味を言葉で整理する章」です。
ここを押さえると、これからの学習で出てくる変数宣言や計算、条件分岐がすごく理解しやすくなります。

まとめ

このパートでは、「C言語のデータの基本」の入口として、変数・型・論理値・処理系依存・浮動小数点の誤差について整理しました。

  • 変数は値を保存する入れ物
  • データ型は入れ物の種類
  • bool は true / false を表す型(stdbool.h が必要)
  • C言語には処理系依存の部分がある
  • 浮動小数点は誤差を含むことがある

最初は少し情報量が多く感じるかもしれませんが、全部を一度に完璧に覚えなくて大丈夫です。
大事なのは、値には種類があり、入れ物にもルールがある という感覚を持つことです。

ここがつかめると、この先の変数・定数・演算の学習がぐっとスムーズになります。