基本情報技術者試験 科目B サンプル問題 問6の解説|8ビットの並びを逆にする rev

基本情報技術者試験

科目B サンプル問題 問6難易度 ★★★擬似言語・ビット演算・シフト最終更新 2026-09-22

空欄は2行まるごと。式を読み解くのは難しいので、4つの選択肢を全部動かして、おかしくなったものから消します。

本番での扱い

1問あたりの目安は約5分(科目Bは100分で20問)。選択肢を8回ずつ動かすこの問題は後回しにして、時間が残ったら戻るのが得策です。

難易度 ★★★(当サイトの目安)── シフトと論理積を何周か追わないと、選択肢を見分けられない。4段階の決め方は科目B 最短合格の戦略にあります。

出題

出典:基本情報技術者試験 科目B サンプル問題 問6

次のプログラム中の   に入れる正しい答えを,解答群の中から選べ。

関数rev は8 ビット型の引数byte を受け取り,ビットの並びを逆にした値を返す。例えば,関数rev をrev(01001011) として呼び出すと,戻り値は11010010 となる。

なお,演算子 ∧ はビット単位の論理積,演算子 ∨ はビット単位の論理和,演算子 >> は論理右シフト,演算子 << は論理左シフトを表す。例えば,value >> n はvalue の値をn ビットだけ右に論理シフトし,value << n はvalue の値をn ビットだけ左に論理シフトする。

〔プログラム〕

○8 ビット型: rev(8 ビット型: byte)
  8 ビット型: rbyte ← byte
  8 ビット型: r ← 00000000
  整数型: i
  for (i を 1 から 8 まで 1 ずつ増やす)
     
  endfor
  return r

解答群

ア r ← (r << 1) ∨ (rbyte ∧ 00000001)
    rbyte ← rbyte >> 1
イ r ← (r << 7) ∨ (rbyte ∧ 00000001)
    rbyte ← rbyte >> 7
ウ r ← (rbyte << 1) ∨ (rbyte >> 7)
    rbyte ← r
エ r ← (rbyte >> 1) ∨ (rbyte << 7)
    rbyte ← r

答えだけ先に見る

正解は アです。

この問題に出てくる記号

読めない記号があったときだけ開いてください。

記号 4コ の読み方をひらく
書き方 読み方
a ∧ b 桁ごとに、両方 1 なら 1、それ以外は 0
a ∨ b 桁ごとに、どちらかが 1 なら 1
a << n 全体を左へ n 桁ずらす。はみ出た桁は捨て、右端には 0 が入る
a >> n 全体を右へ n 桁ずらす。はみ出た桁は捨て、左端には 0 が入る

コードは何をしているか

〔プログラム〕

  8 ビット型: rbyte ← byte
  8 ビット型: r ← 00000000
  整数型: i
  for (i を 1 から 8 まで 1 ずつ増やす)
     
  endfor
  return r

※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。

r は 00000000 から始まり、最後に return r で返されます。for で8回まわるあいだに、r を byte の並びを逆にしたものに仕上げるのが空欄の仕事です(rbyte は byte の写しで、作業用)。

空欄に入るものを決める ── 4つとも動かして確かめる

選択肢の式が何をしているかを読み解くのは難しいので、4つとも実際に動かします。入れるのは問題文の例 01001011。正しい選択肢なら、8回後の r は 11010010 になります。

使う記号は4つだけです。

  • << n ── 全体を左へ n 桁ずらす。左端からはみ出た桁は捨て、右端には 0 が入る
  • >> n ── 全体を右へ n 桁ずらす。右端からはみ出た桁は捨て、左端には 0 が入る
  • ∧ 00000001 ── 右端の桁だけが残り、ほかはすべて 0
  • ∨ ── 桁ごとに、どちらかが 1 なら 1

byte = 01001011 で、4つの選択肢を動かす(各回が終わったあとの値)

緑=その回で新しくできた値

ア r ← (r << 1) ∨ (rbyte ∧ 00000001)
rbyte ← rbyte >> 1
→ 11010010 で正しい

1回目を筆算で

1行目 r ← (r << 1) ∨ (rbyte ∧ 00000001)
 (1) r << 1        00000000 → 00000000
          (0 はずらしても 0)
 (2) rbyte ∧ 00000001
          01001011
          00000001   ∧
          ────────
          00000001   右端だけ残る
 (3) (1) ∨ (2)
          00000000
          00000001   ∨
          ────────
          00000001   = 新しい r
2行目 rbyte ← rbyte >> 1
          01001011 → 00100101

各回が終わったあとの値

1回目 r = 00000001 rbyte = 00100101
2回目 r = 00000011 rbyte = 00010010
3回目 r = 00000110 rbyte = 00001001
4回目 r = 00001101 rbyte = 00000100
5回目 r = 00011010 rbyte = 00000010
6回目 r = 00110100 rbyte = 00000001
7回目 r = 01101001 rbyte = 00000000
8回目 r = 11010010 rbyte = 00000000

2回目からも同じ4つをくり返します。r は1つ左へずれてから右端に rbyte の右端が入り、rbyte は1つ右へ。

イ r ← (r << 7) ∨ (rbyte ∧ 00000001)
rbyte ← rbyte >> 7
→ 3回目で消去

1回目を筆算で

1行目 r ← (r << 7) ∨ (rbyte ∧ 00000001)
          アと同じで 00000001 = 新しい r
2行目 rbyte ← rbyte >> 7
          01001011 → 00000000
          (7桁がはみ出し、左端の 0 だけ残る)

各回が終わったあとの値

1回目 r = 00000001 rbyte = 00000000
2回目 r = 10000000 rbyte = 00000000
3回目 r = 00000000 rbyte = 00000000

rbyte は1回目の >> 7 でもう 00000000。r の 1 は7桁ずつ左へ動いて3回目にはみ出し、r も rbyte も 00000000。ここから先は何度くり返しても 0 のままなので、ここで消せます。

ウ r ← (rbyte << 1) ∨ (rbyte >> 7)
rbyte ← r
→ 01001011 で外れ

1回目を筆算で

1行目 r ← (rbyte << 1) ∨ (rbyte >> 7)
 (1) rbyte << 1    01001011 → 10010110
 (2) rbyte >> 7    01001011 → 00000000
 (3) (1) ∨ (2)
          10010110
          00000000   ∨
          ────────
          10010110   = 新しい r
2行目 rbyte ← r → rbyte も 10010110

(2) は、7桁が右端からはみ出して左端の1桁だけが右端に残る。いまは左端が 0 なので 00000000(左端が 1 なら 00000001)。

各回が終わったあとの値

1回目 r = 10010110
2回目 r = 00101101
3回目 r = 01011010
4回目 r = 10110100
5回目 r = 01101001
6回目 r = 11010010
7回目 r = 10100101
8回目 r = 01001011

2行目 rbyte ← r で、次の回はいま作った r が rbyte(なので r だけ書けば足ります)。毎回、左端の桁が右端へ回るだけなので、8回目で元の 01001011 に戻ります。

エ r ← (rbyte >> 1) ∨ (rbyte << 7)
rbyte ← r
→ 01001011 で外れ

1回目を筆算で

1行目 r ← (rbyte >> 1) ∨ (rbyte << 7)
 (1) rbyte >> 1    01001011 → 00100101
 (2) rbyte << 7    01001011 → 10000000
 (3) (1) ∨ (2)
          00100101
          10000000   ∨
          ────────
          10100101   = 新しい r
2行目 rbyte ← r → rbyte も 10100101

(2) は、7桁が左端からはみ出して右端の1桁だけが左端に残る。右端は 1 なので 10000000。

各回が終わったあとの値

1回目 r = 10100101
2回目 r = 11010010
3回目 r = 01101001
4回目 r = 10110100
5回目 r = 01011010
6回目 r = 00101101
7回目 r = 10010110
8回目 r = 01001011

ウと同じく次の回はいま作った r が rbyte。毎回、右端の桁が左端へ回るだけ。8回目で元に戻ります。

途中で消せたのはイだけで、ウ・エは8回目まで追って初めて外れと分かります。最後まで残ったのはアです。

エは2回目、ウは6回目に 11010010 を通ります。それでも答えは8回後の値です。途中で飛びつかず、最後まで数えます。

答え合わせ

正解は ア です。

r ← (r << 1) ∨ (rbyte ∧ 00000001)
rbyte ← rbyte >> 1

アは、rbyte の右端のビットを1つ取り出して、r の右端に積みます。積むたびに r は1つ左へずれるので、最初に積んだビットほど左へ押し出され、並びが逆になります。1行ずつの動きは下で追えます。

1行ずつ追う 正解の ア で rev(01001011)

出典:科目B サンプル問題 問6(空欄に ア を入れたもの)


ループ開始前

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると1行ずつ積み上がります)

次に読む

この問題でどこに手間取ったかで、行き先が変わります。

この記事で引用した資料

いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

Copied title and URL