今週の話題

販売本数ランキング 今回トップも「スーパーマリオブラザーズ ワンダー(Switch)」GO!
2024年リリースの「Unity 6」公開…パフォーマンス大幅向上やAIサポートの強化―AIツール「Unity Muse」、開発管理ツール「Unity Cloud」も早期アクセス開始 GO!
IP戦略が奏功の任天堂、過去最高益を達成―次なる一手『ゼルダの伝説』映画化にも本気【ゲーム企業の決算を読む】GO!
『RPG Maker Unite』で3Dダンジョンが作成できる公式DLC「アドオン 3Dダンジョン」配信!簡単に2Dと3Dの切り替えも可能、日本語チュートリアル映像も公開 GO!
米大学で『ゼルダの伝説 ティアキン』を使った機械設計のコースが開設…ゲーム内で乗り物をデザインし単位を貰う GO!
ホロライブの二次創作ゲームブランド「holo Indie」立ち上げ、有償配布をサポートへ!近日中に第1弾『ホロパレード』も配信 GO!
アトラス、2024年4月に初任給を30万円へ。社員の平均年収15%引き上げも実施―グローバル展開の好調を反映 GO!

一見、あのPS作品の”続編”がSteamに?しかし実態は…熱意溢れすぎたユーザーによる勝手なナンバリング二次創作―目的は「SIEの気を引くこと」か GO!
またもや『原神』リーク者に鉄槌!Xで配信前キャラを漏らしたユーザーに開示請求実施へ GO!
どんなゲームが”インディーゲーム”?「The Game Awards」のノミネート一覧発表きっかけに「どこからがインディーか」議論が勃発 GO!

前回のコメント

・練習問題がまだまだできていなかったので帰ったら必ず復習します

 是非。

・プログラムをいかに短くするか考える事が出来ず、解説をそのまま使ってしまった

 解説は細かめに書いていますが、作成例では「どこまで省けるか」の一例も示しています。
 あくまでも学習用の一例ですので、実際の開発業務では何パターンもの作成法から最適なものを選ぶことになります。
 まずは「なるほどー」と思っていただければ幸いです。

講義メモ:後半

p.69 オブジェクト型とボックス化

・クラス型は7章で、配列型は6章で、デリゲート型は12章で説明します

p.73 文字列型

・文字列の扱いはC、C++、C#、Javaでそれぞれ異なるので注意。
・C#ではstring型で扱うが、値型ではなく参照型になっている(p.40)
・値型の変数は型に合わせた大きさで、中に値を持つ。
・文字列は0文字以上で文字数無制限なので、型に合わせた大きさが取れない。よって、別途配置しておいて、
 その開始位置(メモリアドレス)を変数値とすることで解決している
・よって、文字列変数「string s」への代入式「s = "ABC"」は下記のように実行される
 ① 文字列"ABC"がメモリの空いている場所に配置される
 ② 配置場所のメモリアドレスが、変数sに代入される
※ p.73にインスタンス(オブジェクト)の説明があるが、7章で扱う
・参照型においては、型によって便利な仕掛けであるプロパティやメソッドが提供されている
・string型の場合:
 ・Lengthプロパティ:文字数を返す。例:Consle.Write(s.Length) ⇒ 3
 ・IndexOf(文字)メソッド:その文字が何文字目にあるかを返す(先頭は0)。例:Consle.Write(s.IndexOf('C') ⇒ 2
 ・IndexOf(文字列)メソッド:その文字列が何文字目からあるかを返す(先頭は0)。例:Consle.Write(s.IndexOf("BC") ⇒ 1
・また、6章で説明する配列の構文を利用して、文字列の何文字目かの文字を得られる(先頭は0)。例:Consle.Write(s[2]) ⇒ C
・また、8章で説明する静的メソッドを持っており、文字列変数② = String.Copy(文字列変数①); とすることで、
 文字列のコピーができる

p.73 string01.cs

//p.73 string01.cs
using System;
class string01
{
    public static void Main()
    {
        string str = "今日はよい天気です";
        string mystr;
        char c;
        // Lengthプロパティで文字列の長さを調べる
        Console.WriteLine("strは長さ{0}です", str.Length); //9
        //文字型変数cに文字列strの5番目の文字を代入
        c = str[4];
        Console.WriteLine("文字列の5番目の文字は「{0}」です", c); //「い」
        //文字列strをmystrにコピー
        mystr = String.Copy(str);
        Console.WriteLine("mystr = {0}", mystr); //「今日はよい天気です」
        //文字列の検索
        int n = str.IndexOf('は'); //下記では先頭が0なので1加えて1番目からにしている
        Console.WriteLine("文字列に'は'が出てくるのは{0}番目の文字", n + 1); //3
        n = str.IndexOf("よい"); //下記では先頭が0なので1加えて1番目からにしている
        Console.WriteLine("文字列に「よい」が出てくるのは{0}文字目から", n + 1); //4
    }
}

p.75 is演算子とas演算子

・まだ学習していない参照型のみを対象としているので、説明は割愛します

p.78 練習問題1 ex0301.cs ヒント

・Main()メソッドの中は、Console.WriteLine("1年は{0}秒", 計算式); の1行のみで良い

作成例

//p.78 練習問題1 ex0301.cs
using System;
class ex0301
{
    public static void Main()
    {
        Console.WriteLine("1年は{0}秒", 365 * 24 * 60 * 60);
    }
}

p.78 練習問題2 ex0302.cs ヒント

①Console.ReadLine()で円の半径を文字列(string型)で得る ⇒ p.34
②文字列を実数(double型)に変換して半径を得る ⇒ p.45
③面積を「半径×半径×Math.PI」で得て表示する

作成例

//p.78 練習問題2 ex0302.cs
using System;
class ex0302
{
    public static void Main()
    {
        string s; //入力用
        Console.Write("半径:"); s = Console.ReadLine(); //文字列を読み込む
        double r; //半径
        r = double.Parse(s); //実数に変換
        Console.WriteLine("半径{0}の円の面積は{1}", r, Math.PI * r * r); //表示
    }
}

作成例・ショートバージョン

//p.78 練習問題2 ex0302.cs
using System;
class ex0302
{
    public static void Main()
    {
        Console.Write("半径:");
        double r = double.Parse(Console.ReadLine()); //半径を文字列で読み込み実数に変換
        Console.WriteLine("半径{0}の円の面積は{1}", r, Math.PI * r * r); //半径と面積を表示
    }
}

第4章 演算子

p.79 式と演算子

・加算などの演算を示す記号や単語を演算子といい、1つまたは2つまたは3つの情報を得て1つの結果を返す
・この情報をオペランド(項)といい、1つだと単項演算子、2つだと2項演算子という。
・演算子には、計算結果を返す算術演算子、比較結果を返す関係演算子、論理演算を行う論理演算子などがある
・「=」も演算子で、代入演算子で、2項=演算子という。
・演算子を含む式は評価されて1つの結果を返す(算術演算子の場合は計算が評価)
・これを式の評価(式の値)という
・よって式「d = 5 + 2」は、2項+演算子による「5 + 2」の評価である「7」を、2項=演算子によってdに代入している。
 また、その評価は代入値である「7」となる。
・これでわかるように、2項+演算子の方が2項=演算子より優先されている(詳細はp.97)

p.80 expression01.cs

// p.80 expression01.cs
using System;
class expression01 {
    public static void Main() {
        int a = 0;
        Console.WriteLine("a = {0}", a);
        //代入式を指定するとその評価(値)を表示できる(代入では代入値)
        Console.WriteLine("(a = 7)の値は{0}", a = 7); //7となる
    }
}

p.81 算術演算子

・すでに学習した2項+演算子、2項-演算子、2項*演算子、2項/演算子で加減乗除算が可能
・加えて、2項%演算子(剰余算 p.84)、単項++演算子(インクリメント p.85)、単項--演算子(デクリメント p.85)がある
・2項+演算子は加算と結合の2つの演算が可能で、これを演算子のオーバーロード(多重定義)という
・2項+演算子は、2項の両方が加算可能であれば加算し、どちらかまたは両方が文字列ならば連結する

提出:p.78 練習問題2

講義メモ

・p.62「Dynamic型」から

提出フォロー:アレンジ演習:p.56 escape01b.cs

・4つある変数をすべてvar型にして動作を確認しよう

作成例

//アレンジ演習:p.56 escape01b.cs
using System;
class escape01
{
    public static void Main()
    {
        var n = '\n'; //【変更】文字変数を改行文字で初期化(char型)
        var str1 = "今日は"; //【変更】文字列変数(string型)
        var str2 = "よい天気です"; //【変更】〃(string型)
        Console.WriteLine(str1 + n + str2); //文字列と改行文字を連結すると文字列になる
        var str3 = "今日は\nよい天気です"; //【変更】途中に改行文字のある文字列(string型)
        Console.WriteLine(str3); //表示すると途中で改行する
        Console.WriteLine("\"Let's Go\"は\\1000です"); //「\"」「\\」が必要
    }
}

p.62 dynamic型

・var型は初期化が必要で、初期化に用いた値の型によって型が決まる
・よって、型が未定義状態にはならない。
・型を未定義状態にしておいて、代入によって決まるようにするのがdynamic型
・VS2022での利用には、ソリューションエクスプローラーで「参照」を右クリックし「参照の追加」で参照マネージャを起動。
 「Microsoft CSharp」のチェックをオンにして「OK」

p.63 dynamic01.cs

//p.63 dynamic01.cs
using System;
class Dynamic01 {
  public static void Main() {
    dynamic x = 10, y = "abc", z; //dynamic型の変数は初期化しなくても良い
    z = 1.25; //代入によって型を定めることもできる
    Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32(int)
    Console.WriteLine("y ---- {0}", y.GetType()); //System.String(string)
    Console.WriteLine("z ---- {0}", z.GetType()); //System.Double(double)
  }
}

アレンジ演習:p.63 dynamic01.cs

・初期化も代入もしていないdynamic型の変数にGetType()を行うとどうなるか確認しよう
・また、初期化または代入の後のdynamic型の変数に、型の違う値を代入するとどうなるか確認しよう
・加えて、nullを代入し、表示とGetType()を行うとどうなるか確認しよう

作成例

//アレンジ演習:p.63 dynamic01.cs
using System;
class Dynamic01 {
  public static void Main() {
    dynamic x = 10, y = "abc", z; //dynamic型の変数は初期化しなくても良い
    //Console.WriteLine("z ---- {0}", z.GetType()); //【追加】初期化も代入もしてないのでエラーになる
    z = 1.25; //代入によって型を定めることもできる
    Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32(int)
    Console.WriteLine("y ---- {0}", y.GetType()); //System.String(string)
    Console.WriteLine("z ---- {0}", z.GetType()); //System.Double(double)
    //【以下追加】
    x = "ABC"; //初期化済みのdynamic型の変数に型が異なる値を代入できる
    Console.WriteLine("x ---- {0}", x.GetType()); //System.String(string)に代わっている
    z = 'Z'; //代入によって型を変えることもできる
    Console.WriteLine("z ---- {0}", z.GetType()); //System.Char(char)に代わっている
    y = null; //nullを代入できるが…
    Console.WriteLine("y ---- {0}", y); //なにも表示されない
    Console.WriteLine("y ---- {0}", y.GetType()); //異常終了する
  }
}

p.64 スコープ

・スコープは「視野」のことで、C#では変数などの有効範囲のこと
・「{」から「}」までをブロックという
・なお、classの「{」がクラスのブロックの開始で、Main()の「{」がMainのブロックの開始であり、最後の2つの「}」で
 それぞれのブロックの終わりを示す
・なお、必要に応じて、Main()の「{」から「}」のブロックの中に、さらにブロックを何重にも作成できる
・変数などの有効範囲は自分が定義されたブロックの中のみ
・C/C++などとはC#ではスコープが異なっても同じ名の変数は定義できない(移植時に注意)

p.65 型変換

・その型で扱える範囲が広いことを「型が大きい」といい、反対を「型が小さい」という
・「型が大きい」変数へ「型が小さい」変数や値を代入すると、大きい方に合わせた形で解釈され、無条件に代入可能。
 例: short s = 5; int i = s; //「型が小さい」short型から「型が大きい」int型への代入なのでOK
・これは値の大きさとは無関係で、例えば、long型の2はshort型に代入可能に思われるがエラーになる
・この場合は、型キャストを行って強制的に型変換させることも可能
・書式: (型)式や値
 例: long s = 5; short i = (short)s; //変数sの値をshort型に変換してから初期値とする
※ 型キャストが正しいかどうかはプログラマの責任で行う(コンパイラは警告しないことがある)。
※ 文字列型から整数型や実数型への型変換はキャストでは不可なので、parseメソッドを用いること(p.45)

p.66 cast01.csについて

・このプログラムは実行しても何も表示されない

アレンジ演習:p.66 cast01.cs

・aの値をbyte型の範囲を超える値にすると、どうなるか確認しよう
・また、キャストによって、元の変数の型は変わらないことを確認する処理を追記しよう

作成例

//アレンジ演習:p.66 cast01.cs
using System;
class cast01 {
    public static void Main() {
        long a = 500; //aの値をbyte型の範囲(0~255)を超えるものにしても
        byte b;
        b = (byte)a; //byte型へのキャストは可能だが
        Console.WriteLine("b = {0}", b); //244になってしまう(異常終了はしない)
        Console.WriteLine("aの型は{0}", a.GetType()); //System.Int64(long)で変わらない
    }
}

p.66 列挙型

・一連の整数値に名前をつけて扱う仕掛けが列挙で、グループの名前にあたるのが列挙名、グループのメンバーにあたるのが列挙子。
・定義書式: enum 列挙名 { 列挙子,… } //int型の列挙
・「列挙名:型」とすることで、sbyte、byte、short、ushort、uint、long、ulong型の列挙を定義することもできる列挙子
・列挙子には順に0から+1ずつ番号が振られるが「列挙子 = 整数」で任意の値に設定できる
・例:enum tuka { ichiendama = 1, goendama = 5, juendama = 10 };
・利用側は「列挙名.列挙子」で値を扱うことができる
・例:Console.WriteLine("5円玉は{0}", (int)tuka.goendama);
・C#やUnityが提供する特別な数値において、列挙型が用いられることが多い
 例:ConsoleColor 列挙型 { Black, DarkBlue, DarkGreen, DarkCyan, … }を色名して利用(p.106)
・列挙子のデータ型は列挙型になるので、整数としてあつかう時は型キャストすること
 例:Console.WriteLine("Blackの値は{0}", (int)ConsoleColor.Black);

p.68 enum01.cs

//p.68 enum01.cs
using System;
class enum01
{
    enum MyMonth { //月名の列挙の定義
        Jan = 1, Feb, Mar, Apr, May, Jun, Jul,
        Aug, Sep, Oct, Nov, Dec
    };
    public static void Main() {
        Console.WriteLine("Aprは{0}月", (int)MyMonth.Apr); //型キャストすると4になる
        Console.WriteLine("Mayは{0}月", (int)MyMonth.May); //型キャストすると5になる
    }
}

今週の話題

販売本数ランキング 今回トップも「スーパーマリオブラザーズ ワンダー(Switch)」GO!
カプコンはデジタル好調で増収増益、ただし『エグゾプライマル』で完全新作の難しさ露呈か【ゲーム企業の決算を読む】GO!
PS5新モデルが本日発売! 小型化されディスクドライブも着脱式に GO!
新発表のOLED版Steam Deckはあくまで「顧客意見を元にしたアップグレード」―次世代「Steam Deck 2」はまだ数年以上先、Valve改めて姿勢鮮明に GO!
「ゲーム業界と他業界のエンジニアは何が違う?」クリーク・アンド・リバーのエンジニア座談会11月16日開催 GO!
8年目を迎えるニンテンドースイッチ、これまでのライフサイクルに囚われることなく「新作タイトルの展開を続ける」GO!
『ティアキン』2,000万本秒読み、『マリカ8DX』や『スマブラSP』などミリオンタイトルが16本も…任天堂が24年3月期 第2四半期の決算資料を公開 GO!

【決算】コロプラの23年9月期決算は43%減益―『白猫プロジェクト』など主要IP盛り上げも売上は微減、新作の広告宣伝費も影響 GO!
今後ルール変更されても「遡及適用」もう行いません―Unity、利用規約更新で開発者の信頼回復図る GO!
人気タイトル独占や無料配布施策行うも「Epic Gamesストア」未だ利益出せず…立ち上げから約5年―しかし目標は依然として「成長」GO!

前回のコメント

・復習しといてよかったです

 何よりです。

・復習が必要になりそうな内容だと感じたため、復習を頑張ろうと思った

 是非。追加の解説が必要でしたらいつでもリクエストしてください。

講義メモ 後半

p.57 論理型

・C#はC言語とは異なり、真理値(真偽値)を表すための型としてbool型が提供されている
・また、bool型の変数に代入したり初期化などに利用できる論理型リテラルとして,true(真)、false(偽)が提供されている
・例: bool flag = true; //フラグをオンにする(立てる)
・なお、これに伴い、C/C++で可能な「非0を真とし、0を偽とする」ことはC#では禁止。
・bool型のNET型(p.42)は「System.Boolean」
・C#が提供する「変数名.GetType()」を用いると、その変数の.NET型情報を返してくれるので、これをConsole.WriteLineなどで
 表示することができる
・例: bool a; Console.Write(a.GetType()); //「System.Boolean」と表示
・C#が提供する「変数名.ToString()」を用いると、変数の内容を示す文字列を返してくれるので、これをConsole.WriteLineなどで
 表示することができる
・なお、bool型で値がtrueであれば「True」、falseであれば「False」となる。
・実は、ToString()は自動的に動作するもので「Console.Write(a); 」としても「True」が表示される

p.57 bool01.cs

//p.57 bool01.cs
using System;
class bool01
{
    public static void Main()
    {
        bool a = true;  //論理型の変数aを真で初期化
        bool b = false; //論理型の変数bを偽で初期化
        Console.WriteLine("a = {0}, b = {1}", a, b); //「a = True, b = False」と表示
        Console.WriteLine("aは{0}", a.GetType());//「aはSystem.Boolean」と表示
        Console.WriteLine("aは文字列にすると「{0}」", a.ToString()); //「True」と表示
        Console.WriteLine("bは文字列にすると「{0}」", b.ToString()); //「False」と表示
    }
}

アレンジ演習:p.57 bool01a.cs

・2行追加して「論理型変数 + 文字列」が可能かどうか、可能であれば型と結果を表示しよう

作成例

//アレンジ演習:p.57 bool01.cs
using System;
class bool01
{
    public static void Main()
    {
        bool a = true;  //論理型の変数aを真で初期化
        bool b = false; //論理型の変数bを偽で初期化
        Console.WriteLine("a = {0}, b = {1}", a, b); //「a = True, b = False」と表示
        Console.WriteLine("aは{0}", a.GetType());//「aはSystem.Boolean」と表示
        Console.WriteLine("aは文字列にすると「{0}」", a.ToString()); //「True」と表示
        Console.WriteLine("bは文字列にすると「{0}」", b.ToString()); //「False」と表示
        Console.WriteLine(a + "型です"); //【追加】「True型です」と表示
        Console.WriteLine((a + "型です").GetType()); //【追加】「System.String」と表示
    }
}

p.58 リテラル

・プログラム中に記述された値のこと、整数リテラル、実数リテラル、文字リテラル、文字列リテラル、論理リテラルがある。
・リテラルの型は表記法とサフィックス(接尾語)で決まる。
・整数リテラルはサフィックスがなければint型→uint型→long型→ulong型(値の大きさによる)。
 L/lを付けるとlong型、U/uを付けるとuint型、UL/ulを付けるとulong型。
・実数リテラルはサフィックスがなければdouble型。F/fを付けるとfloat型、M/mを付けるとdecimal型。
・文字リテラルはchar型
・文字列リテラルはstring型
・論理リテラルはbool型

p.59 Object.GetTypeメソッド

・前に「Object.」とつくものは、自動的に利用可能になっているメソッドなどを示す
・GetTypeメソッドの対象はリテラルや式でも良い
・なお、単項-演算子は優先度が低いのでカッコで囲み「(-10).GetType()」のように指定しすれば良い

p.60 literal01.cs

//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(int)
        Console.WriteLine(format, "100U",   100U.GetType()); //System.UInt32(uint)
        Console.WriteLine(format, "100L",   100L.GetType()); //System.Int64(long)
        Console.WriteLine(format, "100UL", 100UL.GetType()); //System.UInt64(ulong)
        Console.WriteLine(format, "1.25",   1.25.GetType()); //System.Double(double)
        Console.WriteLine(format, "1.25F", 1.25F.GetType()); //System.Single(float)
        Console.WriteLine(format, "1.25M", 1.25M.GetType()); //System.Decimal(decimal)
        Console.WriteLine(format, "10F",     10F.GetType()); //System.Single(float)
        Console.WriteLine(format, "10D",     10D.GetType()); //System.Double(double)
        Console.WriteLine(format, "10M",     10M.GetType()); //System.Decimal(decimal)
        Console.WriteLine();
        Console.WriteLine(format, "-10D", (-10D).GetType()); //System.Double(double)
    }
}

p.61 暗黙の型指定

・初期化によって型を確定できる場合、型名の代わりに「var」を指定すると、型が自動的に推定される
・例: var p = 3; //pはint型になる
・例: var f = true; //fはbool型になる
・なお、無を表すnullを初期値に出来るが、nullでは型を確定できないので対象外。
・どの型になったのかはGetType()メソッドで確認できる
※ varを積極的に利用するかどうかは実務ではチームルールで決めていることがある

【補足】p.62 var01.cs、p.63 dynamic01.csについて

・「public static int Main()」となっているが、この内容ではいつもの「public static void Main()」として良い
・合わせて「return 0;」は不要

p.62 var01.cs

//p.62 var01.cs
using System;
class var01
{
    public static void Main() //※テキストではintだがvoidで良い
    {
        var mytext = "猫でもわかるC#プログラミング 第"; //string型になる
        var no = 3; //int型になる
        var myc = '版'; //char型になる
        Console.WriteLine(mytext + no + myc); //連結してstring型になる
        Console.WriteLine("mytextの型は{0}で、noの型は{1}で、mycの型は{2}です",
            mytext.GetType(), no.GetType(), myc.GetType()); //String,Int32,Char
    }
}

提出:アレンジ演習:p.56 escape01b.cs

・4つある変数をすべてvar型にして動作を確認しよう

講義メモ

・p.52「type07.cs」から

p.50 decimal型(再掲載)

・decimalは10進数のことで、実数を内部的2進数で扱うfloat/double型に比べて、誤差が出づらい
・ただし、1個に128ビット用いるのでメモリの消費量に注意
・初期化に用いる実数値も同じ扱いをする必要があるので、末尾にMまたはmを付けて示す必要がある
 例: decimal d = 3.14M; //decimal型扱いの値で、decimal型の変数を初期化
・扱える値の範囲はdecimal.MinValueからdecimal.MaxValueで、float型より狭いが、long型より広い
・符号なしdecimal型は無い

p.52 type07.cs

//p.52 type07.cs
using System;
class type07
{
    public static void Main()
    {
        decimal total; //decimal型の変数の定義
        Console.Write("借入金額---");
        decimal a = decimal.Parse(Console.ReadLine()); //string型⇒decimal型変換
        Console.Write("利息(%)---");
        decimal p = decimal.Parse(Console.ReadLine()); //string型⇒decimal型変換
        decimal r = p / 100M; //decimal型の変数の演算なので100もdecimal型扱いにする
        total = a * (1m + r); //decimal型の変数の演算なので1もdecimal型扱いにする(1MでもOK)
        Console.WriteLine("1期間後の元利合計は{0:c}です", total); //通貨書式で表示
        a = total; //利息を加えた結果を次の元金とする
        total = a * (1m + r); //decimal型の変数の演算なので1もdecimal型扱いにする(1MでもOK)
        Console.WriteLine("2期間後の元利合計は{0:c}です", total); //通貨書式で表示
        a = total; //利息を加えた結果を次の元金とする
        total = a * (1m + r); //decimal型の変数の演算なので1もdecimal型扱いにする(1MでもOK)
        Console.WriteLine("3期間後の元利合計は{0:c}です", total); //通貨書式で表示
        a = total; //利息を加えた結果を次の元金とする
        total = a * (1m + r); //decimal型の変数の演算なので1もdecimal型扱いにする(1MでもOK)
        Console.WriteLine("4期間後の元利合計は{0:c}です", total); //通貨書式で表示
    }
}

p.53 文字型

・char型:1文字分の情報=Unicodeなので2バイト(16ビット)を持つデータ型
・文字リテラル:プログラム中で文字を記述するもの。'(シングルコーテーション)で囲む。
・初期化の書式: char 変数名 = '文字'; //例: char c = '猫';(C#は、ひらがな、漢字でもOK)
・Console.Write/WriteLineは文字型にも対応しているので、文字や文字型の変数をそのまま指定できる。

p.54 type08.cs

// type08.cs
using System;
class type08
{
    public static void Main()
    {
        char a = '猫', b = 'で', c = 'わ', d = 'か', e = 'る',
            f = 'C', g = '#', h = 'プ', i = 'ロ', j = 'グ',
            k = 'ラ', l = 'ミ', m = 'ン', n = 'グ'; //文字型の変数の初期化
        Console.Write(a); //改行せずに表示
        Console.Write(b);
        Console.Write(c);
        Console.Write(d);
        Console.Write(e);
        Console.Write(f);
        Console.Write(g);
        Console.Write(h);
        Console.Write(i);
        Console.Write(j);
        Console.Write(k);
        Console.Write(l);
        Console.Write(m);
        Console.Write(n);
        Console.WriteLine(); //改行
    }
}

p.54(Unicode番号による指定)

・文字リテラルにおいて、\uで始まる16進数を'(シングルコーテーション)で囲むことで、Unicode番号による指定が可能
・例: char c = '猫'; ⇒ 例: char c = '\u732B'; //「猫」の文字コードは732B
・なお、「\u」の代わりに16進数を意味する「\x」をつけても同じ結果になる
・また、10進数に変換した結果の前に「(char)」をつけても同じ結果になる(シングルコーテーションは不要)
・この「(型)」をキャストといい、型変換をサポートとする。文字はOKだが、文字列には非対応なのでparseを用いる
・例: char c = '猫'; ⇒ 例: char c = (char)29483; //「猫」の文字コードは732B=10進数29483
・Console.Write/WriteLineのフォーマット指定子(p.28)は文字型にも対応しているので、type08.csのように1文字ずる列記する
 必要はない

p.54 type09.cs

//p.54 type09.cs
using System;
class type09
{
    public static void Main()
    {
        char a = '\u732B';    //Unicode指定
        char b = '\x3067';    //16進数指定
        char c = 'も';        //文字リテラル
        char d = (char)12431; //10進数指定
        char e = '\u304B';    //Unicode指定
        char f = '\x308B';    //16進数指定
        Console.WriteLine("{0}{1}{2}{3}{4}{5}", a, b, c, d, e, f);
    }
}

アレンジ演習:type08a.cs

・type09.csを参考にして、フォーマット指定子を用いて短くしよう
 ※「猫でもわかる」まででOK

作成例

//アレンジ演習:type08.cs
using System;
class type08
{
    public static void Main()
    {
        char a = '猫', b = 'で', c = 'も', d = 'わ', e = 'か', f = 'る'; //文字型の変数の初期化
        Console.WriteLine("{0}{1}{2}{3}{4}{5}", a, b, c, d, e, f);
    }
}

p.55 エスケープ文字

・すでに学習した改行を示す「\n」などは文字と同じ扱いのエスケープ文字とされる
・シングルクォーテーションや、ダブルクォーテーション、円マークなどを文字として用いる場合は「\"」「\'」「\\」を用いると良い
・文字列の中に「\n」を挿入して、表示時に改行させることできる

p.56 escape01.cs

//p.56 escape01.cs
using System;
class escape01
{
    public static void Main()
    {
        char n = '\n'; //文字変数を改行文字で初期化
        string str1 = "今日は"; //文字列変数
        string str2 = "よい天気です"; //〃
        Console.WriteLine(str1 + n + str2); //文字列と改行文字を連結すると文字列になる
        string str3 = "今日は\nよい天気です"; //途中に改行文字のある文字列
        Console.WriteLine(str3); //表示すると途中で改行する
    }
}

アレンジ演習:p.56 escape01a.cs

・1行追加して、文字列「"Let's Go"は\1000です」がこの通り表示できるように指定しよう

作成例

//アレンジ演習:p.56 escape01a.cs
using System;
class escape01
{
    public static void Main()
    {
        char n = '\n'; //文字変数を改行文字で初期化
        string str1 = "今日は"; //文字列変数
        string str2 = "よい天気です"; //〃
        Console.WriteLine(str1 + n + str2); //文字列と改行文字を連結すると文字列になる
        string str3 = "今日は\nよい天気です"; //途中に改行文字のある文字列
        Console.WriteLine(str3); //表示すると途中で改行する
        Console.WriteLine("\"Let's Go\"は\\1000です"); //【追加】「\"」「\\」が必要
    }
}