講義メモ ・p.57 論理型(つづき) p.57 論理型(再掲載) ・真理値(真偽値)を扱える型で、1ビット分の記憶容量。 ・真理値(真偽値)は真を意味するtrue、偽を意味するfalseの2値のどちらかになる ・真偽には「正しい、ホント」「間違い、ウソ」という意味はなく「あてはまる」「あてはまらない」が近い。 ・論理型はbool型のみで、trueとfalseは論理リテラル。  ※ C/C++では「整数0で偽、0以外で真を表す」ことが可能だが、C#では禁止なので注意 ・論理型変数はフラグ用に用いられることがある。例: bool tested = false; //テスト済フラグをオフ ・論理型変数はtrueとfalseの2値以外を保持できないので、フラグなどの用途に向く ・なお、Console.Write/WriteLineでbool型変数の値を表示すると先頭が大文字のTrue/Falseとなる ・bool型は.NET型ではSystem.Boolean型になる 提出フォロー:アレンジ演習:p.57 bool01.cs ・bool型変数どうしの加算をするとどうなるか確認しよう ・文法エラーになったらコメントアウトすること ・同じ2項+演算子で「文字列 + bool型変数」の場合も確認しよう 作成例 //アレンジ演習:p.57 bool01.cs using System; class bool01 { public static void Main() { bool a = true; bool b = false; Console.WriteLine("a = {0}, b = {1}", a, b); Console.WriteLine("aは{0}", a.GetType()); Console.WriteLine("aは文字列にすると「{0}」", a.ToString()); Console.WriteLine("bは文字列にすると「{0}」", b.ToString()); //【以下追加】 //Console.WriteLine(a + b); //エラー(bool型どうしの加算は不可) Console.WriteLine("x" + b); //文字列とbool型の連結は可能("xFalse"になる) } } p.57 論理型:GetTypeとToString ・GetTypeの詳細はp.59にて ・bool型の変数に対して「変数.GetType()」とすると、.NET型の文字列"System.Boolean"を含むオブジェクトが返される ・Console.Write/WriteLineは文字列を含むオブジェクトを受け取ると、文字列を表示する ・ToStringの詳細はp.326にて ・bool型の変数に対して「変数.ToString()」とすると、.値がtrueならば文字"True"、falseならば文字"False"が返される ・GetTypeとToStringは論理型専用ではなく、基本的に全ての型において利用可能な仕組み p.58 3.9 リテラル ・リテラル:ソースコードの中に記述された値のこと ・整数リテラル、実数リテラル、文字列リテラル、文字リテラル、論理リテラルがある p.58 3.9 リテラル:整数リテラル ・整数値を表すリテラルで、10進数、8進数、16進数が利用可能 ・10進数の整数リテラル:0から9までの1つ以上の数字列で、先頭は1から9。例:123 ・8進数の整数リテラル:0から7までの1つ以上の数字列で、先頭に0を付ける。。例:0123 ・16進数の整数リテラル:0から9とAからFまでの1つ以上の数字列(小文字可)で、先頭に0xを付ける。例:0x1AF ・サフィックス(接尾語)をつけないとint型扱いになる ・サフィックスLまたはlを末尾につけるとlong型扱いになる(※通常「l」は非推奨) ・サフィックスUまたはuを末尾につけるとuint型扱いになる ・サフィックスULまたはulを末尾につけるとulong型扱いになる ・なお、sbyte、byte、short、ushort型扱いを示すサフィックスはない ・サフィックスをつけない整数リテラルが、int型の範囲である±約21億を超えてもエラーにならない。  ⇒自動的に、uint、long、ulongの順に範囲チェックを行い、最初に該当した型で扱われる  例: 2200000000⇒uint型扱い、-2200000000⇒long型扱い p.58 3.9 リテラル:実数リテラル ・実数値を表すリテラルで、通常表記、指数表記(●E±■)が可能。10進数のみ。 ・サフィックス(接尾語)をつけないとdouble型扱いになる(サフィックスDまたはdを指定可だが、推奨されない場合がある) ・サフィックスFまたはfを末尾につけるとfloat型扱いになる ・サフィックスMまたはmを末尾につけるとdecimal型扱いになる p.58 3.9 リテラル:補足:文字リテラル ・文字を表すリテラルで、シングルコーテーションで1文字を囲んだもの。半角文字、全角文字、エスケープ文字(p.55)を利用可能 ・文字リテラルはchar型扱いになる ・内部的には文字コード(番号)が格納されているので、後述するキャストによって文字コード(番号)を得たり、文字コード(番号)に該当する文字を得ることが可能 p.58 3.9 リテラル:補足:文字列リテラル ・文字列を表すリテラルで、ダブルコーテーションで0文字以上の文字の列を囲んだもの。エスケープ文字を含む全ての文字を利用可能 ・文字列リテラルはstring型扱いになる p.58 3.9 リテラル:補足:論理リテラル ・真偽を表すリテラルで、trueとfalseのみ ・論理リテラルはbool型扱いになる ・内部的には1ビットの情報量だが、0/1で表すことはできないので、後述するキャストによっても整数/実数型には変換できない(C/C++とは異なる) p.58 3.9 リテラル:GetTypeの詳細 ・GetTypeメソッドはObjectクラスに含まれるもので、Objectクラスは暗黙的に全てのクラスの基本クラスとなっているので、全クラスにおいてObjectクラスのもつメソッドが実行可能 ・そして、リテラルはそれぞれの該当する型を表す.NET型を示す構造体(p.275)のオブジェクトとみなされる ・GetTypeメソッドは.NET型を示す構造体をまとめているTypeクラスで扱えるオブジェクトを得て返す仕組み ・このオブジェクトの中に、.NET型を表す文字列が格納されている ・bool型の変数に対して「変数.GetType()」とすると、.NET型の文字列"System.Boolean"を含むオブジェクトが返されるように、すべての変数に対して型を表す文字列を得ることができる。 ・なお、リテラルの場合も同様で「リテラル.GetType()」とすると、リテラルを扱う型を表す文字列を得ることができる。  例:100.GetType() ⇒ System.Int32 が得られる  例:100U.GetType() ⇒ System.UInt32 が得られる p.60 literal01.cs:形式指定文字列の使いまわし ・Console.Write/WriteLineで利用する形式指定文字列は、文字列型の変数に格納して使いまわすことができる ・例: string s = "{0}倍"; Console.WriteLine(s, 3); //「3倍」と表示 アレンジ演習:p.60 literal01.cs ・整数リテラル2200000000の型情報を表示しよう(22億) ・整数リテラル-2200000000の型情報を表示しよう(-22億)※(-2200000000).GetType()とすること ・実数リテラル3.14E+3の型情報を表示しよう(3140だが…) ・文字リテラル、文字列リテラル、論理リテラルの型情報を表示しよう ・【正誤】005行目 Kiteral01 ⇒ Literal01 ※実行には影響しない 作成例 //p.60 literal01.cs using System; class literal01 { public static void Main() { string format = "{0}の型は.NET型で{1}です"; Console.WriteLine(format, "100", 100.GetType()); //System.Int32 Console.WriteLine(format, "100U", 100U.GetType()); //System.UInt32 Console.WriteLine(format, "100L", 100L.GetType()); //System.Int64 Console.WriteLine(format, "100UL", 100UL.GetType()); //System.UInt64 Console.WriteLine(format, "1.25", 1.25.GetType()); //System.Double Console.WriteLine(format, "1.25F", 1.25F.GetType()); //System.Single Console.WriteLine(format, "1.25M", 1.25M.GetType()); //System.Decimal Console.WriteLine(); Console.WriteLine(format, "10F", 10F.GetType()); //System.Single Console.WriteLine(format, "10D", 10D.GetType()); //System.Double Console.WriteLine(format, "10M", 10M.GetType()); //System.Decimal Console.WriteLine(); Console.WriteLine(format, "-10D", (-10D).GetType()); //System.Double //【以下追加】 Console.WriteLine(format, "2200000000", 2200000000.GetType()); //System.UInt32 Console.WriteLine(format, "-2200000000", (-2200000000).GetType()); //System.Int64 Console.WriteLine(format, "3.14E+3", 3.14E+3.GetType()); //System.Double Console.WriteLine(format, "文字A", 'A'.GetType()); //System.Char Console.WriteLine(format, "文字列ABC", "ABC".GetType()); //System.String Console.WriteLine(format, "true", true.GetType()); //System.Boolean } } p.61 3.10 暗黙の型指定 ・C#バージョン3.0以降において、初期化によって型が類推できる変数では、型を省略可能になった  ※ VS2022のC#のバージョンは11.0(最新内部バージョンでは13.0) ・この型がvarで、var型、または、varキーワードによる暗黙の型指定という ・定義書式: var 変数名 = 初期値; //型が類推できる初期値による初期化が必須  例: var a = 10; //aはint型扱いになる アレンジ演習:p.62 var01.cs ・定義済のvar型変数に、同じ型や、異なる型の値を代入するとどうなるか確認しよう。 ・【注記】Mainメソッドの戻り値型がvoidではなくintになり「return 0;」が追記されているが、この場合、必要性はないので、これまでの形式で良い。  ※これは、プログラムを呼び出した対象(例:OSや親システム)に実行結果を返したい場合の記述方法。 作成例 //アレンジ演習:p.62 var01.cs using System; class var01 { public static void Main() { var mytext = "猫でもわかるC#プログラミング 第"; //string var no = 3; //int var myc = '版'; //char Console.WriteLine(mytext + no + myc); Console.WriteLine("mytextの型は{0}で、noの型は{1}で、mycの型は{2}です", mytext.GetType(), no.GetType(), myc.GetType()); //System.String, System.Int32, System.Char //【以下追加】 no = 4; //int型扱いのnoに4を代入できる Console.WriteLine(mytext + no + myc); //myc = ".0版"; //char型扱いのmycに文字列は代入できない(文法エラー) } } p.62 dynamic型 ・C#バージョン4.0以降において、型が未確定の変数を定義可能になった。 ・この場合の型がdynamic型で、var型の上位概念に当たる。 ・dynamic型の変数は代入によって型が決まるので、便利だが実行効率はvar型より低くなる懸念がある ・定義済のdynamic型変数に、異なる型の値を代入すると型を変更できる(varとは異なりエラーにならない) ・ただし、内部的に、Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Createを用いるので、プロジェクトに下記の参照指定が必要  ⇒ Microsoft.CSharp ・手順  ①ソリューションエクスプローラで「参照」を右クリックし「参照の追加」  ②「Microsoft.CSharp」のチェックをオンにして「OK」 ・なお、var型と同様に、初期化によって型を決めることもできる アレンジ演習:p.63 dynamic01.cs ・「z = 1.25;」の前にz.GetType()を実行するとどうなるか確認しよう ・後で、x,y,zに別の型の値を代入できるかどうか確認しよう ・var型、dynamic型の定数が定義可能か確認しよう 作成例 //アレンジ演習:p.63 dynamic01.cs using System; class Dynamic01 { public static void Main() { dynamic x = 10, y = "abc", z; //この時点でxはInt32、yはString、zは未定 //Console.WriteLine("z ---- {0}", z.GetType()); //zは未定なので文法エラーになる z = 1.25; //この時点でzはDouble Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32 Console.WriteLine("y ---- {0}", y.GetType()); //System.String Console.WriteLine("z ---- {0}", z.GetType()); //System.Double //【以下追加】 x = 10; y = 'a'; z = 100M; Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32 Console.WriteLine("y ---- {0}", y.GetType()); //System.Char Console.WriteLine("z ---- {0}", z.GetType()); //System.Decimal //const var c = 10; //var型の定数は不可(文法エラー) //const dynamic d = 10; //dynamic型の定数は不可(文法エラー) const dynamic e = null; //ただし、値がnullであれば可能だが… Console.WriteLine("e ---- {0}", e.GetType()); //実行時エラーになってしまう } } p.64 スコープ ・スコープは「視野」「見える範囲」のことで、変数などの識別子の有効範囲を示す ・基本的に識別子が定義されたブロック{…}内が、そのスコープになる ・入れ子のブロックがある場合、内側のブロックもスコープに含まれる ・なお、C/C++などではスコープが異なれば同名の変数などの識別子が使えるが、C#では禁止。 p.64 scope01.cs 補足 ・このコードで分かるとおり、プログラマが自由にブロックを記述できる ・ブロックを記述することで、変数などの識別子のスコープを制限できる ・但し、必要がないスコープの記述はプログラムの可読性を大きく損なうので注意 p.64 scope01.cs //p.64 scope01.cs using System; class scope01 { //クラスのブロック public static void Main() { //Mainメソッドのブロック int a = 10; Console.WriteLine("a = {0}", a); //ここではaのみ有効 { //プログラマが作ったブロック int b = 5; Console.WriteLine("a = {0}, b = {1}", a, b); //ここではa.bが有効 { //プログラマが作ったブロック int c = 1; Console.WriteLine("a = {0}, b = {1}, c = {2}", a, b, c); //ここではa.b,cが有効 } //cが有効なのはここまで //ここではcは見えません Console.WriteLine("a = {0}, b = {1}", a, b); //ここではa.bが有効 } //bが有効なのはここまで //ここでは、b,cは見えません Console.WriteLine("a = {0}", a); //ここではaのみ有効 } } p.65 3.12 型変換 ・その型が扱える値の範囲を「型の大きさ」という。  例: sbyte型の大きさは-127~126 ・型が大きい変数に、型が小さい変数や値を代入すると、自動的に型が大きいほうに合わせてくれる ・これを暗黙の型変換という  例: int a; short b = 5; a = b; //bの値5を32ビット整数に暗黙変換して代入する ・よって、暗黙の型変換によるトラブルや誤差の発生は想定しなくて良い ・対して、型が小さい変数に、型が大きい変数や値を代入すると、文法エラーになる ・しかし、型が大きい変数や値であっても、型が小さい変数に代入できるのであれば、プログラマの責任で強制的に代入できる ・このための、強制的な型変換をキャスト(あるいは、型キャスト)という ・書式: (型)変数や値  例: short a; int b = 5; a = (short)b; //bの値5を16ビット整数に強制的に変換して代入する ・【正誤】p.66 上から5行目「b = (byte)2;」⇒「b = (byte)a;」 アレンジ演習:p.66 cast01.cs ・【注記】このプログラムは「Console.Write/WriteLine」がまったくないので実行しても何も表示されない ・bの値と、(byte)aの型を表示しよう ・型の大きさを超える値のキャストは可能かを確認しよう(例:(byte)5000)  ⇒ 5000はbyte型の範囲を超えるので文法エラーになる。  ⇒ ただし、byte型の範囲を超える変数値ではエラーにならず、異常値のまま実行されてしまうので注意 ・uint型とint型でのキャストは可能かを確認しよう ・ushort型とint型でのキャストは可能かを確認しよう ・実数リテラル3.9をint型にキャストするとどうなるか確認しよう ・整数3と4の平均値をdouble型へのキャストを用いることで小数点以下まで表示しよう 提出:アレンジ演習:p.66 cast01.cs(途中でもOK) 次回予告:p.66「3.13 列挙型」から