変数を理解しよう!

[C#] 変数を理解しよう!

※ 当サイトは広告を含みます。

C#の型を学んだので、その知識を活かして変数の使い方を学びましょう。
なお、ここで学ぶのはC#で変数を利用する方法です。変数?って人は先に次の記事を読んでください。

変数宣言と利用方法

難しくないので、例を見たほうが早いでしょう。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      // 変数宣言
      int age;

      // 変数に値を代入
      age = 15;

      // 変数の値を利用
      Console.WriteLine(age); // こうやって書くと数値を出力できる
    }
  }
}

つまりは変数宣言は


型名 変数名;

です。

そして値を代入するときは


変数名 = 値;

です。

また、変数を出力するときはConsole.WriteLineに変数名を記述します。
この記述については本題とズレるので解説しませんが、今はそういうものと思ってください。

ちなみに変数名に予約語は利用できません。裏技みたいな方法で近しいことができるのですが、普通に迷惑コードなので辞めてください。
後、変数名に日本語が使えるのですが、僕は反対派なので見える範囲で使うことは許しません。ローマ字もNG、ちゃんと英語を使いましょう。

りさ
りさ

日本語の駄目なとこは何ですか?

管理人
管理人

許容するやつの気持ちが分かんないってのが1番だけど、そもそも入力の切り替えがめんどう。
後は日本語は1文字で2文字分の幅が必要だから、インデントを揃えるのが困難で嫌。

りさ
りさ

感情的な理由にしか聞こえませんが...

管理人
管理人

こういうのをプログラマ宗教問題と言います。取扱には注意しましょう。

変数宣言と同時に値を代入する方法

変数宣言と同時に値を代入することもできます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      // 変数宣言して値を代入
      int age = 15;

      // 変数の値を利用
      Console.WriteLine(age); // こうやって書くと数値を出力できる
    }
  }
}

複数の変数を同時に宣言する方法

同じ型であれば複数の変数を同時に宣言することもできます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      // 複数の変数を同時に宣言
      int age1 = 15, age2 = 30, age3 = 45;

      Console.WriteLine(age1);
      Console.WriteLine(age2);
      Console.WriteLine(age3);
    }
  }
}

変数の初期化

これは変数を利用する前に何らかの値を代入することを言います。
タイミングは宣言時でもいいし、利用前なら宣言後でもいいです。

C#ではローカル変数を作った場合を除き、初期化は自動で行われます。
このローカル変数とは大雑把に言うと関数の中で利用する変数です。

つまりは先程から例で紹介してる変数がローカル変数です。
対してクラスなどに所属する変数は自動的に初期化が行われます。

これは見てもらったほうが早いのでサンプルコードを用意しました。
記述は気にせず実行してください。値が自動的に0になると思います。


namespace Sample
{
  internal class Program
  {
    static int age; // 自動的に0が代入される

    static void Main(string[] args)
    {
      Console.WriteLine(age);
    }
  }
}
管理人
管理人

自動的に初期化される値は型ごとに決まってます。これは型を学習した際に学びましたよね?。
そこで覚えた値が初期化で利用されます。とは言え、今は意図的に初期化すること心掛けたほうがいいですよ。

変数のスコープ

別の記事で少し触れましたが、変数にはスコープと呼ばれる有効範囲があります。
具体的には変数を作成したスコープよりも同じか、それより下位のスコープしか変数を利用できません。

アクセスできない変数を利用した場合はビルドエラーになります。これを次のサンプルコードで確認してください。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      {
        int age = 15;

        // 同じ領域はアクセスできる
        Console.WriteLine(age);

        {
          // さらに下位の領域からもアクセスできる
          Console.WriteLine(age);
        }
      }

      // 上位の領域はアクセスできない
      Console.WriteLine(age);
    }
  }
}
管理人
管理人

ビルド失敗を確認できましたかね。動かしたい場合は最後のConsole.WriteLine(age)をコメントアウトしてください。
また、当然のことですが有効なスコープで同名の変数を作ることも不可能です。

リテラル

さて、変数の基礎は先程までで終わりですが、実際に利用するにはリテラルというルールを覚えなくてはいけません。

リテラルとは値の記述方法です。先程の例で説明すなら15という数値がリテラルになります。
この15は10進数で書かれたことを意味しますが、プログラミングの世界では2進数でも16進数でも記述できます。
さらに言うと文字列とかも記述できるので、これらを区別する記述が必要になります。

では、実際にはどんなリテラルが存在するのが例を使いながら学びましょう。

POINT値の記述はリテラルと呼ばれるルールに従う必要がある。

論理リテラル

bool型で利用するリテラルです。論理値のtruefalseしか記述できません。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      bool b1 = true;
      bool b2 = false;

      Console.WriteLine(b1);
      Console.WriteLine(b2);
    }
  }
}

整数リテラル

整数型で利用するリテラルです。そのまま記述すれば10進数。0xで16進数、0bで2進数を記述できます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int i1 = 100;        // 10進数で記述
      int i2 = 0x100;      // 16進数で記述
      int i3 = 0b00001111; //  2進数で記述

      Console.WriteLine(i1);
      Console.WriteLine(i2);
      Console.WriteLine(i3);
    }
  }
}

合わせてサフィックスと呼ばれる仕組みがあり、特定の型を直接指定できます。
こんな感じに数値の後ろにU, L, ULを付ける記述をします。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      uint ui = 123456789U;   // 数値の後ろにU(またはu)を付けると符号なしを意味する
      long ll = 987654321L;   // 数値の後ろにL(またはl)を付けるとlong型を意味する
      ulong ul = 123123123UL; // 数値の後ろにUL(またはul)を付けるとulong型を意味する

      Console.WriteLine(ui);
      Console.WriteLine(ll);
      Console.WriteLine(ul);
    }
  }
}

実数リテラル

浮動小数点数値型で利用するリテラルです。数値の後ろにD, F, Mを付けると特定の型が記述できます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      double d1 = 9.9;          // 数値の後ろに何も付けないとdoubleを意味する
      double d2 = 9.9998D;      // 数値の後ろにD(またはd)を付けるとdoubleを意味する
      float fl = 3.14F;         // 数値の後ろにF(またはf)を付けるとfloatを意味する
      decimal de = 123456.789M; // 数値の後ろにM(またはm)を付けるとdecimalを意味する

      Console.WriteLine(d1);
      Console.WriteLine(d2);
      Console.WriteLine(fl);
      Console.WriteLine(de);
    }
  }
}

文字リテラル

char型で利用するリテラルです。''(シングルクォーテーション)で囲むのだけ覚えればいいです。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      char c1 = 'a';      // ''で囲って文字を記述する
      char c2 = '\'';     // 'みたいな特殊な文字は'\'を利用して記述する
      char c3 = '\u2605'; // ★をUTF-16で記述する

      Console.WriteLine(c1);
      Console.WriteLine(c2);
      Console.WriteLine(c3);
    }
  }
}
管理人
管理人

\で特殊文字を記述することをエスケープシーケンス(escape sequence)と呼びます。

文字列リテラル

string型で利用するリテラルです。基本的には""(ダブルクォーテーション)で囲むのですが、いくつかパターンがあります。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      string s1 = "test";                // ""で囲って文字列を記述する
      string s2 = "C:\\Temp";            // 特殊な文字は'\'を使って記述する
      string s3 = @"C:\Temp";            // @を付けると特殊な文字も記述できる
      string s4 = """{\''\ ABC \""\}"""; // """で囲むと全部エスケープ不要で記述できる

      // 複数行の記述もできる
      string s5 =
        """
        {
          {
            TEST.BCDEFG
          }
        }
        """;

      Console.WriteLine(s1);
      Console.WriteLine(s2);
      Console.WriteLine(s3);
      Console.WriteLine(s4);
      Console.WriteLine(s5);
    }
  }
}
管理人
管理人

@付きはパスの入力に便利です。"""はテストでファイルの中身を丸ごと記述する時とかに使います。

null

nullは参照型が何も参照していない状態を意味します。つまりは値が無いみたいな状態です。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      string s1 = null;

      Console.WriteLine(s1);
    }
  }
}
管理人
管理人

この何もない状態で安易に操作を試みるとNullReferenceExceptionが発生してプログラムが落ちます。
今は気にしなくていいけど、将来的には常にnullを意識してください。

var(宇宙最強)

一応は伝えておきますが、C#がある程度できるようになるまで使わないでください。
これは型推論と呼ばれる機能で右側の値に応じて自動的に型を判別してくれます。

とりあえず例を見せましょう。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var b1 = true;       // bool型
      var i1 = 10;         // int型
      var l1 = 1000UL;     // ulong型
      var d1 = 1.23456789; // double型
      var c1 = 'C';        // char型
      var s1 = "str";      // string型

      // 表示は.NET型だけど組み込み型と同じです。
      Console.WriteLine(b1.GetType()); // 型名を出力する方法
      Console.WriteLine(i1.GetType());
      Console.WriteLine(l1.GetType());
      Console.WriteLine(d1.GetType());
      Console.WriteLine(c1.GetType());
      Console.WriteLine(s1.GetType());
    }
  }
}

結論は右側が分かれば左を予測できるよねってことで、C#が勝手に型を判断してくれます。

管理人
管理人

つまりは全部varにすれば型なんて考えなくても記述できちゃうんだな。
これが最強で僕なんかはvarしか使いません。ついでに型の文字列が3文字で揃うのが美しいんですよね。

りさ
りさ

全部これでいいじゃん。

管理人
管理人

注意点は動作の途中で型が変わったりはしません。当たり前ですがvarで生成した時に数値型なら数値しか代入できません。
型チェックが緩い言語だと急に文字列を放り込めるのですが、C#のvarはあくまで生成時に限った型推論です。

あとがき

変数名はプログラマ宗教論争が起きて地球が消滅するので気をつけましょう。

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。