back
last update 99/7/13(持ち込み品の確認, 関数のプログラム例を増やす) new 99/7/2(新規作成)
目次

静大プログラミングテスト(案)について

注意:この内容は,静岡大学の講義「プログラミング」(by望月) の模擬試験問題です。 以下の点を注意して活用してください。

  • この問題をきちんと解ければ, 当日,8割は解けるはずです。
  • しかし,あくまで,模擬問題ですから, まったく同じ問題が出るとは限りません。
  • 筆記用具以外に持ち込み可なものは, テキスト(ザ・C 第2版)のみです。 誰の作成であろうと, プリントやメモ書き等の持ち込みは禁止です。
  • 試験場所注意:A302教室で行います。 (コンピュータ室ではありません。)
  • この情報は,出来るだけ画面上で見て確認するにとどめてください。
    なぜなら, 随時更新する予定ですから。
    目安としては,最後の授業の翌日(7/14)までに一応完成させ, その週のうちにうち間違いをなくし, 7/17(土曜)以降はそのまま変更しない予定でいます。 (予定が変わる可能性がありますから,注意してください)


情報について

特にここから問題を出すことは考えていませんが, 「情報を以下にして2値符号で表現するか」という問題は, 情報処理をする上で最も大切なことの一つですから, 普段から頭を使ってみると面白いでしょう。 たとえば,
text p.115 には,アルファベットなど英数字と,2進数との対応表が載っています。
また,
text pp.135-137 には,漢字を表わすための情報の伝え方が載っています。


top

1章の問題から

この部分は特に問題に出すようなことも考えてませんが, 人にわかりやすいプログラムを,コンパイラによって, 機械が理解できるデータに変換することを覚えておきましょう。


top

2章の問題から

問 次のプログラム(抜粋)のなかの@,Aおのおのの演算は違った答えとなるというが, その理由を述べよ。
(ヒント)text p.40(型の変換)

int a;
float b;

a = 10/3;         @
b = 10./3.;       A


問 次のプログラム(抜粋)のなかの@〜Bにおいて, 指示された変数はいくらなのか述べなさい。
(ヒント)代入文とは何なのか思い出そう。(text p.23) コンピュータ特有の数式表現に慣れよう。(text p.23) プログラムを追って行く集中力をつけよう。

int a,b,c;

a = 5;
b = 7;
c = a + b;
               @ このとき c の値は? 
b = b + a;
               A このとき b の値は? 
a= a + c - c;
               B このとき a の値は? 


top

3章の問題から

問 次のプログラム(抜粋)は,@を処理するか,またはAを処理するか答えよ。
また,ここでは,a が 8 のときに条件式を評価したが, a が 1から9 まで変化するならば,それぞれの場合に @とAのいずれを処理するか。
(ヒント)if 文で主に使われる式(論理式)の書き方に慣れよう(text pp.54-55)

int a;

a = 8;
if( (a<3) || (a>5) ){
   @
}else{
   A
}

問 次のプログラム(抜粋)たちは,小さい数から順番に大きな数を表示するが, それぞれ幾つから幾つまで表示するか答えよ。
(ヒント)ループの書き方に慣れよう(text p.60, p.69, p.70, p.75)
int i;

i=1;
while(i<=5){
	printf("%d\n",i); 
	i=i+1;
}

int i;

i=0;
do{
	i=i+1;
	printf("%d\n",i); 
}while(i<5);

int i;

for(i=1; i<=5; i=i+1){
	printf("%d\n",i); 
}

int i;

i=0;
while(i>=0){
	if(i==5) break;
	i=i+1;
	printf("%d\n",i); 
}


top

4章の問題から

問 次のプログラム(抜粋)は,次の動作をするように作られた: しかし,@の部分 ( 複数行が入る可能性あり ) が未完成である。 ここを埋めて,正しく動作するようにしなさい。 (ヒント)最大値は,text p.93 にて求めている。
int tensu[100],n,i,max,ii;

//この部分で,以下のように設定/入力
//     n : 最大の出席番号
//     tensu[i] : 出席番号 i の人の点数
//     tensu[1] から tensu[n] が有効な数字

printf("1 番目の人の点数は,%d です。\n",tensu[1]);
ii=1;
max=tensu[1];
for(i=2; i<=n; i=i+1){
	printf("%d 番目の人の点数は,%d です。\n",i ,tensu[i]);

	@
	
		printf("この点数は最高点ではありません\n");
	}else{
		printf("最高点の候補です\n");
		ii=i;
		max=tensu[i];
	};
}
printf("最高点は %d 番目の人による %d 点です。\n",ii ,max);


問 次のプログラム(抜粋)は,次の動作をするように作られた: しかし,このプログラムは,一部おかしい点があり, 最小の点数が 0 点になり,最大の点数が消えてしまうという。 正しく動作するにはどの部分をどう変更したら良いか答えなさい。
(ヒント)バブルソートは,text p.95
int tensu[100],n,i,mark;

for(i=0; i<100; i=i+1)
	tensu[i]=0;

//この部分で,以下のように設定/入力
//	n : 最大の出席番号 (1クラスは約80名とする)
//	tensu[i] : 出席番号 i の人の点数
//	tensu[1] から tensu[n] が有効な数字
//	tensu[0] は 0
//	tensu[n+1] から tensu[99] は 0

do{
	mark=0;			//markは,目印
	for(i=1; i<=n; i=i+1){
		if( tensu[i]>tensu[i+1] ) {
			t=tensu[i];  //以下3行でならべ変え
			tensu[i]=tensu[i+1];
			tensu[i+1]=t;
			mark=1;	//並べ替えが一度でもあったら,mark←1
		};
	};
}while(mark==1);   //mark が 0 であれば,並べ替えが済んでいるということ

for(i=1; i<=n; i=i+1)
	printf("%d 番目に低い点数は,%d です。\n", i, tensu[i]);



top
5章の問題から
この章の内容は,知識として知っておいてください。


top
6章の問題から
望月は,この章は7章に向けた準備だと考えます。 まずは,pp.146-147, p.157 だけは,しっかりマスターして置きましょう。

しかし,それ以上の点は,必要に応じて勉強すれば良いと思います。

ポインタという概念を持つ言語は,C とそのファミリーしかありません。 しかし,その他の言語でも普通の処理は普通に書けるのですから, ポインタは計算機上でプログラムを組むために必須のものとは言えないでしょう。 また,ポインタの使い方を誤ると,コンピュータが容易に暴走してしまいます。
しかし,ポインタを知っていると, 効率的なプログラムを書くことが出来る可能性があります。
十分に勉強した上で,気をつけて使いましょう。


top

7章の問題から

この章に入る前に,まずはポインタの使い方をおさらいしましょう。
「関数」(次章参照)においては,ポインタを正確に使いましょう。 (おまじないのように(意味も知らずに)覚えておいてもよいから)

なお,教科書と VisualC++ とでは微妙に引数の書き方に差があります。 これは,そもそも C 言語は時代とともに仕様が少しずつ変わっているところ, どのバージョンを基に作られたかということによります。 念のため,VisualC++ 風の書き方も載せておきました。 main を最後にもって行くことにより,関数をいちいち宣言する手間を省いたということと, 引数を宣言する方法が変わっています。

関数の内で計算した結果を,メインルーチンに返す必要が無いか, または,一つだけ返せば良いときには,ポインタを使う必要がありません。
教科書風の書き方
main()
{
	double x,u;
	double f();

	//	ここで,x, y に値を設定したとする。

	u=f(x,y);

	//	ここで,x, y や u の値を表示する。
}

double f(x,y)
double x,y;
{
	return(2.0 * x + 3.0 * y);
}
Visual C++ 用の書き方
double f(double x, double y)
{
	return(2.0 * x + 3.0 * y);
}

main()
{
	double x,u;

	//	ここで,x, y に値を設定したとする。

	u=f(x,y);

	//	ここで,x, y や u の値を表示する。
}


関数の内で計算した結果を,2 つ以上メインルーチンに返す時は, ポインタを使います。
メインルーチン側 : 関数呼び出しによって値が変わる変数は & をつける。
サブルーチン側 : 呼ばれたときに,メインルーチン側の変数の値を変えたければ,* をつける。
教科書風の書き方
main()
{
	int a,b;
	void swap();

	// ここで,a, b に値を設定する。

	swap(&a,&b);

	// swap 関数呼び出し前と,後では,変数 a と b の値が入れ替わる。
}

void swap(x,y)
int *x,*y;
{
	int work;
	work=*x;
	*x=*y;
	*y=work;
}
Visual C++ 用の書き方
void swap(int *x, int *y)
{
	int work;
	work=*x;
	*x=*y;
	*y=work;
}

main()
{
	int a,b;

	// ここで,a, b に値を設定する。

	swap(&a,&b);

	// swap 関数呼び出し前と,後では,変数 a と b の値が入れ替わる。
}


配列は,その性質上もともとポインタの概念を含んでいるので, & や * をつけなくてもデータを受け渡すことが可能です。
教科書風の書き方
main()
{
	char bun[80];
	void cap();

	// ここで,bun[] に文章を入力。(大文字 小文字を取り混ぜて)

	cap(bun);

	// cap 関数呼び出しにより,すべての小文字が大文字に変換される。
}

void cap(mm)
char mm[];
{
	int i;
	i=0;
	while(mm[i]!=0){		// 0 ということは,文字列の最後ということ
		if( ('a'<=m[i]) && (m[i]<='z') ) 
			m[i]=m[i]-32;	// 大文字と小文字は32違う(参照text p.115)
		i=i+1;
	}
}
Visual C++ 用の書き方
void cap(char mm[])
{
	int i;
	i=0;
	while(mm[i]!=0){		// 0 ということは,文字列の最後ということ
		if( ('a'<=m[i]) && (m[i]<='z') ) 
			m[i]=m[i]-32;	// 大文字と小文字は32違う(参照text p.115)
		i=i+1;
	}
}

main()
{
	char bun[80];

	// ここで,bun[] に文章を入力。(大文字 小文字を取り混ぜて)

	cap(bun);

	// cap 関数呼び出しにより,すべての小文字が大文字に変換される。
}


関数を使う理由は,2つあります。
一つは,同じ処理がプログラム中のさまざまな場所で行われる場合に, それを関数にまとめて,その都度呼び出すことにより, メモリを節約し,同じプログラムを書く手間が1回になるためにバグを減らすこと。
もう一つは,長い複雑なプログラムをいくつかの部分に分けることによって, プログラム開発を容易にするためです。
いずれの場合にも,関数呼び出しの約束事さえマスターしてしまえば, あとは1ステップずつ丹念にプログラムを追うことにより,その動作を理解できます。

上に書いた3つの例は最も基本的なものですから, きちんとマスターしておきましょう。
上のプログラムを基にして,関数の書き方の問題を出したいと思います。


top
8章の問題から
この章の内容は,知識として知っておいてください。
ただし,時間があったら取り上げたいと思います。


top
その他から
数値計算への応用を考えたいと思います。
すると,text 内では,以下のプログラムが,数値計算のプログラムと言えます。 プログラムというのは,意外と入出力に精力を取られ, 数値計算を実際に行っているところは実はかなり短いことが多いです。 従って,これらのプログラムを見ると, その考え方は非常に短くまとまっていることになります。 ぜひ読み直して,その考え方を学び取り,他に生かしてください。
これらの中から1問応用問題を作りたいと思っています。


top