C# には値の種類ごとに「型」が用意されています。どの型を選ぶかで、扱える値の範囲・精度・メモリの使用量が変わります。このページでは数値・文字・文字列の型を詳しく学び、型同士の変換と異なる型の演算のルールを理解します。
char と string の違いを説明できるC# の整数型は「何ビットで値を記憶するか」と「負の数を扱うか(符号)」の組み合わせで決まります。
| 型名 | ビット数 | 符号 | 最小値 | 最大値 |
|---|---|---|---|---|
byte |
8 | なし | 0 | 255 |
sbyte |
8 | あり | -128 | 127 |
short |
16 | あり | -32,768 | 32,767 |
ushort |
16 | なし | 0 | 65,535 |
int |
32 | あり | -2,147,483,648 | 2,147,483,647 |
uint |
32 | なし | 0 | 4,294,967,295 |
long |
64 | あり | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
ulong |
64 | なし | 0 | 18,446,744,073,709,551,615 |
💡 型の選び方: 迷ったら
intを使ってください。Unity でもintが最もよく使われる整数型です。longはintの範囲を超える大きな数(累計スコアなど)、byteは色の成分(0〜255)や小さな数値に使います。
型の最大値・最小値はコードから確認できます。
int.MaxValue — int 型が表現できる最大値の定数(2147483647)。byte.MaxValue・long.MaxValue など他の整数型でも同様に使える。
書式:int.MaxValue フィールド
1
public const int MaxValue = 2147483647;
int.MinValue — int 型が表現できる最小値の定数(-2147483648)。
書式:int.MinValue フィールド
1
public const int MinValue = -2147483648;
1
2
3
Console.WriteLine(int.MaxValue); // 2147483647
Console.WriteLine(int.MinValue); // -2147483648
// 他の型も同様: byte.MaxValue → 255, long.MaxValue → 9223372036854775807
整数型には 符号あり(signed) と 符号なし(unsigned) の2種類があります。
int・long など): 負の数も表現できる。同じビット数の場合、正の最大値が半分になる。uint・ulong など): 0以上の値しか入れられない。その分、同じビット数でより大きな正の数を表現できる。8 ビットの例で比べると:
1
2
符号あり sbyte: -128 〜 127 (256通りを負・0・正に振り分ける)
符号なし byte: 0 〜 255 (256通りをすべて 0 以上に使う)
どちらも 2⁸ = 256 通りの値を表現しますが、範囲の割り当てが異なります。
変数に入れられる範囲を超えた計算をするとオーバーフローが発生します。C# のデフォルト動作では例外は発生せず、値が反対端から折り返します。
1
2
3
int maxInt = int.MaxValue;
Console.WriteLine(maxInt); // 2147483647
Console.WriteLine(maxInt + 1); // -2147483648 (最大値の次は最小値に折り返す)
⚠️ 注意: オーバーフローは実行時に無警告で起きます。意図しない計算結果にならないよう、値の範囲に合った型を選ぶことが大切です。
🔍 なぜ折り返すのか・もっと深く知りたい方へ: 2の補数による負数表現のしくみ、
intとSystem.Int32の関係、16進数/2進数リテラルの書き方などは補足ページで解説しています → 数値リテラルと型エイリアス(補足)
小数を扱う型は3種類あります。
| 型名 | ビット数 | 有効桁数 | 主な用途 |
|---|---|---|---|
float |
32 | 約7桁 | Unity の座標・角度など(パフォーマンス優先) |
double |
64 | 約15〜17桁 | 一般的な小数計算(C# のデフォルト) |
decimal |
128 | 約28〜29桁 | 金融計算など(誤差を許容できない場合) |
小数リテラルは既定で double 型です。float や decimal のリテラルを書くにはサフィックスを付けます。
| 書き方 | 型 |
|---|---|
3.14 |
double |
3.14f |
float |
3.14m |
decimal |
1
2
3
double d = 3.14; // double リテラルをそのまま代入
float f = 3.14f; // f サフィックスで float リテラル
decimal m = 3.14m; // m サフィックスで decimal リテラル
1
2
float f = 3.14; // ❌ コンパイルエラー: double は float に暗黙的に変換できない
float f = 3.14f; // ✅ OK
💡 Unity では
floatをよく使う: Unity のVector3やtransform.positionなど、ほとんどの値がfloat型です。Unity で小数を扱うときは3.14fのようにfを付ける習慣をつけましょう。
float と double は値を2進数で近似して記憶します。そのため、計算結果に小さな誤差が出ることがあります。
1
2
Console.WriteLine(0.1 + 0.2); // 0.30000000000000004
Console.WriteLine(0.1 + 0.2 == 0.3); // False
金融計算など誤差を許容できない場面では decimal を使ってください。
char — 1文字を扱う型char は1文字を表す型です。リテラルはシングルクォート(') で囲みます。
1
2
char c = 'A';
Console.WriteLine(c); // A
char は内部的に Unicode のコードポイント(0〜65535 の整数)として記憶されています。そのため整数への変換や算術演算も行えます。
1
2
3
char c = 'A';
Console.WriteLine((int)c); // 65 ('A' の Unicode コードポイント)
Console.WriteLine((char)('A' + 1)); // B (コードポイント 66 → 'B')
特殊文字は \ を使ったエスケープシーケンスで表現します。
| シーケンス | 意味 |
|---|---|
'\n' |
改行 |
'\t' |
タブ |
'\\' |
バックスラッシュ自体 |
'\'' |
シングルクォート自体 |
string — 文字列を扱う型string は文字の並び(シーケンス) を表す型です。リテラルはダブルクォート(") で囲みます。
1
2
3
string name = "Alice";
Console.WriteLine(name); // Alice
Console.WriteLine(name.Length); // 5 (文字数)
char と string の違い| 比較項目 | char |
string |
|---|---|---|
| 文字数 | 必ず1文字 | 0文字以上(何文字でも可) |
| リテラルの囲み | ' シングルクォート |
" ダブルクォート |
| 例 | 'A' |
"Alice" |
1
2
3
char c = 'A'; // ✅ char は1文字
string s = "A"; // ✅ string は1文字でもOK
char c = "A"; // ❌ コンパイルエラー: string を char には代入できない
+ 演算子で文字列を連結できます。
1
2
3
4
string firstName = "Alice";
string lastName = "Smith";
string fullName = firstName + " " + lastName;
Console.WriteLine(fullName); // Alice Smith
char と同じエスケープシーケンスが string 内でも使えます。
| シーケンス | 意味 |
|---|---|
"\n" |
改行 |
"\t" |
タブ |
"\\" |
バックスラッシュ |
"\"" |
ダブルクォート |
1
2
3
Console.WriteLine("1行目\n2行目"); // 改行して2行に出力
Console.WriteLine("A\tB"); // タブで区切って出力
Console.WriteLine("\"Hello\""); // "Hello"(ダブルクォートを含む文字列)
異なる型の値を別の型に変換する操作を型変換と呼びます。
情報が失われない(= より広い型への)変換は自動で行われます。これを暗黙的型変換(implicit conversion) と呼びます。
1
2
3
int i = 42;
long l = i; // int → long へ暗黙的に変換
double d = i; // int → double へ暗黙的に変換
暗黙的型変換が可能な主な方向(矢印の向きに自動変換される):
1
byte → short → int → long → float → double
情報が失われる可能性のある変換は明示的に指定する必要があります。これをキャスト(cast) と呼びます。
書式:キャスト
1
(変換先の型)式
| 要素 | 説明 |
|---|---|
(変換先の型) |
変換したい型名をカッコで囲む |
式 |
変換する値 |
1
2
3
double d = 3.7;
int i = (int)d; // double → int にキャスト
Console.WriteLine(i); // 3 (小数点以下は切り捨て)
⚠️ 注意: キャストによる小数→整数の変換は切り捨てです。四捨五入ではありません。
3.9をキャストしても3になります。
表現範囲を超えた値をキャストするとオーバーフローが起きます。
1
2
3
int big = 300;
byte b = (byte)big; // int → byte にキャスト(300 は byte の範囲 0〜255 を超えている)
Console.WriteLine(b); // 44 (300 % 256 = 44)
Parse メソッドを使うと文字列を数値に変換できます。
int.Parse メソッド — 文字列を int に変換する
書式:int.Parse メソッド
1
int int.Parse(string s);
| パラメータ | 型 | 説明 |
|---|---|---|
s |
string |
整数を表す文字列 |
1
2
3
string s = "42";
int i = int.Parse(s);
Console.WriteLine(i + 1); // 43
数値に変換できない文字列を渡すと実行時に例外が発生します(例外の扱いは後のページで学びます)。
1
int.Parse("abc"); // ❌ 実行時例外: 入力文字列が正しい形式ではありません
ToString メソッドで数値を文字列に変換できます。ただし後述の文字列補間 $"..." を使う方が読みやすい場面が多いです。
1
2
int score = 100;
string s = score.ToString(); // "100"
整数と浮動小数点数を混ぜて演算すると、より広い型に自動的に変換されてから計算されます。これを型の昇格(numeric promotion) と呼びます。
1
2
3
4
int i = 5;
double d = 1.5;
var result = i + d; // result は double 型
Console.WriteLine(result); // 6.5
主な数値昇格の組み合わせ:
| 演算の組み合わせ | 結果の型 |
|---|---|
int ± int |
int |
int ± long |
long |
int ± float |
float |
int ± double |
double |
float ± double |
double |
💡 ポイント: 「より精度の高い・範囲の広い型に合わせる」と覚えましょう。
string と数値の + 演算string に数値を + で結合すると、数値が文字列に変換されてから連結されます。
1
2
3
int score = 100;
string message = "スコア: " + score;
Console.WriteLine(message); // スコア: 100
ただし、+ は左から右に評価されるため、意図しない結果になることがあります。
1
2
Console.WriteLine("1 + 2 = " + 1 + 2); // ❌ "1 + 2 = 12"
Console.WriteLine("1 + 2 = " + (1 + 2)); // ✅ "1 + 2 = 3"
"文字列" + 1 は "文字列1" になり、さらに + 2 で "文字列12" になります。数値計算はカッコで先に計算してから連結しましょう。
文字列補間 $"..." — 文字列の中に式を {式} で埋め込めます。+ で連結するより読みやすく、計算の優先順位の問題も起きません。
1
2
3
4
int score = 100;
string name = "Alice";
Console.WriteLine($"{name} のスコアは {score} 点です。"); // Alice のスコアは 100 点です。
Console.WriteLine($"1 + 2 = {1 + 2}"); // 1 + 2 = 3
{式} の部分が評価され、その結果が文字列として埋め込まれます。
f を付け忘れる1
2
float speed = 1.5; // ❌ コンパイルエラー: double を float に暗黙的に変換できない
float speed = 1.5f; // ✅ OK
1
2
int i = (int)3.9;
Console.WriteLine(i); // 3 (3.9 ではなく 3)
四捨五入したい場合は Math.Round を使います。
1
2
int i = (int)Math.Round(3.9);
Console.WriteLine(i); // ✅ 4
char と string のリテラルを混同する1
2
char c = "A"; // ❌ コンパイルエラー: string を char に代入できない
char c = 'A'; // ✅ OK
+ で計算結果が変わる1
2
Console.WriteLine("合計: " + 3 + 4); // ❌ "合計: 34"
Console.WriteLine("合計: " + (3 + 4)); // ✅ "合計: 7"
int を使うfloat(32bit・Unity向け)・double(64bit・汎用)・decimal(128bit・精度重視)の3種類double リテラルは 3.14、float は 3.14f、decimal は 3.14mchar は1文字('A')、string は0文字以上の文字列("Hello")(型)式 で明示的に行う。小数→整数は切り捨てstring + 数値 は文字列に変換して連結される。計算結果を埋め込むには文字列補間 $"..." が便利int と uint の違いを説明してください。また、同じ32ビットでも最大値が異なるのはなぜですか?
次のコードの出力結果を答えてください。
1
2
3
double d = 9.9;
int i = (int)d;
Console.WriteLine(i);
次のコードの出力結果を答えてください。
1
2
Console.WriteLine("答えは " + 3 + 4);
Console.WriteLine("答えは " + (3 + 4));
次のコードにはコンパイルエラーがあります。どこを修正すればよいですか?
1
float speed = 5.0;
int は負の数も扱える(符号あり)、uint は 0 以上の値しか扱えない(符号なし)。32ビットで表現できる値の個数(2³² ≈ 42 億通り)は同じだが、int はその半分を負の数に使うため正の最大値が小さくなる。uint.MaxValue(約 42 億)は int.MaxValue(約 21 億)の約2倍。
9。(int) キャストは小数点以下を切り捨てるため、9.9 は 9 になる。四捨五入ではない点に注意。
1行目は 答えは 34("答えは " + 3 → "答えは 3"、さらに + 4 → "答えは 34" と左から評価される)、2行目は 答えは 7(カッコ内の 3 + 4 = 7 を先に計算してから連結)。
5.0 は double リテラルなので float 型の変数には代入できない。f サフィックスを付ける。
1
float speed = 5.0f;
[条件分岐(準備中)] では、条件によって実行する処理を変える方法を学びます。