blog/content/post/2008/03/18/2008-03-18-00000849.md

147 lines
9.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 『新版C言語プログラミングレッスン 入門編』の勉強
author: kazu634
date: 2008-03-18
url: /2008/03/18/_914/
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:3845;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- C
- Programming
---
<div class="section">
<p>
 頑張ってみるけど、「プロフェッショナルの流儀」が始まるまで。
</p>
<h4>
ユーザーからのインプットを待って対話的なプログラム
</h4>
<pre class="syntax-highlight">
<span class="synPreProc">#include </span><span class="synConstant">&#60;stdio.h&#62;</span>
<span class="synPreProc">#include </span><span class="synConstant">&#60;stdlib.h&#62;</span>
<span class="synPreProc">#define MAXLINE </span><span class="synConstant">256</span>
<span class="synType">int</span> main(<span class="synType">void</span>);
<span class="synType">int</span> main(<span class="synType">void</span>)
{
<span class="synType">char</span> buffer[MAXLINE];
<span class="synType">int</span> age;
printf (<span class="synConstant">&#34;Please enter your name.</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
gets(buffer);
printf (<span class="synConstant">&#34;Hi, </span><span class="synSpecial">%s</span><span class="synConstant">.</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, buffer);
printf (<span class="synConstant">&#34;Please enter your age.</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
gets(buffer);
age = atoi(buffer);
printf (<span class="synConstant">&#34;You are now </span><span class="synSpecial">%d</span><span class="synConstant">, so you will be </span><span class="synSpecial">%d</span><span class="synConstant"> in 10 years!</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, age, age + <span class="synConstant">10</span>);
<span class="synStatement">return</span>(<span class="synConstant"></span>);
}
</pre>
<ul>
<li>
C の文字列 (char) は、変数一つにつき一文字しか格納できないよ
</li>
<li>
atoi は ascii to integer Ascii文字から整数型へという意味
</li>
<li>
gets は標準出力からユーザーのインプットを待つ命令
</li>
</ul>
<h4>
九九
</h4>
<p>
 とりあえず打ち込んでみた。
</p>
<pre class="syntax-highlight">
<span class="synComment">/* 名前:九九練習プログラム */</span>
<span class="synComment">/* 書式:九九を練習する */</span>
<span class="synComment">/* 解説: */</span>
<span class="synComment">/*  プログラムkukuは、九九の問題をランダムに20個表示して */</span>
<span class="synComment">/*  その正答数と正解率を表示するプログラムです。 */</span>
<span class="synPreProc">#include </span><span class="synConstant">&#60;stdio.h&#62;</span>
<span class="synPreProc">#include </span><span class="synConstant">&#60;stdlib.h&#62;</span>
<span class="synPreProc">#include </span><span class="synConstant">&#60;time.h&#62;</span>
<span class="synPreProc">#define MAX_Q </span><span class="synConstant">20</span><span class="synPreProc"> </span><span class="synComment">/* 表示する問題の個数 */</span>
<span class="synPreProc">#define MAX_LINE </span><span class="synConstant">128</span><span class="synPreProc"> </span><span class="synComment">/* 入力行の最大長 */</span>
<span class="synType">int</span> main(<span class="synType">void</span>);
<span class="synType">void</span> kuku(<span class="synType">int</span> questno);
<span class="synType">int</span> good_answers = <span class="synConstant"></span>; <span class="synComment">/* 正答の数 */</span>
<span class="synComment">/* 関数mainは九九の練習をする。 */</span>
<span class="synComment">/* 問題をMAX_Q回繰り返す。 */</span>
<span class="synComment">/* 最後に結果を表示する。 */</span>
<span class="synType">int</span> main(<span class="synType">void</span>)
{
<span class="synType">int</span> i;
<span class="synType">float</span> rate;
<span class="synComment">/* 現在時刻を使って乱数の「種」を得る */</span>
srand((<span class="synType">unsigned</span> <span class="synType">int</span>)time(<span class="synConstant">NULL</span>));
printf (<span class="synConstant">&#34;これから九九の問題を </span><span class="synSpecial">%d</span><span class="synConstant"> 問出します。</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, MAX_Q);
good_answers = <span class="synConstant"></span>;
<span class="synStatement">for</span> (i = <span class="synConstant"></span>;i &#60; MAX_Q;i++) {
kuku(i);
}
rate = good_answers * <span class="synConstant">100.0</span> / MAX_Q;
printf (<span class="synConstant">&#34;問題は </span><span class="synSpecial">%d</span><span class="synConstant"> 問ありました。</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, MAX_Q);
printf (<span class="synConstant">&#34;</span><span class="synSpecial">%d</span><span class="synConstant"> 問は正しく答えられましたが、</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, good_answers);
printf (<span class="synConstant">&#34;</span><span class="synSpecial">%d</span><span class="synConstant"> 問は間違っていました。</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, MAX_Q - good_answers);
printf (<span class="synConstant">&#34;正答率 </span><span class="synSpecial">%0.1f</span><span class="synConstant"> </span><span class="synSpecial">%%</span><span class="synConstant"> です。</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>, rate);
printf (<span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
printf (<span class="synConstant">&#34;お疲れ様。</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
<span class="synStatement">return</span>(<span class="synConstant"></span>);
}
<span class="synComment">/* 関数kukuは九九の問題を一問出して、答えを待つ。 */</span>
<span class="synComment">/* 正答、誤答の別を表示する。 */</span>
<span class="synType">void</span> kuku(<span class="synType">int</span> questno)
{
<span class="synType">int</span> x, y, result;
<span class="synType">char</span> buffer[MAX_LINE];
x = rand() % <span class="synConstant">9</span> + <span class="synConstant">1</span>;
y = rand() % <span class="synConstant">9</span> + <span class="synConstant">1</span>;
printf (<span class="synConstant">&#34;[Question No. </span><span class="synSpecial">%d</span><span class="synConstant">] </span><span class="synSpecial">%d</span><span class="synConstant"> × </span><span class="synSpecial">%d</span><span class="synConstant"> =&#34;</span>, questno +<span class="synConstant">1</span>, x, y);
fflush(<span class="synConstant">stdout</span>);
gets(buffer);
result = atoi(buffer);
<span class="synStatement">if</span> ( x * y == result) {
printf (<span class="synConstant">&#34;Your answer is correct.</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
good_answers++;
}
<span class="synStatement">else</span> {
printf (<span class="synConstant">&#34;Your answer is wrong.</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
}
printf (<span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>);
}
</pre>
<p>
<a name="seemore"></a>
</p>
<p>
<a href="http://d.hatena.ne.jp/maq/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/maq/', 'id:maq');">id:maq</a> さんのコメントを読んで、「オーバーフロー」について調べる。
</p>
<blockquote title="C や C++ の危険なところ" cite="http://www.linux.or.jp/JF/JFdocs/Secure-Programs-HOWTO/dangers-c.html">
<p>
C ユーザは、確保されている領域を越えることはありえないと確証できなければ、 境界をチェックしない危険な関数を使うべきではありません。 通常使用を避けた方が良い(確実に防御すべき)関数には、strcpy(3)や strcat(3)、 sprintf(3)(親戚に当たる vsprintf(3))、gets(3) があります。 その代わりとして、strncpy(3)や、strncat(3)、snprintf(3)や fgets(3)の使用を お薦めします。詳しくは下記で論じますので読んでください。
</p>
<p>
<cite><a href="http://www.linux.or.jp/JF/JFdocs/Secure-Programs-HOWTO/dangers-c.html" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://www.linux.or.jp/JF/JFdocs/Secure-Programs-HOWTO/dangers-c.html', 'C や C++ の危険なところ');" target="_blank">C や C++ の危険なところ</a></cite>
</p>
</blockquote>
<p>
ということらしい。そういえば、gccでコンパイルしたら「gets使わない方がいいよ」的な警告が出ていたような。とりあえず現状、こういう難しい問題はひとまず置いておいて『<a href="http://d.hatena.ne.jp/asin/4797336781" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/asin/4797336781', '新版C言語プログラミングレッスン 入門編');">新版C言語プログラミングレッスン 入門編</a>』に準拠して勉強を進めていこうと考えてますです。
</p>
<p>
コメントありがとうございます(__)
</p>
</div>