講義メモ ・p.89「論理関係演算子」の条件演算子を用いるミニ演習から p.89 論理関係演算子(再掲載) ・2つのbool型の値による演算でbool型を得るのが論理関係演算で、論理積と論理和がある。 ・2項&&演算子:左辺と右辺が論理値の時に、その論理積をbool型で返す。  論理積とは、両方がtrueであればtrue、でなければfalse。  よって2条件の「かつ」を表すときに利用する  例: (a > b) && (a > c) //aがbより大、かつ、aがcより大ならtrueを返す、でなければfalseを返す  例: (a >= 20) && (a <= 60) //aが20以上、かつ、aが60以下ならtrueを返す、でなければfalseを返す。    つまり、aが20以上60以下ならtrueを返す。 ・2項||演算子:左辺と右辺が論理値の時に、その論理和をbool型で返す。  論理和とは、両方がfalseであればfalse、でなければtrue。  よって2条件の「または」を表すときに利用する  例: (a > b) || (a > c) //aがbより大、または、aがcより大ならtrueを返す、でなければfalseを返す  例: (a <= 20) || (a >= 60) //aが20以下、または、aが60以上ならtrueを返す、でなければfalseを返す。    つまり、aが20以下か60以上ならtrueを返す。 ミニ演習 mini089a.cs ・コンソールから整数2値をint型変数a、bに入力する ・どちらも正の数であれば「aは正、かつ、bも正」と表示する ・また、どちらかまたは両方が正の数であれば「aは正、または、bは正」と表示する ・論理関係演算子と条件演算子を用いること ・ヒント:該当しない場合は""を表示すれば良い 作成例 //ミニ演習 mini089a.cs using System; class mini088a { public static void Main() { Console.Write("整数a : "); int a = int.Parse(Console.ReadLine()); Console.Write("整数b : "); int b = int.Parse(Console.ReadLine()); Console.Write((a > 0 && b > 0) ? "aは正、かつ、bも正\n" : ""); Console.Write((a > 0 || b > 0) ? "aは正、または、bは正\n" : ""); } } p.89 否定演算子 ・論理否定ともいい、右辺にbool型の式をおいてその反転を返す単項!演算子  例:!(a > 0) //aが正の数でなければtrue、であればfalseを返す ・複雑な条件式を反転したい場合に便利  例:!(a == 1 || a == 2 || a == 3) //「aが1、2、3」ではなければ   ⇒ (a != 1 && a != 2 && a != 3) と同じだが、前者の方が読みやすい ミニ演習 mini089b.cs ・コンソールから整数をint型変数aに入力する ・aが10以上20以下でなければ「範囲外」と表示しよう ・否定演算子と条件演算子を用いること 作成例 //ミニ演習 mini089b.cs using System; class mini088a { public static void Main() { Console.Write("整数a : "); int a = int.Parse(Console.ReadLine()); Console.Write(!(a >= 10 && a <= 20) ? "範囲外\n" : ""); } } p.89 ビット論理演算子 ・整数値を指定すると、ビット列に変換してビット毎に演算を行った結果のビット列を整数にして返す演算子 ・2項&演算子:2つの整数値をビット列に変換してビット毎に論理積を得た結果のビット列を整数にして返す ・論理積は1と1なら1、でなければ0になる(&&演算子に似ているが0/1を返す)  例:整数2は0000…0010、    整数3は0000…0011、 2 & 3は0000…0010 なので 2 ・2項|演算子:2つの整数値をビット列に変換してビット毎に論理和を得た結果のビット列を整数にして返す ・論理和は0と0なら0、でなければ1になる(||演算子に似ているが0/1を返す)  例:整数2は0000…0010、    整数3は0000…0011、 2 | 3は0000…0011 なので 3 ・2項^演算子:2つの整数値をビット列に変換してビット毎に排他的論理和を得た結果のビット列を整数にして返す ・排他的論理和は0と1、1と0なら1、でなければ0になる(|演算子に似ているが1と1の時に0を返すのが異なる)  例:整数2は0000…0010、    整数3は0000…0011、 2 ^ 3は0000…0001 なので 1 p.89 ビット論理演算子とbool型 ・2項&演算子、2項|演算子はbool型にも適用可能で、2項&&演算子、2項||演算子とほぼ同じ動作になるが、  短絡評価(後述)を行わないことが異なる ・2項^演算子もbool型に適用可能で、falseとtrue、trueとfalseならtrue、でなければfalseを返す アレンジ演習:p.90 bitwize01.cs ・最後の「y ^ y」の次に「!(y ^ y)」の結果を追記しよう 作成例 //アレンジ演習:p.90 bitwize01.csp using System; class bitwise01 { public static void Main() { byte a = 2, b = 3; //2は000000010、3は00000011 Console.WriteLine(a & b); //00000010 & 00000011 なので 00000010 ⇒ 2 Console.WriteLine(a | b); //00000010 | 00000011 なので 00000011 ⇒ 3 Console.WriteLine(a ^ b); //00000010 ^ 00000011 なので 00000001 ⇒ 1 Console.WriteLine(); bool x = true, y = false; Console.WriteLine(x & x); //true & true ⇒ true Console.WriteLine(x & y); //true & false ⇒ false Console.WriteLine(y & y); //false & false ⇒ false Console.WriteLine(); Console.WriteLine(x | x); //true | true ⇒ true Console.WriteLine(x | y); //true & false ⇒ ftrue Console.WriteLine(y | y); //false & false ⇒ false Console.WriteLine(); Console.WriteLine(x ^ x); //true ^ true ⇒ false Console.WriteLine(x ^ y); //true ^ false ⇒ true Console.WriteLine(y ^ y); //false ^ false ⇒ false Console.WriteLine(!(y ^ y)); //!(false ^ false) ⇒ !(false) ⇒ true } } p.91 ビット論理演算子:単項~演算子 ・整数値をビット列に変換して、全ビットを反転した結果のビット列を返す ・例: ~2 ⇒ 2は00000010だから、11111101 ・「整数値をビット列に変換して、全ビットを反転した結果」を補数(1の補数)という ・コンピュータ内部では補数+1を用いて負の数を表現しており、これを2の補数という ・これは元の値とその2の補数の和がオーバフローして0になることから、減算を「補数化して加算」で実装できることを示している ・例: 1 ⇒ 00000001 なので ~1 ⇒ 11111110 + 1 ⇒ 11111111 となり、これで-1を表す  すると、00000001 + 11111111 ⇒ 100000000 となり、最上位の1が消えて00000000となる。 p.90 短絡評価 ・短絡評価はショートサーキットの略で、論理関係演算子でつないだ条件式において、途中で全体の答えが確定してしまう時に、それ以降の演算を行わない仕組み  例: a = (a > 0 || b > 0) ? a : b; //これは「a > 0」であれば「b > 0」の演算は行わない。   理由:「a > 0 または b > 0」は「a > 0」であればbはなんであっても、全体がtrueになる ・この仕掛けにより、実行効率が上がることに加えて、安全性も向上する  例: a = (a != 0 && 5 / a > 1) … //これは「a == 0」であれば「5 / a > 1」の演算は行わない   理由:「a != 0 かつ 5 / a > 1」は「a == 0」であれば、全体がfalseになる   利点:「5 / a」はaが0だと異常終了してしまうが、↑こうしておけば「5 / 0」の演算は起こらない ・なお、2項&&演算子、2項||演算子においては短絡評価が行われるが、2項&演算子、2項|演算子においては行われない。  ※よって、2項&演算子、2項|演算子を、2項&&演算子、2項||演算子の代わりに用いることは推奨されず、ビット論理演算専用にすることが望ましい ミニ演習 mini090.cs ・コンソールから整数をint型変数aに入力する ・5 / aが1以上なら「5÷aは1以上」と表示しよう ・条件演算子を用いること ・短絡評価が行われる場合と、行われない場合の両方を試そう 作成例 //ミニ演習 mini090.cs using System; class mini088a { public static void Main() { Console.Write("整数a : "); int a = int.Parse(Console.ReadLine()); Console.Write((a != 0 && 5 / a >= 1) ? "5÷aは1以上\n" : ""); //短絡評価有り Console.WriteLine("aがゼロでもここまでは実行される"); Console.Write((a != 0 & 5 / a >= 1) ? "5÷aは1以上\n" : ""); //短絡評価無し Console.WriteLine("aがゼロならここは実行されず、手前で異常終了してしまう"); } } p.94 代入演算子:複合代入演算子 ・2項=演算子を代入演算子といい、基本的に左辺が変数であることが特徴 ・インクリメント演算子と同様に「変数に●を加算する」ような処理は頻出なので、複合代入演算子が提供されている ・複合代入演算子とは「変数 = 変数 演算子 式や値」を「変数 演算子= 式や値」と略記できる仕組み ・例: a = a + 2 ⇒ a += 2 //aに2を足しこむ ・例: a = a - 2 ⇒ a -= 2 //aから2を差し引く ・ちなみに、「++a」は「a += 1」と同じ結果になる ・複合代入演算子としては、算術演算の+=、-=、*=、/=、%=に加えて、論理演算の&=、|=、^=と、シフト演算の<<=、>>=が提供されている ミニ演習 mini095.cs ・コンソールから西暦4桁を入力すると、下2桁にしてから、表示するようにしよう  例: 1962 ⇒ 62にする ・入力した変数の値を複合代入演算子で操作すること 作成例 //ミニ演習 mini095.cs using System; class mini088a { public static void Main() { Console.Write("西暦4桁 : "); int a = int.Parse(Console.ReadLine()); a %= 100; //aを100で割った余りにする=下2桁にする Console.WriteLine("西暦下2桁 : " + a); } } p.95 代入演算子:暗黙の型変換 ・扱える範囲が広い型のことを「大きい型」といい、扱える範囲がこの範囲内に収まる型は「小さい型」という ・大きい型の変数に小さい型の式や値を代入すると、代入前に大きい型への変換が自動的に行われる ・このことを暗黙の型変換(拡大変換)という  例: int i = 10; long j = i; //iの値10をlong型に暗黙の型変換する ・ただし、decimal型への暗黙の型変換はできるが、decimal型からの暗黙の型変換はエラーになる ・また、byte型とsbyte型は、両方向共に変換できないので、キャストを用いる必要がある アレンジ演習:p.96 convert01.cs ・byte型とsbyte型は、両方向共に変換できないが、キャストを用いると可能なことを確認しよう 作成例 //p.96 convert01.cs using System; class convert01 { public static void Main() { byte a = 10; sbyte b; ushort c; short d; uint e; int f; ulong g; long h; float i; double j; decimal k; b = (sbyte)a; //byteをsbyteには変換できないがキャストすれば可能 b = 10; a = (byte)b; //sbyteをbyteには変換できないがキャストすれば可能 c = a; d = a; e = a; f = a; g = a; h = a; i = a; j = a; k = a; } }