C#: 変数とデータ型

変数を「ラベルの貼られた箱」だと考えてみてください。ラベルは名前であり、箱の中にはデータが入っています。箱の適切なサイズと種類を選ぶことで、データを安全かつ効率的に管理することができます。

1. 変数の宣言と初期化

C# は強型付け言語であるため、変数を宣言する際には型を指定する必要があります(あるいは var を使用してコンパイラに型を推論させることもできます):

CSHARP
int age;
age = 25;

string name = "Alice";
double score = 95.5;

また、1行で同じ型の変数を複数宣言することもできます:

CSHARP
int x = 1, y = 2, z = 3;

警告:C# では、初期化されていないローカル変数の使用は許可されていません。コンパイラはエラーを発生させます。


2. 命名規則

C# では、変数名の命名規則が厳格に定められています:

(1) キャメルケースとパスカルケース

C# には、2つの主要な命名規則があります:

識別子の種類 形式
ローカル変数、フィールド camelCase studentName, totalCount
メソッド、クラス、プロパティ パスカルケース CalculateSum, Student

ヒント:camelCase:最初の単語は小文字、それ以降の単語は大文字。PascalCase:すべての単語の大文字。

CSHARP
int studentAge = 18;
double averageScore = 87.5;
string homeAddress = "Beijing";

3. 整数型

C# には、符号付きと符号なしの両方を網羅する 8 種類の整数型が用意されています:

タイプ バイト数 範囲 接尾辞
sbyte 1 -128 ~ 127
byte 1 0 ~ 255
short 2 -32,768 ~ 32,767
ushort 2 0 ~ 65,535
int 4 -2,147,483,648 ~ 2,147,483,647
uint 4 0 ~ 4,294,967,295 U
long 8 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 L
ulong 8 0 ~ 18,446,744,073,709,551,615 UL

ヒント:Javaとは異なり、C#には符号なし整数型(byteushortuintulong)があります。 なお、C#のbyteは符号なし型であり、符号付き版はsbyteであることに注意してください。

▶ サンプル

CSHARP
sbyte sb = -100;
byte b = 200;
short s = -30000;
ushort us = 60000;
int i = 100000;
uint ui = 3000000000U;
long l = 9000000000000000000L;
ulong ul = 18000000000000000000UL;

Console.WriteLine($"sbyte:  {sb}");
Console.WriteLine($"byte:   {b}");
Console.WriteLine($"short:  {s}");
Console.WriteLine($"ushort: {us}");
Console.WriteLine($"int:    {i}");
Console.WriteLine($"uint:   {ui}");
Console.WriteLine($"long:   {l}");
Console.WriteLine($"ulong:  {ul}");
▶ 試してみよう
TEXT 📖 参照専用
sbyte:  -100
byte:   200
short:  -30000
ushort: 60000
int:    100000
uint:   3000000000
long:   9000000000000000000
ulong:  18000000000000000000

4. 浮動小数点型

バイト数 精度 範囲(概算) 接尾辞 用途
float 4 7桁 ±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸ f グラフィックス、ゲーム
double 8 15~16桁 ±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸ d (デフォルト) 科学計算
decimal 16 28~29桁 ±1.0×10⁻²⁸ ~ ±7.9×10²⁸ m 金額

警告:10進リテラルは、デフォルトで double です。float または decimal に代入する際は、接尾辞を付ける必要があります。そうしないと、コンパイラがエラーを発生させます。

CSHARP
float f = 3.14f;
double d = 3.14;
decimal m = 3.14m;

Console.WriteLine($"float:   {f}");
Console.WriteLine($"double:  {d}");
Console.WriteLine($"decimal: {m}");
TEXT 📖 参照専用
float:   3.14
double:  3.14
decimal: 3.14

ヒント:decimalは金融計算用に設計されており、2進浮動小数点数の誤差を回避します。例えば、0.1 + 0.20.3doubleとの間では厳密に一致しませんが、decimalとは厳密に一致します。


5. bool 型

bool には truefalse の 2 つの値しかなく、1 バイトを占めます。

警告:C言語とは異なり、C#の bool は整数との間で暗黙的な型変換を行うことはできません。if(1) は不正な記述です。if(true) または if(x != 0) と記述する必要があります。

CSHARP
bool isReady = true;
bool isEmpty = false;

Console.WriteLine($"isReady:  {isReady}");
Console.WriteLine($"isEmpty:  {isEmpty}");
TEXT 📖 参照専用
isReady:  True
isEmpty:  False

6. char 型

C#の char は 2 バイトの Unicode 文字であり、C 言語のような 1 バイトの ASCII 文字ではありません。

CSHARP
char ch1 = 'A';
char ch2 = '\u4e2d';

Console.WriteLine($"ch1: {ch1}");
Console.WriteLine($"ch2: {ch2}");
Console.WriteLine($"ch1 code: {(int)ch1}");
Console.WriteLine($"ch2 code: {(int)ch2}");
TEXT 📖 参照専用
ch1: A
ch2: 中
ch1 code: 65
ch2 code: 20013

ヒント:char は一重引用符 'A' を使用していますが、string は二重引用符 "A" を使用しています。これらはまったく異なるタイプです。


7. 文字列型

string は、不変の Unicode 文字シーケンスを表す参照型です。

CSHARP
string greeting = "Hello";
string name = "World";
string message = greeting + ", " + name + "!";

Console.WriteLine(message);
Console.WriteLine($"Length: {message.Length}");
TEXT 📖 参照専用
Hello, World!
Length: 13

警告:string は参照型であり、そのデフォルト値は null です(空文字列 "" ではありません)。null 文字列にアクセスすると、NullReferenceException が発生します。


8. var による暗黙の型指定

C# 3.0 では var キーワードが導入され、これによりコンパイラは初期値から型を推論できるようになりました:

CSHARP
var count = 42;
var price = 9.99m;
var label = "hello";
var flag = true;

Console.WriteLine(count.GetType().Name);
Console.WriteLine(price.GetType().Name);
Console.WriteLine(label.GetType().Name);
Console.WriteLine(flag.GetType().Name);
TEXT 📖 参照専用
Int32
Decimal
String
Boolean

警告:var は「任意の型」を意味するものではありません。変数の型はコンパイル時に決定され、初期化する必要があります。以下の記述は不正です:

CSHARP
var x;
var x = null;

ヒント:型名が長い場合や、文脈から型が明らかな場合は、var を使用してください。ただし、読みやすさが損なわれる可能性があるため、過度な使用は避けてください。


9. sizeof — 型のサイズを確認する

sizeof は、型が占めるバイト数を返します。プリミティブ型に対しては直接使用できますが、その他の型に対しては unsafe コンテキストが必要です。

▶ サンプル

CSHARP
Console.WriteLine($"sbyte:    {sizeof(sbyte)} bytes");
Console.WriteLine($"byte:     {sizeof(byte)} bytes");
Console.WriteLine($"short:    {sizeof(short)} bytes");
Console.WriteLine($"ushort:   {sizeof(ushort)} bytes");
Console.WriteLine($"int:      {sizeof(int)} bytes");
Console.WriteLine($"uint:     {sizeof(uint)} bytes");
Console.WriteLine($"long:     {sizeof(long)} bytes");
Console.WriteLine($"ulong:    {sizeof(ulong)} bytes");
Console.WriteLine($"float:    {sizeof(float)} bytes");
Console.WriteLine($"double:   {sizeof(double)} bytes");
Console.WriteLine($"decimal:  {sizeof(decimal)} bytes");
Console.WriteLine($"char:     {sizeof(char)} bytes");
Console.WriteLine($"bool:     {sizeof(bool)} bytes");
▶ 試してみよう
TEXT 📖 参照専用
sbyte:    1 bytes
byte:     1 bytes
short:    2 bytes
ushort:   2 bytes
int:      4 bytes
uint:     4 bytes
long:     8 bytes
ulong:    8 bytes
float:    4 bytes
double:   8 bytes
decimal:  16 bytes
char:     2 bytes
bool:     1 bytes

10. const 定数

値を変更できないコンパイル時定数を宣言するには、const を使用します。これらは宣言時に初期化する必要があります:

CSHARP
const double Pi = 3.14159265358979;
const int MaxRetry = 3;
const string AppName = "MyApp";

Console.WriteLine($"Pi = {Pi}");
Console.WriteLine($"MaxRetry = {MaxRetry}");
Console.WriteLine($"AppName = {AppName}");
TEXT 📖 参照専用
Pi = 3.14159265358979
MaxRetry = 3
AppName = MyApp

警告:const の名前は通常、PascalCase 表記を使用します。この値はコンパイル時に決定可能でなければならず、変数やメソッド呼び出しの結果であってはなりません。

ヒント:実行時に決定される「定数」が必要な場合は、代わりに readonly フィールドを使用してください。


11. 型のデフォルト値

初期値が指定されていない場合、各型にはデフォルト値が設定されています:

タイプ デフォルト値
sbyte / byte / short / ushort / int / uint / long / ulong 0
float 0.0f
double 0.0d
decimal 0.0m
char '\0'
bool false
string null
任意の参照型 null

▶ サンプル

CSHARP
int defaultInt = default;
bool defaultBool = default;
char defaultChar = default;
string defaultString = default;
double defaultDouble = default;

Console.WriteLine($"int:    [{defaultInt}]");
Console.WriteLine($"bool:   [{defaultBool}]");
Console.WriteLine($"char:   [{(int)defaultChar}]");
Console.WriteLine($"string: [{defaultString}]");
Console.WriteLine($"double: [{defaultDouble}]");
▶ 試してみよう
TEXT 📖 参照専用
int:    [0]
bool:   [False]
char:   [0]
string: []
double: [0]

ヒント:default キーワードを使用すると、あらゆる型のデフォルト値を取得できます。これはジェネリック型で特に頻繁に使用されます:default(T)


12. 値型と参照型 — はじめに

C#の型は、大きく分けて2つのカテゴリに分類されます:

カテゴリ ストレージ 割り当ての挙動 代表的なタイプ
値型 スタック(通常) 値をコピーする int, bool, char, decimal, struct, enum
参照型 ヒープ 参照先(アドレス)をコピー string, class, object, 配列
CSHARP
int a = 10;
int b = a;
b = 20;
Console.WriteLine($"a = {a}, b = {b}");

string s1 = "hello";
string s2 = s1;
s2 = "world";
Console.WriteLine($"s1 = {s1}, s2 = {s2}");
TEXT 📖 参照専用
a = 10, b = 20
s1 = hello, s2 = world

警告:s1"world" にはなりませんでした。これは、string が不変であるためです。つまり、s2 = "world" は元のオブジェクトを変更せず、s2 が新しいオブジェクトを指すようにするだけです。 値型の代入では実際の値がコピーされますが、参照型の代入では参照がコピーされます。しかし、stringは不変であるため、値型のように振る舞います。

❓ よくある質問

Q vardynamic の違いは何ですか?
A var はコンパイル時に型を決定し、型安全です。 dynamicは実行時に型を解決し、コンパイル時の型チェックがなく、パフォーマンスが劣り、エラーが発生しやすいです。
Q なぜ、金銭計算においては decimaldouble より優れているのですか?
A decimal は10進数形式で格納されるため、0.1 を正確に表現できます。 doubleは2進数形式で保存されるため、0.1を正確に表現できず、累積的な丸め誤差が生じます。
Q string は値型ですか、それとも参照型ですか?
A string は参照型ですが、不変であるため、代入の際は値セマンティクスが適用されます。つまり、ある変数を変更しても、別の変数には影響しません。
Q constreadonly の違いは何ですか?
A const は、宣言時に代入する必要があり、暗黙的に static であるコンパイル時定数です。 readonlyは、コンストラクタ内で代入可能であり、インスタンスごとに異なる可能性がある実行時定数です。

📖 まとめ

📝 練習問題

  1. int 変数 age に自分の年齢を、string 変数 name に自分の名前をそれぞれ設定し、両方を表示する
  2. floatdoubledecimalをそれぞれ用いて0.1 + 0.2を計算し、その結果が0.3と完全に一致するかどうかを比較する
  3. sizeof を使用して、intdoublechar、および bool のバイトサイズを出力する
  4. const double Pi = 3.14159265 を宣言し、半径 5 の円の面積を計算して、その結果を出力してください
  5. default キーワードを使用して、intboolchar、および string のデフォルト値を取得し、出力する
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%