<<2..演算子と制御文の目次
論理演算子
問題20(難易度:2)                                 2004年12月6日
次をコンパイル実行したときの出力結果について、設問に答えよ。

    1: boolean b;
      2:  int k;
   3:  
      4:  b = k >= 0 && k++ != 3;
      5:  System.out.println("b=" + b + " k=" + k);

設問1 3行目が
      k = 5;
   の場合の出力結果を下から選べ。

  A: b=true k=5
  B: b=false k=5
  C: b=true k=6
  D: b=false k=6


設問2 3行目が
      k = -2;
   の場合の出力結果を下から選べ。

  A: b=true k=-2
  B: b=false k=-2
  C: b=true k=-1
  D: b=false k=-1
解説
 +や−などの数値についての演算子に対して、trueやfalseについて計算する演算子を論理演算子といいます。「かつ」を表す&&や「または」を表す||があります。この二つはちょっと近道をする演算子です。

 &&の場合、左側の式の値がtrueならば、右の式も調べますが、左側がfalseの場合は、右の式はtrueかfalseか調べずに、全体の結果をfalseであると結論付けてしまいます。図のようになります。
 
 ウルトラクイズなどで、不正解の人はどんどん抜けていきますよね。1問でも間違えたら次の問題の挑戦権はないわけで、これに似ています。

 では設問1のkが5の場合を考えてみましょう。左の「k>=0」はtrueですので、右の式も調べます。++はkの後ろに付いているので、まずは「k!=3」について調べます。kは3ではないのでtrue、左も右もtrueでbにはtrueが入ります。おっとkの後ろの++を忘れてはいけません。kは5から6になります。よって正解はC。

 設問2はkが−2です。左の「k>=0」がいきなりfalseなので、右の式はもう調べず、bにはfalseが入ります。ということはk++の++は行われず、kは−2のままということになります。よって正解はB。

 &&の右側に、変数の値が変わったりする副作用があるとき、「あれ!kが増えてないじゃないか、どうしたことだ」といったことが起こるので、気をつけましょう。

解答 設問1 C        設問2 B

参考 読み物Java 「第5章 白黒はっきりさせよう」
問題21(難易度:2)                                   2004年12月7日
次をコンパイル実行したときの出力結果について、設問に答えよ。
         1:  boolean b;
         2:    int k; 
         3:    
         4:    b = k >= 0 || k++ != -2;
         5:    System.out.println("b=" + b + " k=" + k); 
設問1 3行目が
       k = 5;    
    の場合の出力結果を下から選べ。

       A: b=true k=5
       B: b=false k=5   
       C: b=true k=6   
       D: b=false k=6


設問2 3行目が
      k = -2;    
   の場合の出力結果を下から選べ。   
  
       A: b=true k=-2   
       B: b=false k=-2      
       C: b=ftrue k=-1      
       D: b=false k=-1   
解説
 問題20では近道をする「&&」をやりましたが、「または」の「||」も近道をします。

 ||の場合、左側の式の値がfalseならば、右の式も調べますが、左側がtrueの場合は、右の式はtrueかfalseか調べずに、全体の結果をtrueであると結論付けてしまいます。図のようになります。
 
 設問1はkが5です。左の「k>=0」がいきなりtrueなので、右の式はもう調べず、bにはtrueが入ります。ということはk++の++は行われず、kは5のままということになります。よって正解はA。

 設問2のkが−2の場合を考えてみましょう。左の「k>=0」はfalseですので、右の式も調べます。++はkの後ろに付いているので、まずは「k!=−2」について調べます。kは−2なのでfalse、左も右もfalseでbにはfalseが入ります。kの後ろの++を忘れてはいけません。kは−2から−1になります。よって正解はD。
 ||についても&&同様、右側の式の副作用に気をつけましょう。

 &&と||についてまとめておきます。


解答 設問1 A        設問2 D

参考 読み物Java 「第5章 白黒はっきりさせよう」
問題22(難易度:2)                                   2004年12月8日
次をコンパイル、実行したときの出力結果を下から選べ。

         1:  boolean b;
         2:    int k;
     
         3:    k = 5;
         4:    b = k < 0 & --k % 2 == 0;
         5:    System.out.println("b=" + b + " k=" + k);

         6:    k = 5;
         7:    b = k >= 0 | --k % 2 == 0;
         8:    System.out.println("b=" + b + " k=" + k);
  A: b=false k=5
     b=true k=5

  B: b=false k=4
     b=true k=4
 
  C: b=false k=5
     b=true k=4 

  D: b=false k=4
     b=true k=5
解説
 問題2021は「&&」と「||」でしたが、今度は「&」と「|」です。この二つは整数型についてのビット演算に使うのですが(→問題27)、boolean同士の演算にも使えます。意味は&&、||と同じ「かつ」と「または」です。ただし重要な相違点があります。それは近道をしないということです。

 問題20では「&&」の左側がfalseのとき、右側の式の計算をしないことをやりました。また問題21では「||」の左側がtrueのとき、右側の式の計算をしないことをやりました。

 ところが「&」は左側がtrueでもfalseでも、必ず右側の計算を行います。「|」も同様です。近道はしません。途中で結果がわかっても、残りの計算をする律儀な演算子です。下の表の赤く囲んだところが「&&」や「||」では「調べない」になるわけです。

 では4行目を見てみましょう。kは5なので、「&」の左側はfalseになります。右の式の−−はkの前に付いているので、まずkの値を1減らし4にします。そして「k%2==0」を調べると、trueになります。左はfalse、右はtrueなので、結果はfalse、kの値は4になります。

 7行目を見てみましょう。「|」の左側はtrue、右は、まずkが1減り4になり、「k%2==0」はtrueなので、左も右もtrueで結果はtrueになります。kの値は4になります。よって正解はB。

 ここで注意してほしいのは、どちらも右の式に現れる−−でkの値が変更されているということです。

解答 B

参考 読み物Java 「第5章 白黒はっきりさせよう」
問題23(難易度:3)                                 2004年12月9日
次をコンパイル、実行したときの出力結果を選べ。

   1:   int a = 0, b = 1, c = 2;
   2:   boolean d = true;
   3:   System.out.println(a > b | d ^ !(b < c));   

  A: true
  B: false   
  C: コンパイルエラーになる。   
  D: 実行時に例外が発生する。
解説
 問題22で登場した「&」と「|」の仲間に「^」があります。これらはビット演算に使用されるのですが、論理演算にも使用できます。「^」は次のように、左側と右側が同じ論理値(trueとtrue、またはfalseとfalse)の場合、結果がfalseになります。
 では問題の式を見ましょう。「!」は否定で、その後ろの式の値を逆転させます。つまり「!式」は、式の値がtrueならばfalse、falseならばtrueになります。また「|」と「^」の優先順位は同じなので、左から右に行われます。次のようになります。
 まず「a>b」はaが0、bが1なのでfalseになります。dはtrueなので、「false | ture」はtrueになります。右側を見てみましょう。「b<c」はtrue、!が付いて否定になり「!(b<c)」はfalseになります。
 「^」の左側がtrue、右側がfalseなので、結果はtrueになります。よって正解はA。

解答 A

参考 読み物Java 「第5章 白黒はっきりさせよう」
問題24(難易度:3)                                  2004年12月10日
次をコンパイル、実行したときの、出力結果を下から選べ。
        1:  int a = 5;
        2:    double b = 1.2;
        3:    boolean c = false;
        4:    c = a > b || b > 1 & ++a != 6;
        5:    System.out.println(a + " " + b + " " + c);

  A: 5 1.2 true
  B: 6 1.2 true
  C: 5 1.2 false
  D: 6 1.2 false
  E: コンパイルエラーになる
  F: 実行時に例外が発生する
解説
 ややこしいので括弧を使って書き直してみよう。「&」や「|」は、「&&」や「||」より優先順位が高いので、次のように括弧でくくっても同じ結果になる。

      c = a > b || (b > 1 & ++a != 6);
 
 下の図にあるように、「||」の左側がtrueなので、右は調べず、cにtrueが代入される。よって一番右の「++a」は行われず、aは5のまま。よって正解はA。
     


 ではおまけで次のように括弧が付いていたときはどうなるか考えてみよう。

     c = (a > b || b > 1) & ++a != 6;

 下の図にあるように、「&」の左側はtrue、「&」の右側でaの値は6になり、その上で「a!=6」を調べるのでfalse、最終的にfalseがcに入る。aは6になっている。括弧をつけるつけないでこのように結果がちがってくるので、気をつけよう。


解答 A

参考 読み物Java 「第5章 白黒はっきりさせよう」
<<2..演算子と制御文の目次|次問題>>
Copyright (c) 2004 Nagi Imai All Rights Reserved..