今回はデータ型についての説明です。
データ型について
変数の宣言のところでデータ型がでてきました。
データ型でその変数にどんなものを入れるのかという指定しています。
C#は型の指定にけっこうきびしいです。
コードを書いているときに数字型で宣言した変数に文字を代入しようとすると怒ってきます。
それはさておき、
型には値型、参照型の2種類があります。
値型は直接データを格納し、
参照型はデータの実態(インスタンス)がどこにあるかという参照情報が格納されます。
値型について
値型には以下のような型があります。
型名 | 型の説明 | ビット数 |
---|---|---|
byte | 符号なし整数 | 8 |
sbyte | 符号あり整数 | 8 |
short | 符号あり整数 | 16 |
ushort | 符号なし整数 | 16 |
int | 符号あり整数 | 32 |
uint | 符号なし整数 | 32 |
long | 符号あり整数 | 64 |
ulong | 符号なし整数 | 64 |
float | 単精度浮動小数点 | 32 |
double | 倍制度浮動小数点 | 64 |
bool | 論理型 | 8 |
char | Unicode文字 | 16 |
列挙型 | enum 名前 {..}形式のユーザー定義型 名前の付いた整数型の定数をまとめたもので、 コードとコード名との付け合わせなどに使ったりする | – |
構造体 | struct 名前 {..}形式のユーザー定義型 | – |
null許容型 | null値を代入できる値型を表す | – |
タプル | 複数のデータ型を束ねて1つの型として扱う | – |
符号あり/なしの違いはマイナスを表現できるかになります。
sbyteのsはsigned、uintのuはunsignedの頭文字だったと思います。
ビット数はデータ型がメモリをどのくらい使うかになります。
intの場合32ビット=4バイトのメモリを使います。
ユーザー定義型というのはユーザーが自由に型を組み合わせて1つの型として定義したものです。
それぞれ、組み合わせにどの型を使っていいかなど決まり事があります。
また、数値型の場合、ビット数に応じて設定できる数の範囲が決まります。
それぞれMinValue、MaxValueで範囲がわかります。
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"byte :{byte.MinValue}~{byte.MaxValue}");
Console.WriteLine($"sbyte :{sbyte.MinValue}~{sbyte.MaxValue}");
Console.WriteLine($"short :{short.MinValue}~{short.MaxValue}");
Console.WriteLine($"ushort :{ushort.MinValue}~{ushort.MaxValue}");
Console.WriteLine($"int :{int.MinValue}~{int.MaxValue}");
Console.WriteLine($"uint :{uint.MinValue}~{uint.MaxValue}");
Console.WriteLine($"long :{long.MinValue}~{long.MaxValue}");
Console.WriteLine($"ulong :{ulong.MinValue}~{ulong.MaxValue}");
Console.WriteLine($"float :{float.MinValue}~{float.MaxValue}");
Console.WriteLine($"double :{double.MinValue}~{double.MaxValue}");
Console.WriteLine($"decimal:{decimal.MinValue}~{decimal.MaxValue}");
/*
byte :0~255
sbyte :-128~127
short :-32768~32767
ushort :0~65535
int :-2147483648~2147483647
uint :0~4294967295
long :-9223372036854775808~9223372036854775807
ulong :0~18446744073709551615
float :-3.4028235E+38~3.4028235E+38
double :-1.7976931348623157E+308~1.7976931348623157E+308
decimal:-79228162514264337593543950335~79228162514264337593543950335
*/
}
}
列挙型、構造体については別記事で説明します。
null許容型について
値型には null を代入することはできないのですが、null許容型 T? の場合 null を代入することができます。
たとえば、int型の変数に0が入っていた時に、計算の結果0になったのか?値を代入していないため0なのか?わかりません。そのためまだ代入がされていない状態を表すために null を使います。
使い方は型の後ろに ? を付けます。
bool? flag = null;
char? letter = null;
int? number1 = null;
double? number2 = null;
null許容型の変数には元になる型 T に入れられる値 と null を代入することができます。
bool? の場合、代入できるのは true、false、null になります。
null許容型の配列もできます。
var ary = new int?[3];
ary[0] = null;
ary[1] = 10;
ary[2] = null;
参照型について
参照型はこんな感じです。
急にわけわからなくなりますが、初めのうちはstringと配列を覚えておけば大丈夫です。
参照型の変数を使う場合、newキーワードを使って初期化をする必要があります。
詳しくは[C# プログラミング入門] クラスのインスタンスについてを参照してください。
型名 | 説明 |
---|---|
string | 文字列 |
クラス | メソッド、変数などをひとまとめにするための型。 ユーザーが定義することもできる。 |
インターフェイス | クラスにメソッドやプロパティの定義を強制するための型。 ユーザーが定義することもできる。 |
配列 | 同じデータ型の束ねて1つのデータとして扱う 1次元、多次元配列 int[]、int[, ]など |
デリゲート | メソッドへの参照を表す型 |
object | すべての型の基底クラス |
文字列についてはこちらの記事に説明があります。
配列についてはこちらの記事に説明があります。
クラスについてはこちらの記事に説明があります。
値型変数と参照型変数の初期値ついて
メソッドの中で宣言された変数は値型・参照型どちらも初期化、代入をしないで中身を使用するとコンパイルエラーになります。
class Program
{
public static void Main() { }
void method1()
{
int x;
int? y;
System.Console.WriteLine(x); //エラーになり実行できない
System.Console.WriteLine(y); //エラーになり実行できない
int[] ary;
System.Console.WriteLine(ary[0]); //エラーになり実行できない
}
void method2()
{
//宣言と同時に初期化するか使う前に代入する。
int x = 10;
int y;
y = 20;
System.Console.WriteLine(x + y);
}
}
こんなエラーがでてきます。
「 エラー CS0165 未割り当てのローカル変数 ‘x’ が使用されました。 」
「 エラー CS0165 未割り当てのローカル変数 ‘y’ が使用されました。 」
「 エラー CS0165 未割り当てのローカル変数 ‘ary’ が使用されました。 」
クラス内で変数(フィールド)を宣言した場合は初期化、代入をしなくてもエラーにはなりません。その場合、変数には既定値が設定されます。
値型の場合は基本的に「0」で埋められた値になります(メモリ上の話)。
整数・実数の場合は「0」、論理型の場合は「false」になります。
null許容型の場合は「null」が初期値になります。
class Sample
{
public int a;
public bool b;
public int? a_nullable;
}
class Program
{
public static void Main()
{
var s = new Sample();
System.Console.WriteLine(s.a);
System.Console.WriteLine(s.b);
System.Console.WriteLine(s.a_nullable == null); // nullの場合、trueになる
}
}
0
False
True
参照型の場合、既定値はどのデータも指していない状態(null)になります。
クラスのメンバー変数に参照型を使用していて、それがnullの状態でアクセスしようとするとエラーになるので注意してください。
class Sample
{
public int[] ary;
}
class Program
{
public static void Main()
{
var s = new Sample();
System.Console.WriteLine(s.ary[1]); // 実行時にエラーになる
}
}
型推論(var)
varキーワードを使うと型を指定しなくても変数を宣言できます。
この方法で宣言する場合、初期化が必須になります。
varが使えるのはローカル変数だけです。
var number = 10; //numberはint型になる
var name = "日本人"; //nameはstring型になる
var country; //これは初期化していないのでエラーになる
じゃあ、今まで出てきた型を覚えなくていいのでは?と思うかもしれませんが、
varは右側の値や式から型を予測しているだけので実際の型を知っておく必要があります。
var num1 = 10; //int型
var num2 = 4294967296; //intでは入りきらないのでlong型
リテラル
変数の宣言や代入で「10」とか“日本人”とか書いていたと思いますが、
コードに直接書いた数字や文字をリテラルといいます。
整数リテラル
数値型を表します。10進数、16進数、2進数のリテラルがあります。
10進数を表すリテラル
数字を普通に書くと10進数を表します。
数字の後ろに特定の文字をつけると型を明示的に指定することができます。
var number1 = 10; //int型
var number2 = 10l; //long型
var number3 = 10u; //uint型
var number4 = 10ul; //ulong型
var number5 = 10.0f; //float型
var number6 = 10.0d; //double型
var number7 = 10.0m; //decimal型
var number8 = 10.0; //double型
16進数を表すリテラル
16進数を表すには、0x または 0X を頭に付けます。
また、間にアンダーバー _ で区切って見やすくすることができます。
var hex1 = 0xFF;
var hex2 = 0X10;
var hex3 = 0xFF_01_A1;
var hex4 = 0x_FF_AA_BB
2進数を表すリテラル
2進数を表すには、0b または 0B を頭に付けます。
また、間にアンダーバー _ で区切って見やすくすることができます。
var binary1 = 0b0101;
var binary2 = 0B1111;
var binary3 = 0b_1001_1010;
文字リテラル
文字型(char型)を表します。
直接文字を指定する場合は、文字をシングルコーテーション ‘ で囲みます。
char c1 = 'A';
char c2 = 'あ';
文字コードを入力して文字を指定ことができます。
Unicodeエスケープシーケンスで指定する場合は、\u の後ろに文字コードの16進数表現(4桁)を指定します。
var c = '\u3042'
System.Console.WriteLine(c); // あ
16進数エスケープシーケンスで指定する場合は、\x の後ろに文字コードの16進数を指定します。
var c1 = '\x61';
var c2 = '\x0062';
System.Console.WriteLine(c1); // a
System.Console.WriteLine(c2); // b
また、文字コードの値をchar型に変換することで文字を指定することができます。
var c1 = (char)97; // 10進数で文字コードを指定
var c2 = (char)0x62; // 16進数で文字コードを指定
System.Console.WriteLine(c1); // a
System.Console.WriteLine(c2); // b
文字列リテラル
文字列(string型)を表します。
文字列の指定は、文字列をダブルコーテーション “ で囲みます。
この場合、改行・円マークなどはエスケープシーケンス(\n、\\)を使って指定します。
var string1 = "あいうえお"; //string型
var string2 = "abc\\de"
System.Console.WriteLine(string2); // abc\de
アットマーク @ をダブルコーテーションの先頭に付けると文字列内でエスケープシーケンスを使わずに円マークや改行を入力することができます。
var string1 = @"abc\de";
var string2 = @"123
456";
System.Console.WriteLine(string1);
System.Console.WriteLine(string2);
abc\de
123
456
文字列の使い方については、こちらの記事に説明があります。
C# 記事まとめページに戻る(他のサンプルコードもこちら)
コメント