前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
| 授業 科目 |
計算機実習 I | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
| 氏名 | ||||||||||||||||
| 担当者 | DÜRST, M.J., 松田、 松本、武藤、矢吹 |
|||||||||||||||
プログラミング一般やプログラミング言語 C において使われる次の英語の用語の日本語訳と説明を書きなさい。日本語訳ではできるだけ片仮名を使わないようにしてください。
array
配列; 同じ型の複数の要素を順番にメモリに配置し、添え字を使って使用できるもの。
floating point number
浮動小数点数; 極めて大きいや小さい数をある程度の精度で計算機内に表現する仕組み。
modulo operator
剰余演算子; a % b で a を b で割っての余りを計算する演算子。
standard output
標準出力; 画面やリダイレクトのファイルへの出力。
actual parameter
実引数; 関数に実際に引き渡される値のこと。
dereference operator
間接演算子; ポインタが指す値を返す演算子
call by value
値渡し; 関数に値そのものを渡し、変更されても元のところに影響がない仕組み。
次のテーブルの式の値を計算しなさい (i は int の変数)。
| 番号 | 式 | 値 | 番号 | 式 | 値 |
| 例 | 2+3*5 |
17 |
例 | 2+3*5 |
17 |
3*0 ? 4 : 5 |
5 |
15 & 25 |
9 |
||
0x83 | 5 |
135 |
i=19, ++i, i-- |
20 |
||
'3' - '9' |
-6 |
20 - 12-6 |
2 |
||
0777 |
1023 |
(int)2.345E6 |
2345000 |
||
~(~22 & ~33) |
55 |
i = 22.33 |
22 |
||
12 << 3 |
96 |
39 >> 2 |
9 |
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
printf の書式 (10 点)変数 c、d、f、i の後に下記の表の
printf 文を実行する。各出力を 1文字ずつ表に記入しなさい。スペースは SP、小数点は DOT と書く。出力が予想不可能の場合、最初の文字のところに
@@ と書く。0 の様な文字は全てゼロ。'a' の文字コードの番号は十進数で 97。
char c = 'g'; double d = 33.333; float f = 20.2; int i = 15;
| 番号 | printf 文 |
文字 1 | 文字 2 | 文字 3 | 文字 4 | 文字 5 | 文字 6 | 文字 7 | 文字 8 | 文字 9 | 文字 10 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 例 | printf("%d", i); |
1 | 5 | ||||||||
printf("%d", c); |
1 | 0 | 3 | ||||||||
printf("0x%x", i); |
0 | x | f | ||||||||
printf("%04X", i); |
0 | 0 | 0 | F | |||||||
printf("%5c", c); |
SP | SP | SP | SP | g | ||||||
printf("%-5d", i); |
1 | 5 | SP | SP | SP | ||||||
printf("%+d", i); |
+ | 1 | 5 | ||||||||
printf("%%d", i); |
% | d | |||||||||
printf("%.3f", f); |
2 | 0 | DOT | 2 | 0 | 0 | |||||
printf("%.3E", f); |
2 | DOT | 0 | 2 | 0 | E | + | 0 | 1 | ||
printf("%.3f", d); |
3 | 3 | 3 | DOT | 3 | 3 | 0 |
free 関数 (9 点)free 関数を使うときに注意すべき点を三つ挙げ、説明しなさい。
必要のなくなったメモリは必ず返さないといけない。そうしないといつかメモリが足りなくなります。
まだ必要のなメモリは絶対返してはならない。するとメモリが再利用される可能性があり、混乱になる。
メモリを返すときには malloc などでもらったポインタ以外で返さない。そうしないもらってもないメモリの部分を「返す」ことになる。
次の入力関数の場合、入力の終わり (end of file) をどうやって感知できるか説明しなさい。
getchar: int としての戻り値が EOF の場合。
fgets: 戻り値が NULL の場合。
scanf: 戻り値が EOF の場合。
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
| 授業 科目 |
計算機実習 I | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
| 氏名 | ||||||||||||||||
| 担当者 | DÜRST, M.J., 松田、 松本、武藤、矢吹 |
|||||||||||||||
下記は、ファイル "alphabet.txt" から半角文字を一つ読み込み、その
ASCII コード番号を "number.txt" に出力するプログラム、及び入出力ファイルの例である。空欄を正しく埋めなさい。
#include <stdio.h>
int main (void)
{
FILE* fp;
char c;
fp = fopen("alphabet.txt","r");
fscanf(fp,"%c",&c);
fclose(fp);
fp = fopen("number.txt","w");
fprintf(fp,"%d",c);
fclose(fp);
return 0;
}
入出力ファイル例
入力ファイル "alphabet.txt": A 出力ファイル "number.txt": 65
"alphabet.txt" が存在していない状態で、上記のプログラムを実行すると、異常終了する。これを避けるためには、プログラムをどのように改良すればよいか書きなさい。
fopen 関数の戻り値が NULL であるかどうかを調べ、
NULL の場合はエラーメッセージを出して、
プログラムを終了するようにする。
typedef の意義 (6 点)プログラムの中で typedef をどこ、なぜで使うべきなのか説明しなさい。
typedef で複雑の型に別名をつけることが可能。特に構造体の場合にはよくつかわれるが、
構造体限定ではない。別名をつけることでプログラムが細かい具体的な C 言語の型から
応用の分野の用語や概念に抽象化される。それによってより読みやすく、分かりやすくなる。
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
swap (6 点)2つの変数 x, y の中身を入れ替える関数 swap を作りたい。空欄に適切なコードを埋めなさい。
プログラム
void swap (int *x, int *y)
{
int work;
work = *x;
*x = *y ;
*y = work;
}
reverse (4 点)配列 array の中身を逆順に並べ替える関数 reverse
を作りたい。空欄に適切なコードを埋めなさい。ただし上記の問で作成した関数 swap を使うものとする。
プログラム
void reverse (int *array, int n)
{
int i, j;
for (i=0, j=n-1; i < n/2; i++, j--)
swap (array+i, array+j); //または &array[i], &array[j]
}
上記の問で作成した関数 reverse を利用するプログラムを作成した。実行結果を答えなさい。
プログラム
int main (void)
{
int i;
int number[5] = { 2, 4, 6, 8, 10};
reverse (number, 5);
for (i=0; i < 5; i++)
printf ("%d, ", *(number+i)); // (A)
printf ("\n");
for (i=0; i < 5; i++)
printf ("%d, ", (*number)+i); // (B)
printf ("\n");
return 0;
}
10, 8, 6, 4, 2, 10, 11, 12, 13, 14,
以下の処理は (A) (B) どちらと実行結果が同じになるか: (B)
for (i=0; i < 5; i++)
printf("%d, ", *number+i);
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
| 授業 科目 |
計算機実習 I | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
| 氏名 | ||||||||||||||||
| 担当者 | DÜRST, M.J., 松田、 松本、武藤、矢吹 |
|||||||||||||||
数列 s0, s1, s2,..., sn-1 の最小値を以下のような再帰的な考え方により求めることができる。
sa が求めるべき最小値となるので、sa を戻り値として返す。a < b ならば、sa と sb の中央の位置を境に数列を二分し、それぞれの最小値を再帰的に求め、そのうち小さい方の値を返す。以下は、再帰を用いて最小値を求めるプログラムである。空白を埋めて完成させなさい。
#include <stdio.h>
int min (int s[], int a, int b)
{
int c, m1, m2;
if (a == b)
return s[a];
c = (a+b)/2;
m1 = min( s, a, c );
m2 = min( s, c+1, b );
printf("c=%d m1=%d m2=%d\n", c, m1, m2);
return (m1 < m2) ? m1 : m2;
}
int main (void)
{
int s[] = {95, 30, 90, 60, 80};
printf("minimum=%d\n", min( s, 0, 4 ));
return 0;
}
上記のプログラムを実行したときの結果を完成させなさい。
c=0 m1=95 m2=30 c=1 m1=30 m2=90 c=3 m1=60 m2=80 c=2 m1=30 m2=60 minimum=30
UTF-8 一文字あたりのバイト数に分けて文字の種類を書きなさい。
1 バイト: ローマ字 (基本のものだけ)
2 バイト: アラビア文字、ヘブライ文字、ギリシア文字、「記号付き」ローマ字
3 バイト: (半角・全角) 片仮名、平仮名、漢字
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
C言語の標準ライブラリには、文字列の長さを (バイト単位で) 返す関数 strlen が用意されている。この関数と同様の働きをする関数 mystrlen を実装したい。
以下の空白を埋めて、関数 mystrlen とそれを利用するプログラムを完成しなさい。
#include <stdio.h> // 関数 mystrlen の定義 int mystrlen (const char *str) { int i=0; while (str[i]) i++; return i; } int main (void) { // 文字列「ABCDE」の長さを求める char str[] = "ABCDE"; printf("%d\n", mystrlen(str) ); //出力値: 5 // 文字列「3210」の長さを求める printf("%d\n", mystrlen("3210") ); //出力値: 4 return 0; }
次のそれぞれ二つの制御文をどう使い分ければいいのか詳しく説明しなさい。
for 文と while 文
for 文では初期化、継続条件、「次の一歩」をまとめて一か所に指定できる。 典型的な
使い方は配列の一個一個の要素の処理です。しかし複数の指数を同時に操作したり、
複数の条件を同時にチェクすることも可能です。while 文は継続条件だけが決まった場所に
あります。したがって while 文は初期化が特に必要ない、「次の一歩」が繰り返す
処理の中で行われているなどのときに最適である。回数が分かる時には多くの場合
for で、終了条件だけが分かる時に while が最適。
if 文と switch 文
if 文は else とともに一般的な枝別れの制御う文なのに、switch は特殊なものである。
switch の場合、「整数の定数と等しい」という制約があり、それがないと switch 文が使えない。
逆に switch 文の場合には複数の case で同じ処理をしたり、case を break で終わらなく、
次の case に流れ込む (要注意!)、case 以外を default でし示す機能もあります。
一般的には三つや四つのケース以上で可能であれば switch を使うが、そうでない
ときには if/else を使うべきである。
前期試験 ・ 2009 年 7 月 30 日 4 時限実施 ・ ページ
| 授業 科目 |
計算機実習 I | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
| 氏名 | ||||||||||||||||
| 担当者 | DÜRST, M.J., 松田、 松本、武藤、矢吹 |
|||||||||||||||
次の質問 (一部省略) が Q & A フォーラムにだされたので答えなさい。
#include 後にスペースが無くてもコンパイルできるのに、なぜだめでしょうか。pow(2, n) % n で error: invalid operands to binary % が出たが、なぜ。invalid lvalue in assignment のエラーになりました。parse error at end of input と出たが、プログラムの終わりに問題は見当たらない。macro "getchar" passed 1 arguments, but takes just 0 となった。diff を使いましたが、出力なしに終わってしまいました。int *p; と書くとき、ここの「*」はどんな演算子でしょうか。char buffer[3]="end"; で何か問題があるのだろうか。授業でよかった点、そして改善すべき点などについて教えてください。
よかった点 (何か書いたら 3 点):
[@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@]
[@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@]
改善すべき点 (何か書いたら 3 点):
[@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@]
[@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@]