#author("2023-06-28T19:09:46+09:00","ldap:bbm85148","土村 展之")
#author("2023-07-06T12:14:00+09:00","ldap:bbm85148","土村 展之")
* [[プログラミング実習II知能・機械:https://am.kwansei.ac.jp/prog2/]] の教科書 [#pbe6ca01]
『キックオフC言語 2023年度用』のサポートページです。

#contents


** 配布物 [#y5cd0c9a]
製本した印刷物は、授業の初回で配布します。
//A5版以外に、少量ですが大きめの手作りのB5版も用意しています。

PDF は以下で公開します。
- [[閲覧用:https://cs.kwansei.ac.jp/~tutimura/debug/KickOffC/KickOffC-2023view.pdf]]
-- 1章まで(目次など)を PDF の末尾に移動したので、書籍のページ番号と PDF のページ番号が一致します。
-- ページ番号が、版面の上と下の2ヶ所にあるので、ページ全体が表示されてなくても確認が容易です。
-- リンク部分の文字の色が「赤」です。
- [[印刷用:https://cs.kwansei.ac.jp/~tutimura/debug/KickOffC/KickOffC-2023print.pdf]]
-- 用紙の端に、章ごとの帯のような印(ツメ)があります。
-- リンク部分の文字の色が「黒」です。
-- B5用紙の中にA5の領域の版面があります。
--- 裁断できるのなら「B5用紙に原寸」で印刷してA5に裁断するか、「A4用紙に123%拡大」で印刷してB5に裁断します。(ツメが用紙の端まで印刷されます。)
--- 通常は「A5用紙に原寸」「B5用紙に123%拡大」のどちらかで印刷します。(ツメが用紙の端までは印刷できないでしょう。)
- [[ソースコード閲覧:https://cs.kwansei.ac.jp/~tutimura/debug/KickOffC/source/]]
-- [[全ファイルダウンロード:https://cs.kwansei.ac.jp/~tutimura/debug/KickOffC/KickOffC-2023source.zip]]

** 正誤表 [#c6e69f1d]

*** 2章 [#c02]
:p. 31 末尾|マクロ定数についての補足です。「#define 文はインデントせずに、プログラムの冒頭部分(#include のすぐ下)に記述するのが習慣です。」例えば [[p.135:https://cs.kwansei.ac.jp/~tutimura/debug/KickOffC/KickOffC-2023view.pdf#page=135]] のソースコード8.8などの使い方を参考にしてください。
:p. 34 問題4.|このスワップ動作は、3変数間で''同時に''行うことを意図しています。順次入れ替えるわけではありません。
:p. 34 問題8.|マクロ YEAR_PER_CENTURY は''2回''使用することに気をつけてください。

*** 3章 [#c03]
:p.52|問題9.を7章に移動して、今回の提出対象から除外します。そして、問題6.と、問題4.の考察をオプションにします。
:p.52 問題9.|「x の逆正弦を''弧度法''で返す。」→「x の逆正弦を''度数法(度)''で返す。」弧度法はラジアンで表すことなので、オリジナルの asin(x) の動作と同じになります。

*** 4章 [#c04]
:p.71 問題3.|「1個のelse-if」は「1個のifと1個のelse」と数えます。
:p.71 問題5.|動作確認のmain()と補助関数を例示しておきます。
 void print_exist_triangle(int a, int b, int c) {
     printf("3辺の長さが %d, %d, %d の三角形は", a, b, c);
     if (exist_triangle(a, b, c)) {
         printf("存在する\n");
     } else {
         printf("存在しない\n");
     }
 }
 
 int main(void) {
     print_exist_triangle(1, 1, 1);  // する
     print_exist_triangle(3, 4, 5);  // する
     print_exist_triangle(1, 1, 10); // しない
     print_exist_triangle(10, 5, 5); // しない
     print_exist_triangle(1, 15, 5); // しない
 }

*** 6章 [#c06]
:p.104 問題4.|whileループは、結果として消滅しても構いません。(案3) は、forループだけにすることを提案しています。
:p.104 問題7.|数値の表示形式は、桁数を増やす工夫をしてください。数列Akの0への収束が早いため、数値の変化を確かめるのに、表示桁数を増やす必要があります。

*** 7章 [#c07]
:p.119 問題0.|以下を追加します。『 問題0.[仮引数のスコープ(3.4節の復習)] p.45 の ソースコード3.7 の5行目のtriangle_side()関数について、仮引数を「(double a, double b, double c)」から「(double x, double y, double z)」に変更すると、そのままではコンパイルエラーになる。エラーを解消するための''最小限の修正''を行え。実行結果は修正前と同じになるようにせよ。4行目のコメント中の「a,b,c」は「x,y,z」に修正し、これ以外に不必要な(実行結果に影響しない)修正は行ってはならない。』

*** 8章 [#c08]
:p.142 問題8.|オプションの問題を追加しておきます。『問題8. [配列要素の全ペア] 東海道新幹線のぞみ号の停車する6つの駅の、東京駅からの距離(km)は、それぞれ
  東京  品川  新横浜 名古屋 京都  新大阪
  0.0    6.8   28.8  366.0  513.6  552.6 
である。この距離を''1次元配列''に格納し、以下の表のように、各駅の間の距離を''計算で''求めて表示するプログラムを作れ。
&br;・実行結果の、()内の駅名はヒントであるので、''数値部分だけ''を表示すればよい。
&br;・数値は "%8.1f" で表示すると、桁が揃いやすい。
&br;・絶対値を返す数学関数 fabs(x) を用いてよい。
 実行結果
           ( 東京)( 品川)(新横浜)(名古屋)( 京都)(新大阪)
 ( 東京)      0.0     6.8    28.8   366.0   513.6   552.6
 ( 品川)      6.8     0.0    22.0   359.2   506.8   545.8
 (新横浜)     28.8    22.0     0.0   337.2   484.8   523.8
 (名古屋)    366.0   359.2   337.2     0.0   147.6   186.6
 ( 京都)    513.6   506.8   484.8   147.6     0.0    39.0
 (新大阪)    552.6   545.8   523.8   186.6    39.0     0.0
』

*** 9章 [#c09]
:p.162 問題3.|『2.5.''1''項』→『2.5.''2''項』&br;toupper()の参照先が間違っていました。p.25です。また toupper() 関数は、変換の必要のない文字はそのまま返すので、事前に小文字であるかどうかの検査は不要です。
:p.162 問題4.|関数のプロトタイプと、main()関数を例示しておきます。また、参考にしたURLがコメント中に記載されていれば、採点の際に考慮します。
 void print_cancel_or_not(char weather[]) {
     /* ここを作る */
 }
 int main(void) {
     print_cancel_or_not("暴風雪警報");
     print_cancel_or_not("大雪警報");
     print_cancel_or_not("特別警報(大雪)");
 }
:p.162 問題5.|ヒントとして、p.131の8.4.3節を参照してください。
:p.162 問題6.|ヒントを追加します。charからintへの変換の式は「c - '0'」です。関数に独立させると、次の通りです。
 int char2int(char c) { return c - '0'; }
これを使うと、次のように、「1文字」から「整数」に変換されます。
 char2int('0') → 0
 char2int('1') → 1
 ...
 char2int('9') → 9

*** 10章 [#c10]
:p.178 問題5.|『(ii. 信頼性) ''プログラムを正確に作れる''』→『(ii. 信頼性) ''動作検証が容易である''』&br;(補足)レポートには「(i)関数呼び出しが有利。なぜなら... (ii)コピーして符号反転が有利。なぜなら... (iii)関数呼び出しが有利。なぜなら...」のように、3項目について、「関数呼び出し」と「コピーして符号反転」の2つの手法のどちらが有利かを述べること。
:p.178 問題6.|『逆数''にする''関数 frac_inv(*r) を追加せよ。』→『逆数''を求める''関数 frac_inv(*r'', *x'') を追加せよ。』引数を *r と *x の2個にして、*r = 1 / *x のように代入してください。&br;(補足)動作検証に用いる数値には、frac_t y = { -1, 4 }; のように、''除数の分子をマイナス''にした例を含めてください。
:p.178 問題7.|動作検証用のmain()を例示しておきます。
 int main(void) {
     quad_t q;
     sol_t s = { 2.0, 3.0 };
  
     quad_unsolve(&q, &s);
     printf("a=%f, b=%f, c=%f\n", q.a, q.b, q.c); // 1.0, -5.0, 6.0
 
     sol_solve(&s, &q);
     printf("alpha=%f, beta=%f\n", s.alpha, s.beta); // 2.0 と 3.0
 
     q.a = -2 * q.a;
     q.b = -2 * q.b;
     q.c = -2 * q.c;
     sol_solve(&s, &q);
     printf("alpha=%f, beta=%f\n", s.alpha, s.beta); // 2.0 と 3.0 のまま(入れ替わってもよい)
 }
:p.178 問題8.|追加です。『問題8. [標準ライブラリの構造体を用いる] ⇒12.1.1項』とすべきところでしたが、参照先(P.203)の指示をさらに単純化します。『10章 現在時刻を取得する以下の関数を作り、main()関数では、この関数を呼び出して、現在の時分秒を表示しなさい。
 #include <time.h>
 struct tm *get_current_time(void) {
     time_t t = time(NULL);
     return localtime(&t);
 }
struct tm の仕様は付録A.11(p.223)を参照し、ソースコード12.1(p.205)も参考にせよ。』

*** 11章 [#c11]
:p.198 問題2.|補足指示です。入力ファイルとして、次の内容を input.txt として保存して用いてください。
 123 One Two Three
 987 Nine Eight Seven
また、出力結果を提出してください。出力結果は「./11_6_2.exe > 11_6_2.txt」として保存した "11_6_2.txt" か、あるいは画面に出力された文字をコピー&ペーストしてテキストファイルを作成してください。
:p.198 問題3.|問題を差し替えます。『191ページのソースコード11.3を参考に、1行に1つの整数の記述されたファイルを読み取り、読み取った数値の''最大値''と''最小値''を表示せよ。』
~入力ファイルとして、次の内容を用い、出力結果も提出してください。
~入力ファイルとして、次の内容を in-value.txt として保存して用い、出力結果も提出してください。
 24
 53
 95
 48
 20
 75
 33
~ (ヒント1) 読み込む数値の範囲が 0 から 100 の間であることを利用してよい。(事前に範囲がわからない場合に INT_MAX, INT_MIN の定数を用いる手法もある。)
~ (ヒント2) 最大値と最小値は同時に求めるように考えてみよ。→192ページの頻出ミス(上)
~ (ヒント3) ファイル末尾に空行を追加した場合、最小値が 0 になることも試してみよ。→192ページの頻出ミス(下)
:p.198 問題5.|新たに追加します。→[[./11_6_5]]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS