パスワードを忘れた? アカウント作成
14273280 journal
日記

yumeの日記: C#学習 10 4

日記 by yume

コメントありがとうございます。

++C++;

●組込み型変換
・数値の暗黙的な型変換。精度が変換しても値の精度が失われない場合のみ、代入することで自動的に変換する。
short m = 365;
long n = m; //short から longへ暗黙的な型変換
・数値の明示的な型変換。暗黙でできない型変換は「キャスト」することで明示的に変換する。
・文字列を数値化する場合はParseを使う。
・演習問題3つ

  static void Main()
                {
                        Console.WriteLine("A:文字を文字コードへ変換");
                        Console.WriteLine("B:整数小数除算比較");
                        Console.WriteLine("C:切り詰めチェック");
                        Console.Write("モードを選択:");
                        string inputOrder = Console.ReadLine().ToUpper();

                        switch (inputOrder)
                        {
                                case "A": modeA(); break;
                                case "B": modeB(); break;
                                case "C": modeC(); break;
                        }

                        Console.Write("終了しますか?(y/n):");
                        string inputEndAnswer = Console.ReadLine().ToUpper();
                        if (inputEndAnswer == "N") Main();
                }

                static void modeA()
                {
                        Console.Write("文字を入力:");
                        string inputString = Console.ReadLine();
                        char stringToChar = inputString[0];
                        int charToInt = (int)stringToChar;
                        Console.WriteLine("文字{0}の文字コードは{1}", stringToChar,charToInt);
                }

                static void modeB()
                {
                        Console.Write("整数を入力:");
                        string inputLeft = Console.ReadLine();
                        Console.Write("もう一度:");
                        string inputRight = Console.ReadLine();
                        int intAnswer = int.Parse(inputLeft) / int.Parse(inputRight);
                        decimal decimalAnswer = decimal.Parse(inputLeft) / decimal.Parse(inputRight);
                        Console.WriteLine("整数除算結果:{0}", intAnswer);
                        Console.WriteLine("小数除算結果:{0}", decimalAnswer);
                }

                static void modeC()
                {
                        Console.WriteLine("切り捨てテスト:");
                        double[] testArray = new double[10];
                        int[] intArray = new int[10];
                        testArray[0] = -1.9;
                        for(int i = 1; i < testArray.Length; i++)
                        {
                                testArray[i] = testArray[i - 1] + 0.5;
                        }
                        for(int i = 0; i < testArray.Length; i++)
                        {
                                intArray[i] = (int)testArray[i];
                                Console.WriteLine("double:{0} / int:{1}", testArray[i], intArray[i]);
                        }
                }

>コメントいただいたswitch風に書こうと思ったものの、書き方がわからない=学習していない要素があるみたい なので、公式ドキュメントから書き方を見て、素直に書いた。

●オーバーフローのチェック
・ある数値型が扱える数の範囲を超えること。
・範囲を超えると、想定外の数値が出てくる恐れがある。例えばsbyteでは64 + 65 = -127になってしまう。
・checkedキーワードを使えば、その中の整数型の計算でオーバーフローあった場合、例外(System.OverflowException)が出る。
checked
{
    //計算など
}
・uncheckedキーワードもある。ブロック内のオーバーフローを無視する。
・浮動小数点数型の場合、オーバーフローはinfinity(正方向、オーバーフロー)か0(負方向、アンダーフロー)になる。
・checkedでも例外が出ない。

●定数
・同じリテラルを何度も書くなら、定数を定義しておくとよい。
const 型名 変数名 = リテラル; //当然、宣言時に値を入れる。
・クラスのメンバーにすることもできる
>まだちょっとわからない。ローカル変数(ローカル定数)ではなく、グローバル変数(グローバル定数)的なものか。
・クラスのメンバーなら、readonlyもある。定数ではなく、読み取り専用変数。 readonly 型名 変数名;
>微妙に使い勝手が違うらしい。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by yume (47405) on 2020年08月21日 0時26分 (#3873848) 日記

    switch文については
    ++C++;のis、switch の拡張 (型スイッチ) [ufcpp.net]のページに書いてありました。
    ・これはswitch文ではなく、switch式
    ・式だから、戻り値(式だから計算結果があるわけだ)が必須

    今回のコードの、switch文を以下のように書きなおし

    var result = inputOrder switch
    {
        "A" => modeA(),
        "B" => modeB(),
        "C" => modeC(),
          _ => -1,
    };
    if (result == -1) Console.WriteLine("そんなモードないです");

    さらに、各modeメソッドをvoidからintにして、return 0を書くことで、実際に動作しました。

  • by Anonymous Coward on 2020年08月21日 10時33分 (#3873976)

    もっとも見たいのは、先日あなたが宣言した、目標とするアドベンチャーゲームの作成のためのストーリー(は既にあるとのことですのが)とその実装です。
    設問への回答が自然言語記述式なのか、選択肢式なのか、どうお考えなのかはわかりませんが、その野心に感動しました。

    率直に申し上げてC#だろうがLispだろうがProrogだろうがFortranだろうが、言語などに拘泥せず実装までこぎつけることが大切と存じます。
    言語習得が主題だからプログラムを最後まで作らなくていいんだ、これは俺の男坂(次作未定)というようなのは勘弁してちょんまげ

    と、言われるとへそを曲げるかやる気をなくすのが戦後昭和から令和人間ですが、それでも慫慂せざるを得ません。
    しかしC#が主題ですから、そのこだわりはございましょうが、実際のところはやりたいことがあれば言語の差異などびっくりするほど問題になりません。
    前世紀、ベーシック誌になぜかPEEK,POOK文ばかりだったり、IO誌に16進数のダンプばかりが掲載されていたゆえんであります。
    ほんとに頑張ってください。

    言語習得なんてやりたいことがあれば即おわります。

  • by Anonymous Coward on 2020年08月21日 11時08分 (#3874011)

    Parse() を使うときは、try catch で囲うといいですよ。
    数値に変換できない場合、Exception が throw されますので。

    それがいやな場合、
    public static bool TryParse (string s, out int result);

    を使うのもあります。

    あと気になったのは、除数の 0 チェックかな。
    勉強だからそこはオミットしたでもいいのですが、こういう特別な場合の処理を書く癖をつける
    (書かないと気持ちが悪いと感じる)ようになると、少しいいかなと思いました。

    • by Anonymous Coward

      こういう特別な場合の処理を書く癖をつける
      (書かないと気持ちが悪いと感じる)ようになると、少しいいかなと思いました。

      なんかそんな機能あったなと思って調べてみたら、コードコントラクト [microsoft.com]は失敗だったらしい。 [infoq.com]

typodupeerror

ハッカーとクラッカーの違い。大してないと思います -- あるアレゲ

読み込み中...