1. 変数とは?

この記事では、当社の新人エンジニア研修の参考にC#を解説します。

前回は「C#を初めて学ぶ新人社員の皆さんへ」ということでC#学習のコツをお話しました。

今回は、変数データ型について解説します。

変数は「データに付ける名前(ニックネーム)」だと考えてください。変数を使うことで、データの再利用や演算が容易になります。

プログラミングに限らず、「名前」という仕組みがないと非常に不便ですよね。現実でも、「クリスマスイブの日に橋の下に捨てられていた白い犬」を毎回その長い呼び名で呼ぶのではなく、「三太」と名前をつければ簡単に指し示すことができます。これが変数の役割とよく似ています。

設計において、適切な名前をつけられるかどうかは非常に重要な要素
(Ruby開発者:まつもとゆきひろ 〜「プログラマが知るべき97のこと」より)

コンピュータの本質は「計算機」です。計算機はデータを処理するため、一時的にデータを保管する場所が必要です。その場所に「名前」を付けて扱いやすくしたものが変数です。

例えば、メインメモリ上のアドレスをそのまま使うのは人間には分かりにくいです。そこで、「わかりやすい名前(変数名)」を付けてあげることで、プログラム中で扱いやすくしています。

変数を「引っ越しの荷物を入れるダンボール箱」になぞらえることがあります。
ダンボール箱にラベルがないと、中身が何か分からず困ります。同様に、変数にも「何を入れるか」の名前付けが重要なのです。

新人エンジニア
変数のイメージは箱

また、箱ごとに「食器用」「電化製品用」のように用途を決めておけば混乱しません。同様に、変数に何を入れるかをあらかじめ決めるのがデータ型です。データ型を決めることで、間違ったデータ操作を防ぎます。

  • 例:
    • 2 + 35 という数値演算
    • "Hello " + "World""Hello World" という文字列結合
    • 数値同士であれば加減乗除が可能ですが、文字列との演算は結果が異なる、もしくは意味をなさない場合もある

C#でも整数値や文字列、真偽値など様々な型を扱い、また自分たちで作る型(クラス)も登場します。データ型を理解することは、C#を使いこなすうえで欠かせません。

「変数(Variable)」の「変わる」という言葉通り、プログラム中で値が変化する可能性があります。それに対して、変化しない(変えられない)ものを「定数(Constant)」と呼びます。ここではまず変数を、続いて定数を学んでみましょう。

2. 変数の基本

以下のサンプルプログラムでは、型の異なる4つの変数を宣言し、それぞれの値をコンソールに出力します。

using System;

public class Example05
{
    public static void Main(string[] args)
    {
        int data1 = 1;
        double data2 = 1.0;
        bool flag = false;
        char c = 'C';

        Console.WriteLine(data1);
        Console.WriteLine(data2);
        Console.WriteLine(flag);
        Console.WriteLine(c);
    }
}

<結果>

1
1.0
False
C

C#のプログラムは「上から下へ」順次実行されます。
  1. 変数を 宣言 する:int data3;
  2. 値を 代入 する:data3 = 10;
  3. 宣言と代入を一行で書く:int data3 = 10;
  4. 変数を使う(参照 する):Console.WriteLine(data3);

誤りが多いのは、Console.WriteLine("data3") のように、変数名を文字列リテラルで書いてしまうことです。そうすると、画面出力は "data3" という文字列そのものになります。

実験

「もし、文字列を渡すと実行結果はどうなるか?」

Console.WriteLine("data1");

また、他の変数の値を代入することもできます。

int data4 = data3;

そして、演算の結果を代入することもできます。

data4 = data3 + 1;

変数に新しい値を代入すると、もともと入っていた値は上書きされます。

data3 = data3 + 1;

例題

例題

実行結果はどうなるでしょう? その理由は?

int a = 1;
int b = a;
a = 2;
Console.WriteLine(a + ":" + b);

ローカル変数

今回紹介した変数はローカル変数です。メソッド内の { } ブロックの範囲だけで有効となります。
また、C#ではローカル変数を初期化しないまま使おうとするとコンパイルエラーになります。

int data1;
Console.WriteLine(data1); // ← ここで使おうとするとエラー

「変数は初期化してから使う」というのが原則です。

直接記述される定数値のことを「リテラル」と呼びます。例えば 1, 1.0, false, 'C' はすべてリテラルです。

3. 変数の宣言

C#では、変数を宣言するときに「型」を先に書きます。これは静的型付け言語の特徴です。

型名 変数名;


  • C#での「名前(変数・メソッド・クラスなど)」を識別子と呼びます。
  • 識別子には、英字と数字、アンダースコア _ などが使えますが、先頭を数字にしてはいけません。

たとえば、int 1stNumber; のような宣言はできませんし、C#にも予約語があり、それらを変数名には使えません。

int int = 0; // これはエラー

このような宣言ができてしまうと、int が型なのか変数なのか区別がつかなくなるため禁止されています。

予約語とリテラル

C#にもたくさんの予約語public, class, if, staticなど)やリテラル(true, false, null など)があります。Visual StudioやVS CodeなどのIDEで色分けされるので、それを目安にしてください。

実験:同じ変数名を2回宣言してみる

int data1 = 10;
int data1 = 20; // 再度宣言するとどうなるか?

→ 「変数が重複している」エラーが出るはずです。エラーメッセージをメモしておきましょう。

実験:変数の参照と宣言の順番を逆にしてみる

Console.WriteLine(data1);
int data1 = 10;

→ 変数が見つからない旨のエラーが出るでしょう。「基本は上から下に処理する」からです。

静的型付けと動的型付け言語

C#は変数の宣言時に変数の型を明示します。これを静的型付けといいます。一方、動的型付けといって宣言時に変数の型を明示しない言語もたくさん存在します。

静的型付けの言語の代表例は、C#を始めJava、C++、などがあります。

一方動的型付けの言語の代表例は、Python、JavaScript、Ruby、PHPなどです。

どちらも一長一短がありますが、最初に学ぶ言語としては、コンパイル時に型エラーを検出しやすい静的型付け言語がバグを減らせる分だけ勉強しやすい、という考え方もあります。

4. C#で使用できる主な組み込み型

C#では下記の組み込み型があります。

ビット幅値の範囲・内容
booltrue または false
byte8ビット符号なし(※) / 符号あり sbyte が別にある
char16ビットUnicode 文字 (U+0000 ~ U+FFFF)
short16ビット-32768 ~ 32767
int32ビット-2,147,483,648 ~ 2,147,483,647
long64ビット-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
float32ビット単精度浮動小数点数(-3.4×10^38~3.4×10^38 など)
double64ビット倍精度浮動小数点数(±5×10^-324~±1.7×10^308 など)
decimal128ビット高精度(財務計算などで使用)

メモリ上の表現

  1. int の 1 はメモリ上で「32ビットの2進数」で表される
  2. double の 1.0 はまた別の2進数表現

「同じ 1 でも、整数の1と実数の1.0 はメモリ上のビットパターンが異なる」ということが「型変換(キャスト)」で重要になってきます。

5. なぜ、変数を使うのか?

変数を使う理由を一言で言うと、「データに意味を与え、使い回し、変更ができる」からです。

以下のExample06は、あなたが現在22歳だとして、将来の年齢をコンソールに表示するプログラムです。

using System;

public class Example06
{
    public static void Main(string[] args)
    {
        int yourAge = 22;

        Console.WriteLine("あなたは今" + yourAge + "才です");
        Console.WriteLine("あなたは10年後" + (yourAge + 10) + "才です");
        Console.WriteLine("あなたは20年後" + (yourAge + 20) + "才です");
        Console.WriteLine("あなたは30年後" + (yourAge + 30) + "才です");
        Console.WriteLine("あなたは40年後" + (yourAge + 40) + "才です");
        Console.WriteLine("あなたは50年後" + (yourAge + 50) + "才です");
    }
}

<結果>

あなたは今22才です
あなたは10年後32才です
あなたは20年後42才です
あなたは30年後52才です
あなたは40年後62才です
あなたは50年後72才です
  1. yourAge という「年齢」だと分かりやすい名前が付いています。これが数値 22 のままだと「何を表す数字か?」が不明瞭です。
  2. 年齢が1歳増えた場合は、単に yourAge = 23 と書き換えれば良いですね。

このように、変数を使うことでデータの意味付け、使い回し、変更が容易になります。

新人エンジニア
キャメルケース

変数名における キャメルケース (camelCase) : yourAge, myFriendName など
C#のローカル変数では小文字始まりが一般的です(ただし意見は分かれる場合あり)。

6. 定数を使うとき

変数は後から値が変わる可能性があります。それに対して「後から変更できない」ものを定数と言います。C#ではconstキーワードを使います。英語の【constant(定数)】の省略形です。

public class Example07
{
    public static void Main(string[] args)
    {
        const int ADULT_AGE = 20;
        // ADULT_AGE = 18;  // ← これはコンパイルエラー: 値を変更できない
    }
}

定数は宣言時に初期化する必要があり、以降の再代入はできません。

public class Example08
{
    public static void Main(string[] args)
    {
        const int ADULT_AGE = 18;

        Console.WriteLine("成人年齢は" + ADULT_AGE + "才です");
        Console.WriteLine("今年の成人は10年後" + (ADULT_AGE + 10) + "才です");
        Console.WriteLine("今年の成人は20年後" + (ADULT_AGE + 20) + "才です");
        Console.WriteLine("今年の成人は30年後" + (ADULT_AGE + 30) + "才です");
        Console.WriteLine("今年の成人は40年後" + (ADULT_AGE + 40) + "才です");
        Console.WriteLine("今年の成人は50年後" + (ADULT_AGE + 50) + "才です");
    }
}



<結果>

成人年齢は18才です
今年の成人は10年後28才です
今年の成人は20年後38才です
今年の成人は30年後48才です
今年の成人は40年後58才です
今年の成人は50年後68才です


新人エンジニア
スネークケース

定数は全大文字+アンダースコアというスネークケースがよく使われます。

7. char型は整数のように扱える?

次のExample09を見てください。

public class Example09
{
    public static void Main(string[] args)
    {
        char a = 'A';
        a += (char)32;
        Console.WriteLine(a);
    }
}

<結果>

a

C#のchar型は内部的には「文字コード(16ビットの数値)」として扱われます。 'A' のコードに 32 を足すと 'a' になるわけです。(ASCIIテーブルなどを参照)
文字の大小変換や暗号化などで、charを数値的に操作するテクニックが使われる場合があります。

8. クラスはnamespaceを使って管理する

C#では「namespace」を使いクラスを整理します。

今までのサンプルのようにすべてデフォルト名前空間(namespaceなし)ですと、クラスが増えると整理がしにくくなります。現場ではnamespaceを使ってソースコードを分類します。

namespace Chap02
{
    public class Example01
    {
        public static void Main(string[] args)
        {
            char a = 'A';
            a += (char)32;
            Console.WriteLine(a);
        }
    }
}

このように記述することで「Chap02」という名前空間配下にExample01クラスが属することになります。同じソリューション(プロジェクト)内でクラス名の衝突を防ぐ効果もあります。

9. 別のnamespaceにあるクラスを呼び出して使用する

別のnamespaceにあるクラスを呼び出して使用してみましょう。以下のプログラムでは、C#の日時クラス System.DateTimeを“フルネーム”で使用しています。

namespace Chap02
{
    public class Example02
    {
        public static void Main(string[] args)
        {
            // 完全修飾名で呼び出し
            Console.WriteLine(System.DateTime.Now);
        }
    }
}

<結果>

2025/02/18 16:45:55

(表示形式はPCのロケールや設定によります)

さらに、using System; と書いておけば、単に DateTime.Now と書けます。

using System;

namespace Chap02
{
    public class Example03
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now);
        }
    }
}

ただし誤解しがちですが、using は「クラスを読み込む」わけではなく「名前空間を省略できる」ようにする仕組みです。

using System;
using System.Text;
// など

と書いておくと、その名前空間配下のクラスを完全修飾名なしで呼び出せるようになります。

using System.Text;StringBuilder クラスを StringBuilder sb = new StringBuilder(); のようにシンプルに書ける

<まとめ:隣の人に正しく説明できたらチェックを付けましょう>

□ 文字型はシングルクォーテーション ’ で囲い、文字列はダブルクォーテーション " で囲うのは変数名と区別するためである

□ 変数を作成することを「変数の宣言」といい、変数に値を入れることを「代入」、変数に入っている値を見ることを「参照」という

□ 変数には、他の変数の値を代入することができ、また演算の結果を代入することもできる

□ ローカル変数は、スコープが一番狭い変数であり、初期化してから使う

□ 変数の宣言では、変数に入れる値の型をはじめに指定する必要があり、それを静的型付けという

□ まず最初に真偽値のbool、整数値のint、浮動小数点数のdoubleの3つの型は最低限覚える

□ namespaceの目的は①わかりやすい分類整理②名前空間の提供③不必要なものを公開しないことができる、の3つ

まとめができたら、実際にコードを書いてみて、自分で試行錯誤しながら習得を進めましょう。


変数とデータ型はあらゆるプログラミング言語の基礎です。ここでしっかり理解しておくと、後のオブジェクト指向や高度なライブラリ操作を学ぶときに大いに役立ちます。

次回は、「3章. 演算子でプログラムに計算させる」を学びます。









最後までお読みいただきありがとうございます。