2-2 変数と定数

2-2-1   C# で予約されたデータ型

  C# は、.NET Framework の CTS ( Common Type System )に準拠したいくつかのデータ型があります(表 2-1 )。

●表 2-1 ● データ型一覧


(タイプ)
分 類 内 容 備 考
sbyte 値 型 整 数 符号あり 1 バイト - 128 ~ 127
short 符号あり 2 バイト - 32768 ~ 32767
int 符号あり 4 バイト - 231~ 231- 1
long 符号あり 8 バイト - 263~ 263- 1
byte 符号なし 1 バイト 0 ~ 255
ushort 符号なし 2 バイト 0 ~ 65535
uint 符号なし 4 バイト 0 ~ 232- 1
ulong 符号なし 8 バイト 0 ~ 264- 1
float 浮動小数点 IEEE754 準拠 4 バイト ± 1.5 × 10- 45~± 3.4 × 1038
double IEEE754 準拠 8 バイト ± 5.0 × 10- 324~± 1.7 × 10308
bool 論理型 値は true か false のみ
char Unicode 文字( 2 バイト) 引用符は ' '
decimal 10 進数データ型 ± 1.0 × 10- 28~± 7.9 × 1028
object 参照型 すべての型のベース型
string BSTR 型 Unicode 文字列 引用符は" "

 各データ型のビット形式については、一般のコンピュータ知識の範疇にあたるので詳細は省略しますが、いくつかの C# の特徴的な点をふまえて補足します。

 なお、上記の表で「型(タイプ)」の欄に書かれた名称は、C# のキーワード(予約語)であり、この後の 2-2-2 「変数の宣言」で使用します。また、表にある「値型」と「参照型」の分類の意味は、2-3 「値型と参照型」で説明します。

●整数について

  C# の整数は、「符号あり」と「符号なし」の 2 種類があります。そのバイト長が異なる 4 種類のデータ型があります。

<ワンポイント>

● for C++

  C/C++ 言語では、同じ int 型でも OS によって、2 バイトや 4 バイトなど、バイト長が異なることがありますが、C# では常にバイト長は一定です。

●浮動小数点

 小数点をともなう計算では、浮動小数点、または decimal (次項で説明)を使うことになります。C# の浮動小数点は、IEEE754 準拠の浮動小数点であり、一般的なプログラミング言語で利用されています。

  IEEE の浮動小数点では、± 1.m × 2n または± 0.m × 2n と表記できる値について、符号、仮数( m の部分)、指数( n の部分)をビットの並びとして記憶します。IEEE に限らず、一般的に浮動小数点の小数部分の扱いでは、特に 10 進数表記とは異なるので注意が必要です。

  10 進数では、小数点第 1 位が 10 分の 1、第 2 位が 100 分の 1 となりますが、浮動小数点の仮数( m の部分)は、あるビットが 2 分の 1、その下位のビットが 4 分の 1、さらに下位が 8 分の 1 となります。そのため、10 進数の小数が浮動小数点で正確に表されるとは限りません。この誤差を、浮動小数点の「丸め誤差」といいます( IEEE 浮動小数点の正確なビット表現は、値の範囲によって多少変化します。また、「正の無限大」や「負の無限大」、「数でない値」などが定義されています。正確なビット表現は関連ドキュメントを参照してください)。

 さらに浮動小数点では、表 2-1 の float なら有効数字が 7 桁、double なら有効数字は 15 桁~ 16 桁程度と、有効桁数が限られています。そのため、財務計算などの大きな額の計算には向きません。桁数の大きい金額の計算には、次に説明する decimal を使います。

● decimal

  decimal は、金額が大きい財務計算に向いたデータ型です。有効数字は、28 桁~ 29 桁です。

 また、小数点も扱うことができます。decimal は、± m × 10n で表すデータをビットとして記憶しています。m は、0 ~ 296-1 の範囲の整数、n は- 28 ~ 0 の範囲です。指数( n の部分)がマイナスになるので、小数点も表すことができます。

 ただし、浮動小数点と違い、指数の対象となる数(底)は、2 ではなく 10 です。また仮数にあたる部分( m の部分)は、小数ではなく整数です。つまり、浮動小数点のように、小数部分が 2 分の 1、4 分の 1、8 分の 1 という値の組み合わせではなく、10 進数を想定した表現になっています。そのため、浮動小数点で起こる「丸め誤差」は、decimal には発生しません。

●文字の扱い

  char 型は、1 文字データを扱うデータ型です。このデータは、Unicode 文字であり、見た目が全角・半角に限らず、常に 2 バイト長です。このデータを表記するときは、シングルコーテーション( ' ' )でデータをくくります。

  string 型は、可変長の文字列を扱うときのデータ型で、これも Unicode 文字列です。このデータを表記するときは、ダブルコーテーション(" ")を使います。

 この文字列データも .NET Framework の Common Type System に準拠したものですが、.NET Framework では実行時の文字列操作は、Unicode として扱います。ただし、プログラムのソースコードは、その OS のネイティブな文字セットを使うことができます(日本語 Windows 環境では、ShiftJIS )。例えば、以下のようなプログラムも、日本語 Windows 環境では、既定では ShiftJIS の文字セットとして保存されます。このソースプログラムを C# コンパイラでコンパイルすると、文字列「"Hello, world!"」は、Unicode 文字列に変換されます(文字列の操作については、別途、2-5 「文字列」で扱います)。また、メモ帳などで、Unicode としてソースプログラムを保存し、それをコンパイルすることもできます。

[例]文字列の代入

  
    string str = "Hello, world!";
  

●日付・時間について

 日付や時間のデータ型について、C# では専用のキーワード(予約語)は用意されていません。しかし、Base クラスライブラリには、DateTime クラスや TimeSpan クラスなど、日付や時間を簡単に操作できる便利なクラスが用意されており、もちろん C# でも、これらのクラスを C# プログラムで利用することができます(これらを利用するには、第 4 章「クラスの定義と実装」で扱うクラスの知識が必要です。日付や時間の操作を学びたい場合、第 4 章まで学習した後、Base クラスライブラリ関連のレファレンスマニュアルをご覧ください)。

● bool

  bool 型は、真偽値をもつデータ型であり、true か false のどちらかの値しかとりません。プログラムの流れを変化させるフラグなどで利用できます。

<ワンポイント>

● for C++

  C# の真偽値である bool 型の値は、C++ の条件式で使う値のように、整数の 0、1、または -1 で置き換えられる値ではありません。あくまで独立したデータ型であり、bool 型に代入できる値は、true と false という値だけです。この 2 つの値もキーワード(予約語)です。

2-2-2  変数の宣言

  C# では、データを格納する器(うつわ)である変数の宣言方法は、C/C++ に似ています。以下のように、表 2-1 にあったデータ型を記述したのち、変数名を記述します。変数名は、大文字と小文字が区別されるので、「abc」という名前の変数と「Abc」という名前の変数は異なる変数として扱われます。

データ型 変数名 ;

[例]変数の宣言

  
int x;
char Abc;

 変数には初期値を設定することもでき、変数宣言のタイミングで、「=」演算子をともなって、初期値を代入できます。また、複数の変数をまとめて列挙することもできます。

[例]変数の初期化、複数の宣言

  
int x = 10;
int a=10, b=20, c;
<ワンポイント>

● for VB6

 従来の Visual Basic (以下、VB )とは異なり、変数は必ずあらかじめ宣言していなければ、その変数を利用することはできません。

 また、従来の VB では、以下のような書き方をすると、最後の変数 c だけが Integer 型になり、他は既定の Variant 型になってしまいました。

Dim a, b, c As Integer 'c だけが Integer

  VB では、すべてを Integer 型にするためには、すべての変数について型を指定する必要がありました。

Dim a As Integer, b As Integer, c As Integer

 しかし、C# では先頭に宣言したデータ型ですべての変数のデータ型が決まります。

int a, b, c; // すべての変数が int

 なお、この変数の宣言は、クラス内であればどこでも宣言できますが、その宣言の場所によって、その変数の役割が変わります。宣言する場所については、次項で扱います。

2-2-3  ローカル変数とメンバ変数

 クラス内であれば、変数はどこでも宣言できますが、括弧 {} のブロック内で宣言された場合、そのブロック内だけで有効です。

 宣言箇所で大きく 2 つに分類すると、「クラス内に直接宣言する変数」と「メソッド内に宣言する変数」に分類できます。

 クラス内に宣言する変数を、一般的な用語では「メンバ変数」とよび、C# では「フィールド」とよんでいます。フィールドは、クラス内の複数のメソッドからアクセスすることができます。フィールドについての詳しい内容を理解するには、クラスの概念が必要なので、第 4 章「クラスの定義と実装」で改めて扱います。

 メソッド内に宣言する変数を「ローカル変数」とよび、そのメソッド内でのみ利用できます。ローカル変数を利用する場合、その変数を参照する地点よりも前に宣言してあれば、どこに宣言してあっても構いません。

 次に例を示します。このプログラムを完全に理解するには、クラスに関わるさまざまな知識が必要です。第 4 章でクラスの話が登場するまでは、しばらくローカル変数だけを扱います。

[例]フィールドとローカル変数

  
 1: namespace MySpace
 2: {
 3:  public class MyApp
 4:  {
 5:   public static int x; // フィールド
 6:   public int y = 0;  // フィールド
 7:   public static void Main(string [] args)
 8:   {
 9:    int abc = 100; // ローカル変数 abc 宣言
10:    x = 150; // フィールド x に値代入
11:    System.Console.WriteLine(abc); // 変数 abc 参照
12:   }
13:   public static void f()
14:   {
15:    x = 10; // フィールド x に値代入
16:   }
17:  }
18: }

 前記のプログラムの 9 行目には、ローカル変数 abc が宣言してあります。この変数は Main メソッドの中に宣言してあるので、Main メソッド以外からは利用することはできません。まさに変数 abc は、Main メソッド内の「ローカルな」変数といえます。

2-2-4  定数表記

 変数に値を代入したり、計算式などに表記するデータ(定数)は、データ型に応じてさまざまです。C/C++ に似たところもありますが、decimal など固有の書き方もあります。以下に、主な定数の表記例を示します(表 2-2 )。

●表 2-2 ● 定数の使用例


(タイプ)
分 類 内 容 備 考
sbyte 値 型 整 数 符号あり 1 バイト - 128 ~ 127
short 符号あり 2 バイト - 32768 ~ 32767
int 符号あり 4 バイト - 231~ 231- 1
long 符号あり 8 バイト - 263~ 263- 1
byte 符号なし 1 バイト 0 ~ 255
ushort 符号なし 2 バイト 0 ~ 65535
uint 符号なし 4 バイト 0 ~ 232- 1
ulong 符号なし 8 バイト 0 ~ 264- 1
float 浮動小数点 IEEE754 準拠 4 バイト ± 1.5 × 10- 45~± 3.4 × 1038
double IEEE754 準拠 8 バイト ± 5.0 × 10- 324~± 1.7 × 10308
bool 論理型 値は true か false のみ
char Unicode 文字( 2 バイト) 引用符は ' '
decimal 10 進数データ型 ± 1.0 × 10- 28~± 7.9 × 1028
object 参照型 すべての型のベース型
string BSTR 型 Unicode 文字列 引用符は" "

 整数については、通常の 10 進数で表記できるほか、0x をつけることで 16 進数で表記できます。また、英字の大文字か小文字のエルを語尾につけると、明示的に long 型を表します。そのほか表が示すとおり、「u」や「ul」をつけると、それぞれ該当するデータ型として扱われます。

 この整数表記に何も語尾をつけないときは、コンパイラは int、uint、long、ulong の順に照らし合わせて、値を格納可能な大きさのバイト長をもつデータ型として扱います。

 浮動小数点は、大文字・小文字を問わず、語尾に「d」か「f」をつけます。何も語尾につけなければ、double とみなされます。

  bool については、既に説明したように「true」か「false」という 2 つの値表記しかもちません。

  decimal 型の定数には、大文字・小文字を問わず「m」をつけます。

 文字については、1 文字か可変長文字列かによって、シングルコーテーションかダブルコーテーションかを使い分けるので注意が必要です。また、制御文字を char 型や string 型で利用することができます。前述の表中にある string 型の定数の「\n」は改行を表します。制御コードは「エスケープシーケンス」とよばれる表記方法をします。

 次に、エスケープシーケンスの表記例を示します(表 2-3 )。

●表 2-3 ● エスケープシーケンス一覧


文字の意味 コードの値(括弧内は 10 進数表記)
\n 改 行 0x000a ( 10 )
\r 復 帰 0x000d ( 13 )
\t タ ブ 0x0009 ( 9 )
\' シングルコーテーション 0x0027 ( 39 )
\" ダブルコーテーション 0x0022 ( 34 )
\\ \ マーク 0x005c ( 92 )
\0 ヌル文字 0x0000 ( 0 )
\a ビープ音 0x0007 ( 7 )
\b バックスペース 0x0008 ( 8 )
\f 改ページ 0x000c ( 12 )

 エスケープシーケンスには、\ を利用します。そのため、文字列で以下のようにパスを表記すると、正しいパスになりません。

[例]誤ったパスの表記

  
C:\bookstore\files\news.txt

 このままだと、文字列の中の「\b」、「\f」、「\n」が制御コードとみなされるからです。これを正しいパスにするには、エスケープシーケンスの表にあるように、\ マークを 2 つ続けることで、\ マーク自体を表します。

[例]正しいパスの表記

  
C:\\bookstore\\files\\news.txt

 また、C# にはエスケープシーケンスを無効にする表記もあります。以下のように「@」をつけて表記すると、エスケープシーケンスは作用せずに、\ マークもそのままのデータとして扱われます。

[例]エスケープシーケンスの解除

  
@"C:\bookstore\files\news.txt"

 この項の最後として、エスケープシーケンスに関する完成した例をあげておきます。

[例]エスケープシーケンス

  
 1: namespace MySpace
 2: {
 3:  public class MyApp
 4:  {
 5:   public static void Main(string [] args)
 6:   {
 7:    string s = "C:・・bookstore・・news.txt";
 8:    string t = @"C:・bookstore・news.txt";
 9:    System.Console.WriteLine(s);
10:    System.Console.WriteLine(t);
11:   }
12:  }
13: }

単純な二重引用符では¥マークが特別な意味を持ちます