『キックオフC言語 2022年度用』のサポートページです。
製本した印刷物は、授業の初回で配布します。A5版以外に、少量ですが大きめの手作りのB5版も用意しています。
PDF は以下で公開します。
- 閲覧用
- ページ番号が、ページの上と下の2ヶ所にあるので、ページ全体が表示されてなくても確認が容易です。
- リンク部分の文字の色が「赤」です。
- 印刷用
- ページ端に、章ごとの帯のような印(ツメ)があります。
- リンク部分の文字の色が「黒」です。
- B5用紙の中にA5の領域の版面があるので、裁断できるのなら「B5用紙に原寸」で印刷してA5に裁断するのがベストですが、通常は「A5用紙に原寸」「B5用紙に122%拡大」のどちらかで印刷するのがよいでしょう。
- ソースコード閲覧
正誤表†
『自動清算』→『自動精算』
まえがき†
- p.iv 下から6行目
- 『チーティング』→『ティーチング』
- p.50 問題6.と7.
- 難易度順的には、6.と7.を入れ替えておくべきでした。
- p.50 問題7.タイトル部分
- 『関数の再利用と信頼性』→『関数の信頼性・キャスト』再利用する場面は、特にありませんでした。逆にキャスト(p.30参照)の必要になる場合があります。
- p.50 問題8.
- 指示を追加します。『εはマクロ名をEPSとして定義せよ。(p.31を参照のこと。)』具体的には、次のような記述を #include の直後に書きます。ギリシャ文字のイプシロンはマルチバイト文字のため、識別子には使えません。
#define EPS 0.000001
- p.54 脚注*3
- 『単純に 2 つの if を並べるだけだと、 printf() が 2 回とも実行される場合があるので、 else if は必須です。』→『この例ではelseがなくても動作に変わりはありませんが、一般の条件では2つのifが同時に成り立つ可能性があるので、else ifで構造的に1回だけに絞っています。』
- p.69 問題2.
- 指示を追加します。
『if文1つで判定せよ。』『1個の if と1個の else で判定せよ。』
- p.69 問題4.
- 指示を追加します。『1≦m≦6 あるいは 1≦n≦3 のどちらの範囲にも該当しなければ、何も表示しない。この動作を void print_grade(int a) の関数に独立させ、また70ページのコラムを参考に、正しく動作することのわかる main() を作れ。』
- p.69 問題6.
- 辺の長さをintに限定するメリットは特にないので、関数のプロトタイプを『int exist_triangle(double a, double b, double c)』にしておくべきでした。(解答には影響しません。)
- p.70 問題7.
- 『x は 10 以上 990 以下の 10 の倍数』これは入力側の条件と考えてください。これ以外の値が与えられたときでも、エラー処理は不要です。
- p.86 問題0.
- 誤植ではありませんが、問題を追加します。
『次のプログラムの無駄を省いて、単純にせよ。(34ページの問題2.も参照のこと。)』
#include <stdio.h>
int main(void) {
int a;
for (int i=1; i<=5; i++) {
a = i * 10;
}
printf("%d\n", a);
return 0;
}
- p.86 問題8.
- 余力のある人向けに、以下を追加します。提出は必須ではありません。
『整数 y,m について定義される T(y,m) の値を表示してみよ。y は 2022 などの値1つを自由に選んで固定し、m は 3から14まですべてを試みよ。
T(y,m) = (y + y/4 - y/100 + y/400 + 13*(m+1)/5) % 7
そして、現実の y年m月1日の曜日との関係で、気づいたことを述べよ。なお、13月、14月は、翌年の1月、2月と対応付けて考えよ。』
- p102 問題6.と問題7.
- 誤植ではありませんが、以下のように問題を差し替え/廃止します。(元の問題をオプション課題として残しておきます。提出欄の ...6orig と 7orig です。)
6. [ある?ない?]
ソースコード 6.5 の is_prime3() を利用して、次の関数を作れ。
• int is_sum_of_2primes(int n) は、 n が 2 つの素数の和で表せれば論理型の TRUE、そうでなければ FALSE を返す。(追記)2つの素数は同じものでもよい。
そして main() 関数で、2 から 100 までの整数のうち、素数でもなく、2 つの素数の和でも表せないものを、すべて求めて表示せよ。
7. 廃止
- p102 問題9.
- 12章 の6章部分を参照してください。
- p.112 コラムのすぐ上の行
- 『場合には』→『変数には』意味が通じないので、訂正します。
- p.117 問題0.
- 以下を追加します。『 問題0.[仮引数のスコープ(3.5節の復習)] p.44 の リスト3.3 の5行目のtriangle()関数について、仮引数を「(double a, double b, double c)」から「(double x, double y, double z)」に変更すると、そのままではコンパイルエラーになる。エラーを解消するための最小限の修正を行え。実行結果は修正前と同じになるようにせよ。4行目のコメント中の「a,b,c」は「x,y,z」に修正し、これ以外に不必要な(実行結果に影響しない)修正は行ってはならない。』
3.5節での説明は不十分でした。仮引数のスコープはその関数全体であるため、仮引数がどんな名前であるかは、別の関数(呼び出し側)からは感知できないことに注意してください。
- p.117 問題A.
- 復習の問題を追加します。『問題A. [論理型の変数と関数(4.5節)] 次のプログラムの print_is_in_circle() 関数中の if の条件式を埋めよ。ヒント:「if (is_in_circle(x,y,r) == TRUE)」ではない。is_in_circle() 関数の return が条件式を返すことに着目して、p.62--p.65をよく読むこと。』
#include <stdio.h>
/* 点(x,y)が、原点を中心とする半径rの円の内側なら、論理型の TRUE、
そうでなければ FALSE を返す */
int is_in_circle(double x, double y, double r) {
return (x * x + y * y <= r * r);
}
void print_is_in_circle(double x, double y, double r) {
printf("(%g,%g)は、原点を中心とする半径 %g の円の", x, y, r);
if ( /* ここを埋めよ */ ) {
printf("内側\n");
} else {
printf("外側\n");
}
}
int main(void) {
print_is_in_circle(1.0, 1.0, 1.4142); // 外
print_is_in_circle(1.0, 1.0, 1.4143); // 内
print_is_in_circle(11, 4, 12); // 内
print_is_in_circle(11, 5, 12); // 外
return 0;
}
- p.117 下から1行目
- ユークリッドの互除法を説明していませんでした。WikiPedia.ja:ユークリッドの互除法#手続き的記述 などを参照してください。
- p.118 問題4.
- 指示を追加します。『4つの関数のプロトタイプ宣言を、プログラムの先頭部分(#include よりは後)に追加せよ。』また、main()関数のサンプルを例示しておきます。
#include <stdio.h>
int main(void) {
set_year(0); // 無効
set_month(0); // 無効
printf("year = %d, month = %d\n", get_year(), get_month());
set_year(2022);
set_month(6);
printf("year = %d, month = %d\n", get_year(), get_month());
return 0;
}
- p.154 問題3.
- toupper()については『2.5.1項』→『2.5.2項』を参照してください。p.25です。
- p.154 問題6.
- 12章 の9章部分を参照してください。
12章†
- p.191 6章
- 変更と補足があります。変更は、『1000, 500, 100のいずれか』→『5000, 1000, 500, 100のいずれか』と、受取可能な金額に5000も含めます。補足は、最後に次の文を追加します。『受け取れない金額に「受け取れません」と表示することは、最初の段階では考えなくても構いません。(6.4.3項のように、例外的な処理が必要になります。)』
- p.192 9章
- お釣りに1000円札を含めてください。そして表示するメッセージを『a円硬貨b枚』→『a円b枚』に変更してください。
- p.194 ソースコード中の7行目
- 以下のプロトタイプ宣言を挿入しておくべきでした。
/* プロトタイプ宣言 */
int input_int(void);
int sec2fee(int sec);
int is_coin_note(int value);
int get_coin_note(void);
int hms2sec(int h, int m, int s);
int sec_diff(int h1, int m1, int s1, int h2, int m2, int s2);
void put_change(int x);
struct tm get_current_time(void);
int decide_fee(void);
int receive_fee(int fee);
- p.195 ソースコード中の60行目
- 『%d:%d:%d』→『%d:%02d:%02d』分と秒は、1桁の数字でも0を補って、2桁で表示する必要がありました。
13章†
- p.203 ソースコード 13.2の7行目
- コメント中の引数名が不一致です。『aとbがほぼ等しければ0, a>bなら正, a<bなら負を返す』→『xとyがほぼ等しければ0, x>yなら正, x<yなら負を返す』
- p.208 コラムの1行目
- 『終端を示こと』→『終端を示すこと』