中間試験結果

プログラミング入門2
中間試験結果について
情報工学科 篠埜 功
得点分布(36点満点)
受験者 109人
得点分布
0-10: 0人
11-20: 14人
21-22: 3人
23-30: 50人
31-36: 42人
22点以下の人は要注意です。期末の準備を
十分にしてください。
多くの人が間違えていた点
#include <stdio.h>
int main (void) {
int i,n;
printf ("正の整数を入力してください: ");
scanf("%d", &n);
printf ("%dの約数を小さい順に列挙すると、\n", n);
for (i=0; i<n; i=i+1)
if (n%i==0)
printf ("%d, ", i);
printf ("%d である。\n", n);
return 0;
}
iが0の状態でn%iを実行すると0での割り算の余りになる。0での
割り算の余りは未定義(何が起こるか分からない)。
(赤字のi=0のところをi=1とすればよい)
無限ループ
#include <stdio.h>
int main (void) {
int i;
for (i=0; i<=i+1; i++)
printf ("%c", 'a');
return 0;
}
こういう書き方でも良さそうに見えるが、int型で0から始
めて1を順に加えていくといつかint型の最大の数になり、
それに1を加えた場合、挙動は未定義であり(負の数に
なるかもしれない)、大小関係がそこで逆転し、ループを
抜けてしまう場合がある。無限ループはwhile(1) … ある
いはfor(;;) … という書き方が基本。
無限ループ
#include <stdio.h>
int main (void) {
int i=0;
while (i==0)
printf ("%c", 'a');
return 0;
}
このプログラムは無限ループするが、iと0が等しいことを
無駄に毎回判定する(コンパイラがこの部分の最適化を
しなければ)。
無限ループはwhile(1) … あるいはfor(;;) … という書き方
が基本。
文字列の終端の判定
#include <stdio.h>
int countSpaces (char *str) {
int count=0, I;
for (i=0; str[i]!=‘¥n’; i=i+1)
if(str[i]==‘ ‘) count=count+1;
return count;
}
これだと、文字列中に改行があった場合、そこで終わりになり、改行
がなかった場合は文字列の終端を超えてアクセスすることになる(そ
の場合の挙動は未定義)。文字列の終わりはヌル文字’¥0’なので、
for (i=0; str[i]!=‘¥0’; i=i+1)
のように書く。’¥0’は0なので、
for (i=0; str[i]!=0; i=i+1)
でもよく、あるいは
for (i=0; str[i]; i=i+1)
でもよい。これらの中のstr[i]の部分は*(str+i)でもよい。
文字列の終端の判定
#include <stdio.h>
int countSpaces (char *str) {
int count=0, I;
for (i=0; i<99; i=i+1)
if(str[i]==‘ ‘) count=count+1;
return count;
}
これだと、98文字以上の文字列に対応できない。
ポインタの表記
int sum (int *p, int size) {
int s=0, i;
for (i=0; i<size; i=i+1)
s=s+*(p[i]);
return s;
}
上記のプログラムはコンパイル時にエラーになる。
s=s+*(p+i);
あるいは
s=s+*(i+p);
あるいは
s=s+p[i];
とすればよい。
s=s+i[p];
も正解だが、授業中に言った通り、このように書くのはよくない。
プロトタイプ宣言
#include <stdio.h>
double addTwice (double, double)
int main (void) {
double x;
x=addTwice (15.0, 25.0);
printf ("%f\n", x);
return 0;
}
double addTwice (double x, double y){
return (x+y)*2;
}
上記のプログラムはコンパイル時にエラーになる。赤字の部分は
double addTwice (double, double);
のように最後にセミコロンが必要。仮引数部分に変数名を書いて
double addTwice (double x, double y);
のようにしてもよい。
初期化
#include <stdio.h>
Int squareSum (int n) {
int i, sum;
for (i=1, i<=n; i=i+1)
sum = sum + i*i;
return sum;
}
上記のプログラムはsumの初期値が定まっていない状態でsumの値を
使っているので、関数の返り値が何になるか分からない。
変数sumの宣言で0で初期化するか、あるいはループの前でsumに0を
代入すればよい。