...

誤答例

by user

on
Category: Documents
30

views

Report

Comments

Description

Transcript

誤答例
情報処理 II 試験問題 (2011 年 2 月 7 日) の誤答例 (2 月 14 日改訂)
タイプライタ体でない「;」は誤答の区切り,
「⇒」以降は添削例,
「//」以降は村川のコメントである.
2
• (1) -1,0,1,2 // 2 は,「ループ終了時の (ループ内の処理で使用されない) 値」である.
• (1) i+1 // i=i+1 と勘違いした?
• (2) i*3 // for(i=2;i<100;i*3) は,文法的には問題ないが,i の値が更新されず無限ループに
陥る.
• (2) i=i^3 // ビット単位の排他的論理和の演算をするので,i の値は 2,1,2,1,... となる.
• (3) (1,1),(2,1),(3,1),(1,2),(2,2),(3,2),(1,3),(2,3),(3,3) // この解答になる 2 重
ループは,for(j=1;j<=3;j++) for(i=1;i<=3;i++) である.
• (3) (1,1),(2,2),(3,3) // 「j の値は変わるが i の値は変わらない」という状況がある点に注
意して,問題文(と正解)を見直してほしい.
• (4) i;j ≦ 2;j++ // プログラムコードを書くべきところで「≦」は間違い.
• (4) i,j<3,j++ // for のカッコの中には,; が (コメント,文字列リテラルを除いて) ちょうど
2 つ必要となる.
• (4) 0;i<=j;j++ // これでは,i の値が変わった直後に j の値は必ず 0 となるため,パターンの
最後の 2 つは「(1,2),(2,2)」にならない.j の初期化が 1 でも同様.
• (4) j=i;j<2;j++ // 初期化が j=j=i となる (一つの式で j に二度代入するのは良くない.リ
pp.174–176).
• (5) FILE; スタック; ストリーム; 配列 // 2 番目以降の
(5)
に当てはめると,おかしくなる.
• (6) char; char *; char の配列; 文字列; FILE *; ポインタ // ライブラリ関数 fgetc の戻り値
の型にしなければならない.
• (7) <stdio.h> // ここは関数名を書かないといけない.
• (7) fgetc; malloc; scanf // 「fp は...
(7)
を呼び出し,その戻り値を保持している」に
合わない.
• (7) 引数 // 「ライブラリ関数の引数を呼び出し」は,おかしい.
• (7) FILE *fopen(char *path, char *mode); // 関数名だけを書く.
• (8) ファイルポインタが示す,ファイルの中の値を取り出す // 「1 バイト (または 1 文字) の値」
としなければならない.
• (8) 1 列を読み込む; 1 行ずつ読み込む // fgetc は,バイト単位の処理となる.
• (8) ファイルの中身を 1 文字ずつチェックしている; ファイルの文字を 1 文字ずつ検索している
// 「チェック」や「検索」ではなく,「読み出し」である.
• (8) ファイルの先頭から 1 文字ずつ読み出して,その値をファイルポインタに返している // 1 文
字読み出すと,fp が指し示す FILE オブジェクトの中身は少々変わるかもしれないが,fp の値
そのもの (どこを指し示すか) は変化しない.
• (8) ファイルポインタの 1 バイトを読み出す // 読み出す対象を間違っている.
1
• (8) 文字列のはじめから 1 バイトずつ読み出す // fgetc と while ループを組み合わせて使うの
では,文字列は出てこない.
• (8) 停止判定をするために使用されている // 「読み出す」という重要な情報が抜けている.
• (8) 変数 c へファイルの値を代入する // 「ファイルの値」では通じない.
• (8) EOF と該当するまで // この他にも,
(8)
の直後の句点(.)を読点(,)と勘違いし
たと思われる答案が見られた.
• (8) 処理対象; 処理内容 // 関数形式マクロと勘違いした? 「処理内容を書く」を誤解した?
• (9) EOF; -1 // 「EOF(または-1) に達して c に EOF が代入される」は,おかしい.
• (9) ナル文字; ヌル文字; NULL 文字; 終端文字; 終端記号 // ストリームなので,そんな文字や記
号があるわけではない.第 13 回 (20110117) 参照.
• (9) \n // 改行文字とファイルの終わりは違う.一般に,一つのテキストファイルには複数の改
行文字がある.
• (9) NULL; 終端のアドレス // fgetc を使用する限り,戻り値がポインタ (アドレス) になること
はない.
• (9) ファイルの文末; ファイルの最終行; ファイルの最後の文字 // ピントがずれている.
• (9) ファイルの終端の一つ後ろ // 「ファイルの終端」で十分.
3
(複数の答案に見られた記述)
• 関数 floatbit は void 型の関数である // 「戻り値の型が void」である.floatbit そのもの
の型は,「関数型」をキーワードに自習してほしい.
• 6 行目はプロトタイプ宣言であり // 関数定義の一部である.プロトタイプ宣言であれば,閉じ
カッコの後に; が来なければならない.
• q の初期値は,図 1 の 0x0999 番地を指している // 0x1000 から 1 を引いたら 0x0fff(また
は 0xfff) である.それと,図 1 には num のことをまったく書いていないので,「num が図 1 の
0x1000 番地から 0x1003 番地を占めるとき」といった断り書きは,入れておかないといけない.
• sizeof は引数の占めるメモリ領域を返すライブラリ関数である // sizeof は,演算子である
(第 4 回 (20101101)).
• q に終了アドレスの一つ前のアドレスを代入し,p に開始アドレスを代入している // 「開始ア
ドレス」「終了アドレス」が何を指すのか分からない.ここは,13–26 行目が p をループカウン
タとする for ループであることに注意し,p の初期値,反復を終える値がそれぞれ何なのかを説
明するのがよい.
• p の中身を c に代入している // これは c = *p よりもむしろ c = p と解釈されてしまう.「参
照」もしくは「指し示す」という言葉が使えるようになろう.
• b=10000000 と初期化する // 一千万に見える.「2 進数で表すと」といった断りがほしい.
• b が 0 以下になった時点で for ループを終了する // 構文的 (論理的) にはそのとおりだが,読
解・論述としては不十分.b は符号なしなので,
「0 以下」ではなく「0」と書かないといけない.
2
• b と c のビットが合致すれば // それだと if (c == b) である.
• c かつ b であった場合 // それは if (c && b) である.
• b に 1 を代入し,1 を左に 7 回シフトさせて // = と << の優先順位に注意すると,b = (1 <<
7) であって (b = 1) << 7 ではない.
• b の値を半分にし // 整数値としてみると半分になっているが,ここではシフト演算として使用
しているので,「b の値を 1 ビット右にシフトする」のほうが適切である.
• *argv[] には文字列が入る // 変数名は argv であり,厳密に言えば argv[0], argv[1], ... が
文字列を指し示す (または空ポインタ定数 NULL と等しい) ポインタとなる.実用上は,argv[0],
argv[1], ... は(NULL でなければ)文字列と同一視される.
• argv[] という char *型の変数を用いている // 同上.加えて,*argv もしくは argv[0] は,
char *型の (変数ではなく) 値となる.
• atof により,文字列を float 型の数値に変換し,それを floatbit 関数に渡している // atof
の仕様を見直してほしいが (リ p.495),戻り値は double 型である.この値がどこで float 型に
変換されるかというのが,36 行目の関数呼び出しを説明する要所の一つである.
• このプログラムは,ある実行環境で,./floatbit -3.5 を実行すると,「-3.5:
11000000
01100000 00000000 00000000」という出力になった. // あまりにも安直な結合,安直な論
述の出だしである.
• 2 進数で入力する // しない.「入力は何か」「出力は何か」を理解し,正しい日本語 (かつ正しい
技術表現) で言ったり書いたりできるようになろう.
(誤記ほか)
• 1 括 ⇒ 一括
• 記込 ⇒ 書き込み // 「記入」か「書き込み」かで混乱したか?
• 結課 ⇒ 結果
• 実引き数 ⇒ 実引数
• 単準 ⇒ 単純
• 番値 ⇒ 番地
• 先頭 1 ビットは符合 ⇒ 先頭 1 ビットは符号
• /.floatbit -3.5 ⇒ ./floatbit -3.5 // 「./」と書くことで,カレントディレクトリの
floatbit を実行ファイルとして,コマンドを実行することになる.
• float bit 関数 ⇒ floatbit 関数 // ファイル名やソースコード中の識別子で,空白がないの
に空けるような書き方は,しないように.
• ポイント型 ⇒ ポインタ型
• まずドットヘッダを宣言する ⇒ まずヘッダファイルをインクルードする
• 自作関数 void // void は予約語の一つであり,関数名 (識別子) として使用できない.
(さらにレベルアップを)
• 32 bit を 8 bit ごとに分けて出力するプログラムである ⇒ float 型の値を 8 bit ごとに出力す
3
るプログラムである // float 型が 32 bit であることは,プログラムの仕様として書くべきでは
なく,実行例から推測できる情報である.
• コマンドライン引数を定義している; コマンドライン引数を宣言している ⇒ コマンドライン引
数より値を獲得する
• int i を作る ⇒ int 型の変数 i を定義する // 「変数 i を int 型で定義する」という言い方も
聞くが,レジでたまに耳にする「千円でお預かりします」と同様に,美しい日本語ではない.
• argv[0] は./floatbit,argv[1] は-3.5,argv[2] は NULL が入れられる ⇒ argv[0] は
"./floatbit",argv[1] は"-3.5"となり,argv[2] には NULL が格納される // 文字列を指し
示すポインタが,文字列と同一視されるのは前述のとおり.「3.5」と「"3.5"」を区別しよう.
• 文字列を関数 atof で値化し ⇒ 文字列を,関数 atof で double 型の値にし // 文字列の
"-3.5",double 型の-3.5,いずれも値である.
• atof 関数によって文字列が float 型の数字に変えられて ⇒ atof 関数によって,文字列が
double 型の値に変換され
• atof を argv[i] として呼び出し,floatbit にしている ⇒ argv[i] を引数として関数 atof
を呼び出し,さらに,その戻り値を引数として関数 floatbit を呼び出している
• 3–4 行目で,インクルード文 <stdio.h>, <stdlib.h> を宣言している ⇒ 3–4 行目で,ヘッダ
ファイル stdio.h, stdlib.h を取り込んでいる // < と > は,インクルード文の構成要素であ
り,「stdio.h」「stdlib.h」がヘッダファイルである.
• stdio.h をインクルードしたのは,void と printf と sizeof を使えるようにするためである
⇒ stdio.h をインクルードしたのは,ライブラリ関数の printf を使えるようにするためであ
る // すでに書いたとおり,void も sizeof も関数ではない.なお,NULL もまた,stdio.h (別
のヘッダファイルでもよい) をインクルードすることで使える定数 (オブジェクト形式マクロ) で
ある (リ p.457, リ p.424).
• 14–15 行で変数を宣言しているが,変数の宣言は関数のはじめにするという規格もあるので好ま
しくない // ブロックの先頭で変数を宣言できる (リ p.222, リ p.113).
• floatbit 関数は入れ子構造になっており ⇒ floatbit 関数は入れ子の for ループを持って
おり
• floatbit 関数の中では,float 型の num,unsigned char 型の*q, *p が変数として使用され
ている ⇒ floatbit 関数は,仮引数として float 型の num を持つ.またローカル変数として,
unsigned char 型のポインタ q, p を持つ // 仮引数と,関数のブロック内で宣言されている
ローカル変数は,分けて記述するのが望ましい.
• l.7, l.8 の*q, *p はどちらも正の数の整数である変数 q, p を確保している // 添削できない.最
低限,変数宣言において*は変数名の一部ではなく型名の一部であることを,理解してほしい.
• q には (unsigned char *)&num-1 を代入し,p には q+sizeof(float) を代入している // 値
の意味を書かないのでは,それぞれの宣言文を理解し説明したとは言えない.
• q に読み出しの終了地点のアドレス,p に読み出しの先頭地点のアドレスを代入する // 「q に終
了アドレスの」から始まる誤答とそれに対する解説を見直してほしい.それと,「読み出しの終
了地点のアドレス」は,q ではなく q+1 ((unsigned char *)&num と等しい) である.
4
• p̸=q; p=p-1 のとき // 条件 → 処理 → 増分 → 条件 → 処理 → 増分 →... (第 3 回 (20101025))
という反復が分かるような説明を書いてほしい.
• p の値と q の値が違えば,p を減算する // 同上.実際には,デクリメントしてから,p と q の比
較をする.
• c & b が 0 でないとき,if 文が,0 のとき,else 文が実行される // 「else 文」という表現は
自然ではない.if 文は,18–22 行目を占める.
• 右に 1 桁ずつずらしていく // 「桁 (digit)」ではなく「ビット (bit)」,
「ずらす」ではなく「シフ
トする」.
• "\n" (終端文字) を出力する // 一般に,終端文字とは ’\0’ をいう.
• 改行文字が入れられている ⇒ 改行を出力する
• 浮動小数の値 ⇒ 浮動小数点数 // 「浮動 + 小数点 + 数」という分割をするので,「浮動小数」
はおかしい (または俗語であり,試験の答案には望ましくない).
• 今は省略する ⇒ 後述する // こう書くからには,答案の後ろの方で言及していなければならな
い (答案はそうしていた).
• 簡略の為 ⇒ 簡単のため // 英語では “for simplicity” と書く.
5
Fly UP