<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Serendip &#187; language-c</title>
	<atom:link href="http://www.serendip.ws/archives/tag/language-c/feed" rel="self" type="application/rss+xml" />
	<link>http://www.serendip.ws</link>
	<description>Webデザイン・プログラミング</description>
	<lastBuildDate>Fri, 03 Feb 2012 05:40:44 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>C言語で行末の空白を赤の下線で強調表示する</title>
		<link>http://www.serendip.ws/archives/4649</link>
		<comments>http://www.serendip.ws/archives/4649#comments</comments>
		<pubDate>Sat, 03 Apr 2010 12:43:53 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4649</guid>
		<description><![CDATA[C言語でターミナルで表示される文字をカラー表示させる でのエスケープシーケンスによるカラー表示を使って行末の空白文字列を明示させてみる。 空白文字が見つかったら空白以外の文字が見つかるまでスキップして、見つか]]></description>
			<content:encoded><![CDATA[<p><a href="/archives/4635">C言語でターミナルで表示される文字をカラー表示させる</a> でのエスケープシーケンスによるカラー表示を使って行末の空白文字列を明示させてみる。</p>
<p>空白文字が見つかったら空白以外の文字が見つかるまでスキップして、見つかった空白以外の文字が <code>'\n'</code> ならば下線付きでカラー表示させてスキップ回数分の空白を出力する。<br />
見つかった空白以外の文字は <code>ungetc</code> を使って標準入力に戻す。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>

<span class="PreProc">#define CHAR_SPACE </span><span class="Constant">' '</span>

<span class="PreProc">#define COLOR_RED     </span><span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[31m&quot;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> 前景色 赤 </span><span class="Comment">*/</span>
<span class="PreProc">#define COLOR_DEFAULT </span><span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[39m&quot;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> 前景色 デフォルト </span><span class="Comment">*/</span>
<span class="PreProc">#define DEC_UNDERLINE </span><span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[4m&quot;</span><span class="PreProc">  </span><span class="Comment">/*</span><span class="Comment"> 装飾   下線 </span><span class="Comment">*/</span>
<span class="PreProc">#define DEC_DEFAULT   </span><span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[0m&quot;</span><span class="PreProc">  </span><span class="Comment">/*</span><span class="Comment"> 装飾   デフォルト </span><span class="Comment">*/</span>

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">int</span> c, count;

    <span class="Statement">while</span> ((c = getchar()) != <span class="Constant">EOF</span>) {
        <span class="Statement">if</span> (c == CHAR_SPACE) {
            count = <span class="Constant">1</span>;
            <span class="Statement">while</span> ((c = getchar()) == CHAR_SPACE) {
                count++;
            }
            <span class="Statement">if</span> (c == <span class="Special">'\n'</span>) {
                printf(COLOR_RED);
                printf(DEC_UNDERLINE);
            }
            <span class="Statement">while</span> (count-- &gt; <span class="Constant">0</span>) {
                putchar(CHAR_SPACE);
            }
            <span class="Statement">if</span> (c == <span class="Special">'\n'</span>) {
                printf(COLOR_DEFAULT);
                printf(DEC_DEFAULT);
            }
            ungetc(c, <span class="Constant">stdin</span>);
        } <span class="Statement">else</span> {
            putchar(c);
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}
</pre>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/lang_c_tail_space_visualize.png" alt="iTerm で行末の空白文字列を強調表示した Screenshot" title="iTerm で行末の空白文字列を強調表示した Screenshot" width="400" height="250" class="size-full wp-image-4648" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4649/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C言語でターミナルで表示される文字をカラー表示させる</title>
		<link>http://www.serendip.ws/archives/4635</link>
		<comments>http://www.serendip.ws/archives/4635#comments</comments>
		<pubDate>Fri, 02 Apr 2010 02:35:51 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4635</guid>
		<description><![CDATA[C言語でエスケープシーケンスを使って端末に表示される文字・背景をカラー表示させてみる。 \x1b は ESC の16進表記 背景色 前景色 黒 \x1b[40m 黒 \x1b[30m 赤 \x1b[41m 赤 \x1b[ [...]]]></description>
			<content:encoded><![CDATA[<p>C言語でエスケープシーケンスを使って端末に表示される文字・背景をカラー表示させてみる。</p>
<p><code>\x1b</code> は <code>ESC</code> の16進表記</p>
<table class="entry-table-style">
<tr>
<th colspan="2">背景色</th>
<th colspan="2">前景色</th>
</tr>
<tr>
<td style="background-color:black;color:white;">黒</td>
<td><code>\x1b[40m</code></td>
<td style="background-color:white;color:black;">黒</td>
<td><code>\x1b[30m</code></td>
</tr>
<tr>
<td style="background-color:red;color:white;">赤</td>
<td><code>\x1b[41m</code></td>
<td style="background-color:black;color:red;">赤</td>
<td><code>\x1b[31m</code></td>
</tr>
<tr>
<td style="background-color:green;color:white;">緑</td>
<td><code>\x1b[42m</code></td>
<td style="background-color:black;color:green;">緑</td>
<td><code>\x1b[32m</code></td>
</tr>
<tr>
<td style="background-color:yellow;color:black;">黄色</td>
<td><code>\x1b[43m</code></td>
<td style="background-color:black;color:yellow;">黄色</td>
<td><code>\x1b[33m</code></td>
</tr>
<tr>
<td style="background-color:blue;color:white;">青</td>
<td><code>\x1b[44m</code></td>
<td style="background-color:black;color:blue;">青</td>
<td><code>\x1b[34m</code></td>
</tr>
<tr>
<td style="background-color:magenta;color:black;">マゼンタ</td>
<td><code>\x1b[45m</code></td>
<td style="background-color:black;color:magenta;">マゼンタ</td>
<td><code>\x1b[35m</code></td>
</tr>
<tr>
<td style="background-color:cyan;color:black;">シアン</td>
<td><code>\x1b[46m</code></td>
<td style="background-color:black;color:cyan;">シアン</td>
<td><code>\x1b[36m</code></td>
</tr>
<tr>
<td style="background-color:gray;color:white;">灰色</td>
<td><code>\x1b[47m</code></td>
<td style="background-color:black;color:white;">白</td>
<td><code>\x1b[37m</code></td>
</tr>
<tr>
<td>デフォルトに戻す</td>
<td><code>\x1b[49m</code></td>
<td>デフォルトに戻す</td>
<td><code>\x1b[39m</code></td>
</tr>
</table>
<p></p>
<table class="entry-table-style">
<tr>
<th colspan="2">その他の装飾</th>
</tr>
<tr>
<td style="text-decoration:underline;">下線</td>
<td><code>\x1b[4m</code></td>
</tr>
<tr>
<td style="font-weight:bold;">高輝度（太字化）</td>
<td><code>\x1b[1m</code></td>
</tr>
<tr>
<td style="color:#fffcef;background-color:#211;">反転（背景色と前景色の入れ替え）</td>
<td><code>\x1b[7m</code></td>
</tr>
<tr>
<td>デフォルトに戻す</td>
<td><code>\x1b[0m</code></td>
</tr>
</table>
<h3>サンプルコード</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Comment">/*</span><span class="Comment"> 背景色の指定 </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[40m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を黒に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が黒</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[41m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を赤に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が赤</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[42m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を緑に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が緑</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[43m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を黄色に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が黄色</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[44m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を青に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が青</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[45m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色をマゼンタに </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景がマゼンタ</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[46m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色をシアンに </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景がシアン</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[47m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色を灰色に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景が灰色</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[49m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 背景色をデフォルトに戻す </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;背景色がデフォルト</span><span class="Special">\n</span><span class="Constant">&quot;</span>);

    printf(<span class="Constant">&quot;</span><span class="Special">\n</span><span class="Constant">&quot;</span>);

    <span class="Comment">/*</span><span class="Comment"> 前景色の指定 </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[30m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を黒に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が黒</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[31m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を赤に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が赤</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[32m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を緑に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が緑</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[33m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を黄色に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が黄色</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[34m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を青に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が青</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[35m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色をマゼンタに </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色がマゼンタ</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[36m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色をシアンに </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色がシアン</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[37m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色を白に </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色が白</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[39m&quot;</span>);     <span class="Comment">/*</span><span class="Comment"> 前景色をデフォルトに戻す </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;前景色がデフォルト</span><span class="Special">\n</span><span class="Constant">&quot;</span>);

    printf(<span class="Constant">&quot;</span><span class="Special">\n</span><span class="Constant">&quot;</span>);

    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[4m&quot;</span>);      <span class="Comment">/*</span><span class="Comment"> 下線を付ける </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;下線を付ける</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[1m&quot;</span>);      <span class="Comment">/*</span><span class="Comment"> 高輝度 </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;高輝度</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[7m&quot;</span>);      <span class="Comment">/*</span><span class="Comment"> 反転（背景色と前景色の入れ替え） </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;反転（背景色と前景色の入れ替え）</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    printf(<span class="Constant">&quot;</span><span class="Special">\x1b</span><span class="Constant">[0m&quot;</span>);      <span class="Comment">/*</span><span class="Comment"> デフォルトに戻す </span><span class="Comment">*/</span>
    printf(<span class="Constant">&quot;デフォルトに戻す</span><span class="Special">\n</span><span class="Constant">&quot;</span>);

    <span class="Statement">return</span> <span class="Constant">0</span>;
}
</pre>
<h3>上記のコードのスクリーンショット</h3>
<p>Mac OSX 付属の Terminal での表示</p>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/lang_c_color_mac_terminal_ss.png" alt="C言語 Mac OSX Terminal カラー表示 Screenshot" title="C言語 Mac OSX Terminal カラー表示 Screenshot" width="337" height="458" class="size-full wp-image-4643" /></p>
<p>Mac OSX の iTerm での表示</p>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/lang_c_color_mac_iterm_ss.png" alt="C言語 Mac OSX iTerm カラー表示 Screenshot" title="C言語 Mac OSX iTerm カラー表示 Screenshot" width="342" height="522" class="size-full wp-image-4644" /></p>
<p>Ubuntu 9.10 KarmicKoala の Gnome Terminal での表示</p>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/lang_c_color_ubuntu_gnome_terminal_ss.png" alt="C言語 Ubuntu 9.10 KarmicKoala Gnome Terminal カラー表示 Screenshot" title="C言語 Ubuntu 9.10 KarmicKoala Gnome Terminal カラー表示 Screenshot" width="368" height="566" class="size-full wp-image-4645" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4635/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>8.7 記憶割当て, 演習8-7 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4575</link>
		<comments>http://www.serendip.ws/archives/4575#comments</comments>
		<pubDate>Wed, 31 Mar 2010 13:50:47 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4575</guid>
		<description><![CDATA[8.7 記憶割当て malloc, free の簡単な実装を学ぶ。 malloc 時に要求サイズが空きブロックより小さい場合に、後側からブロックを使用していくことに気がつかず、理解するのに時間がかかった。 後側からブロッ [...]]]></description>
			<content:encoded><![CDATA[<h3>8.7 記憶割当て</h3>
<p><code>malloc</code>, <code>free</code> の簡単な実装を学ぶ。</p>
<p><code>malloc</code> 時に要求サイズが空きブロックより小さい場合に、後側からブロックを使用していくことに気がつかず、理解するのに時間がかかった。<br />
後側からブロックを使用していくのは、空きリストのポインタを変更しなくてもよいからだろうか。</p>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/malloc_memory_fig.png" alt="malloc メモリ図" title="malloc メモリ図" width="473" height="765" class="size-full wp-image-4576" /></p>
<h3>演習8-7</h3>
<p><code>malloc</code> での妥当なサイズの条件がいまいちわからない。<br />
負の値が渡された場合、<code>unsigned</code> に変換されて大きなサイズが要求されるので、そのチェックを入れてみた。</p>
<p><code>free</code> での正しいサイズ・フィールドというのもわからない。<br />
解放ブロックのヘッダ位置と次のポインタの差が解放ブロックのサイズの場合が正しいサイズということだろうか。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>

<span class="Type">typedef</span> <span class="Type">long</span> Align;     <span class="Comment">/*</span><span class="Comment"> long の境界に整合させる </span><span class="Comment">*/</span>

<span class="Type">union</span> header {          <span class="Comment">/*</span><span class="Comment"> ブロックのヘッダ </span><span class="Comment">*/</span>
    <span class="Type">struct</span> {
        <span class="Type">union</span> header *ptr;  <span class="Comment">/*</span><span class="Comment"> 空きリストの上なら次のブロック </span><span class="Comment">*/</span>
        <span class="Type">unsigned</span> size;      <span class="Comment">/*</span><span class="Comment"> このブロックの大きさ </span><span class="Comment">*/</span>
    } s;
    Align x;            <span class="Comment">/*</span><span class="Comment"> ブロックの整合を強制 </span><span class="Comment">*/</span>
};

<span class="Type">typedef</span> <span class="Type">union</span> header Header;

<span class="Type">void</span> *my_malloc(<span class="Type">unsigned</span>);
<span class="Type">static</span> Header *morecore(<span class="Type">unsigned</span>);
<span class="Type">void</span> my_free(<span class="Type">void</span> *);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> *s, *p;

    <span class="Statement">if</span> ((s = my_malloc(<span class="Constant">10</span>)) == <span class="Constant">NULL</span>) {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't allocate memory</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }
    <span class="Statement">if</span> ((p = my_malloc(<span class="Constant">10</span>)) == <span class="Constant">NULL</span>) {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't allocate memory</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }

    s[<span class="Constant">0</span>] = <span class="Constant">'h'</span>;
    s[<span class="Constant">1</span>] = <span class="Constant">'e'</span>;
    s[<span class="Constant">2</span>] = <span class="Constant">'l'</span>;
    s[<span class="Constant">3</span>] = <span class="Constant">'l'</span>;
    s[<span class="Constant">4</span>] = <span class="Constant">'o'</span>;
    s[<span class="Constant">5</span>] = <span class="Constant">'!'</span>;
    s[<span class="Constant">6</span>] = <span class="Special">'\0'</span>;

    p[<span class="Constant">0</span>] = <span class="Constant">'H'</span>;
    p[<span class="Constant">1</span>] = <span class="Constant">'E'</span>;
    p[<span class="Constant">2</span>] = <span class="Constant">'L'</span>;
    p[<span class="Constant">3</span>] = <span class="Constant">'L'</span>;
    p[<span class="Constant">4</span>] = <span class="Constant">'O'</span>;
    p[<span class="Constant">5</span>] = <span class="Constant">'!'</span>;
    p[<span class="Constant">6</span>] = <span class="Special">'\0'</span>;

    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, s);
    printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, p);
    my_free(s);
    my_free(p);

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Type">static</span> Header base;     <span class="Comment">/*</span><span class="Comment"> 開始時の空きリスト </span><span class="Comment">*/</span>
<span class="Type">static</span> Header *freep = <span class="Constant">NULL</span>;    <span class="Comment">/*</span><span class="Comment"> 空きリストの先頭 </span><span class="Comment">*/</span>

<span class="Comment">/*</span><span class="Comment"> my_malloc : 汎用の記憶割当てプログラム </span><span class="Comment">*/</span>
<span class="Type">void</span> *my_malloc(<span class="Type">unsigned</span> nbytes)
{
    Header *p, *prevp;
    Header *morecore(<span class="Type">unsigned</span>);
    <span class="Type">unsigned</span> nunits;

    <span class="Statement">if</span> ((<span class="Type">long</span>) nbytes &lt;= <span class="Constant">0</span>) { <span class="Comment">/*</span><span class="Comment"> 引数が正の整数かをチェック </span><span class="Comment">*/</span>
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;my_malloc : wrong memory size </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, nbytes);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }

    nunits = (nbytes + <span class="Statement">sizeof</span>(Header) - <span class="Constant">1</span>) / <span class="Statement">sizeof</span>(Header) + <span class="Constant">1</span>;
    <span class="Statement">if</span> ((prevp = freep) == <span class="Constant">NULL</span>) {  <span class="Comment">/*</span><span class="Comment"> 空きリストはまだない </span><span class="Comment">*/</span>
        base.s.ptr = freep = prevp = &amp;base;
        base.s.size = <span class="Constant">0</span>;
    }
    <span class="Statement">for</span> (p = prevp-&gt;s.ptr; ; prevp = p, p = p-&gt;s.ptr) {
        <span class="Statement">if</span> (p-&gt;s.size &gt;= nunits) {  <span class="Comment">/*</span><span class="Comment"> 十分大きい </span><span class="Comment">*/</span>
            <span class="Statement">if</span> (p-&gt;s.size == nunits) {  <span class="Comment">/*</span><span class="Comment"> 正確に </span><span class="Comment">*/</span>
                prevp-&gt;s.ptr = p-&gt;s.ptr;
            } <span class="Statement">else</span> {    <span class="Comment">/*</span><span class="Comment"> 後尾の部分を割り当て </span><span class="Comment">*/</span>
                p-&gt;s.size -= nunits;
                p += p-&gt;s.size;
                p-&gt;s.size = nunits;
            }
            freep = prevp;
            <span class="Statement">return</span> (<span class="Type">void</span> *)(p+<span class="Constant">1</span>);
        }
        <span class="Statement">if</span> (p == freep) {   <span class="Comment">/*</span><span class="Comment"> 空きリストをリング状につなぐ </span><span class="Comment">*/</span>
            <span class="Statement">if</span> ((p = morecore(nunits)) == <span class="Constant">NULL</span>) {
                <span class="Statement">return</span> <span class="Constant">NULL</span>;    <span class="Comment">/*</span><span class="Comment"> 残りなし </span><span class="Comment">*/</span>
            }
        }
    }
}

<span class="PreProc">#define NALLOC </span><span class="Constant">1024</span><span class="PreProc">     </span><span class="Comment">/*</span><span class="Comment"> 要求する最小の単位数 </span><span class="Comment">*/</span>

<span class="Comment">/*</span><span class="Comment"> morecore : システムにもっとメモリを要求する </span><span class="Comment">*/</span>
<span class="Type">static</span> Header *morecore(<span class="Type">unsigned</span> nu)
{
    <span class="Type">char</span> *cp, *sbrk(<span class="Type">int</span>);
    Header *up;

    <span class="Statement">if</span> (nu &lt; NALLOC) {
        nu = NALLOC;
    }
    cp = sbrk(nu * <span class="Statement">sizeof</span>(Header));
    <span class="Statement">if</span> (cp == (<span class="Type">char</span> *) - <span class="Constant">1</span>) {   <span class="Comment">/*</span><span class="Comment"> スペースが全然ない </span><span class="Comment">*/</span>
        <span class="Statement">return</span> <span class="Constant">NULL</span>;
    }
    up = (Header *) cp;
    up-&gt;s.size = nu;
    my_free((<span class="Type">void</span> *) (up + <span class="Constant">1</span>));
    <span class="Statement">return</span> freep;
}

<span class="Comment">/*</span><span class="Comment"> my_free :  ブロック ap を空きリストに入れる </span><span class="Comment">*/</span>
<span class="Type">void</span> my_free(<span class="Type">void</span> *ap)
{
    Header *bp, *p;

    bp = (Header *) ap - <span class="Constant">1</span>;     <span class="Comment">/*</span><span class="Comment"> ブロック・ヘッダを指す </span><span class="Comment">*/</span>
    <span class="Statement">for</span> (p = freep; !(bp &gt; p &amp;&amp; bp &lt; p-&gt;s.ptr); p = p-&gt;s.ptr) {
        <span class="Statement">if</span> (p &gt;= p-&gt;s.ptr &amp;&amp; (bp &gt; p || bp &lt; p-&gt;s.ptr)) {
            <span class="Statement">break</span>;  <span class="Comment">/*</span><span class="Comment"> 領域の始めあるいは終りの解放ブロック </span><span class="Comment">*/</span>
        }
    }
    <span class="Statement">if</span> ((bp &lt; p-&gt;s.ptr) &amp;&amp;  <span class="Comment">/*</span><span class="Comment"> 次の領域が後方にある場合 </span><span class="Comment">*/</span>
            ((p-&gt;s.ptr - bp - bp-&gt;s.size) != <span class="Constant">0</span>)) { <span class="Comment">/*</span><span class="Comment"> ブロックサイズのチェック </span><span class="Comment">*/</span>
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;my_free : wrong block size </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, bp-&gt;s.size);
    }
    <span class="Statement">if</span> (bp + bp-&gt;s.size == p-&gt;s.ptr) {  <span class="Comment">/*</span><span class="Comment"> 上の nbr へ結合 </span><span class="Comment">*/</span>
        bp-&gt;s.size += p-&gt;s.ptr-&gt;s.size;
        bp-&gt;s.ptr = p-&gt;s.ptr-&gt;s.ptr;
    } <span class="Statement">else</span> {
        bp-&gt;s.ptr = p-&gt;s.ptr;
    }
    <span class="Statement">if</span> (p + p-&gt;s.size == bp) {  <span class="Comment">/*</span><span class="Comment"> 下の nbr へ結合 </span><span class="Comment">*/</span>
        p-&gt;s.size += bp-&gt;s.size;
        p-&gt;s.ptr = bp-&gt;s.ptr;
    } <span class="Statement">else</span> {
        p-&gt;s.ptr = bp;
    }
    freep = p;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4575/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-6 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4571</link>
		<comments>http://www.serendip.ws/archives/4571#comments</comments>
		<pubDate>Fri, 26 Mar 2010 13:57:15 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4571</guid>
		<description><![CDATA[演習8-6 void *my_calloc(unsigned n, unsigned size) { void *p; if ((p = my_malloc(size * n)) == NULL) { fprintf(s [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-6</h3>
<p><img src="http://www.serendip.ws/wordpress/wp-content/uploads/calloc_memory_fig.png" alt="calloc メモリ図" title="calloc メモリ図" width="457" height="146" class="size-full wp-image-4572" /></p>
<pre><span class="Type">void</span> *my_calloc(<span class="Type">unsigned</span> n, <span class="Type">unsigned</span> size)
{
    <span class="Type">void</span> *p;

    <span class="Statement">if</span> ((p = my_malloc(size * n)) == <span class="Constant">NULL</span>) {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't allocate memory</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
        exit(<span class="Constant">EXIT_FAILURE</span>);
    }
    memset(p, <span class="Constant">0</span>, size * n);

    <span class="Statement">return</span> p;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4571/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-5 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4543</link>
		<comments>http://www.serendip.ws/archives/4543#comments</comments>
		<pubDate>Wed, 24 Mar 2010 13:57:40 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4543</guid>
		<description><![CDATA[演習8-5 リンク数 (st_nlink) と最後に inode が変更された時間 (st_ctime) を表示させてみる。 #include &#60;time.h&#62; #define MAX_TIME_STR 10 [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-5</h3>
<p>リンク数 (<code>st_nlink</code>) と最後に <code>inode</code> が変更された時間 (<code>st_ctime</code>) を表示させてみる。</p>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;time.h&gt;</span>

<span class="PreProc">#define MAX_TIME_STR </span><span class="Constant">100</span>

<span class="Type">void</span> parseTm(<span class="Type">const</span> <span class="Type">struct</span> tm *tp, <span class="Type">char</span> *str)
{
    strftime(str, MAX_TIME_STR, <span class="Constant">&quot;</span><span class="Special">%b</span><span class="Constant"> </span><span class="Special">%d</span><span class="Constant"> %Y %H:%M:</span><span class="Special">%S</span><span class="Constant">&quot;</span>, tp);
}

<span class="Comment">/*</span><span class="Comment"> fsize : ファイル &quot;name&quot; のサイズを印字する </span><span class="Comment">*/</span>
<span class="Type">void</span> fsize(<span class="Type">char</span> *name)
{
    <span class="Type">struct</span> stat stbuf;
    <span class="Type">char</span> timestr[MAX_TIME_STR];

    <span class="Statement">if</span> (stat(name, &amp;stbuf) == -<span class="Constant">1</span>) {
        fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;fsize : can't access </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name);
        <span class="Statement">return</span>;
    }
    <span class="Statement">if</span> ((stbuf.st_mode &amp; S_IFMT) == S_IFDIR) {
        dirwalk(name, fsize);
    }
    parseTm(localtime(&amp;stbuf.st_ctime), timestr);
    printf(<span class="Constant">&quot;</span><span class="Special">%4d</span><span class="Constant"> </span><span class="Special">%8ld</span><span class="Constant"> </span><span class="Special">%s</span><span class="Constant"> </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, stbuf.st_nlink, stbuf.st_size, timestr, name);
}
</pre>
<p>実行結果</p>
<pre>$ ./fsize *
   1      155 Mar 16 2010 12:00:36 Makefile
   1    10560 Mar 16 2010 12:39:46 fsize
   1     3763 Mar 16 2010 12:39:44 main.c
   1    10244 Mar 16 2010 12:39:46 main.o
   1      840 Mar 16 2010 12:02:18 my_dirent.h
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4543/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-4 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4531</link>
		<comments>http://www.serendip.ws/archives/4531#comments</comments>
		<pubDate>Mon, 22 Mar 2010 11:41:10 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4531</guid>
		<description><![CDATA[演習8-4 /* fp に対してファイルの位置を指定する * バイナリ・ファイルに対しては、origin から offset 文字だけ離れたところにセットする * origin には MY_SEEK_SET (始め),  [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-4</h3>
<pre><span class="Comment">/*</span><span class="Comment"> fp に対してファイルの位置を指定する</span>
<span class="Comment"> * バイナリ・ファイルに対しては、origin から offset 文字だけ離れたところにセットする</span>
<span class="Comment"> * origin には MY_SEEK_SET (始め), MY_SEEK_CUR (現在位置), MY_SEEK_END (ファイルの終り) が指定可能</span>
<span class="Comment"> * テキスト・ファイルに対しては、offset はゼロ、または ftell (この場合は origin は MY_SEEK_SET) で返される値でなければならない</span>
<span class="Comment"> * エラーの場合は fseek からはゼロ以外の値が返される</span>
<span class="Comment"> </span><span class="Comment">*/</span>
<span class="Type">int</span> my_fseek(MY_FILE *fp, <span class="Type">long</span> offset, <span class="Type">int</span> origin)
{
    <span class="Type">int</span> result = <span class="Constant">0</span>;

    <span class="Statement">if</span> (fp == MY_NULL) {
        <span class="Statement">return</span> -<span class="Constant">1</span>;
    }
    <span class="Statement">if</span> (fp-&gt;flag &amp; _WRITE) {
        <span class="Statement">if</span> (my_fflush(fp) == MY_EOF) {
            <span class="Statement">return</span> MY_EOF;
        }
        result = lseek(fp-&gt;fd, offset, origin);
    } <span class="Statement">else</span> <span class="Statement">if</span> (fp-&gt;flag &amp; _READ) {
        <span class="Statement">if</span> (origin == MY_SEEK_CUR) { <span class="Comment">/*</span><span class="Comment"> 現在位置からの場合 </span><span class="Comment">*/</span>
            offset -= fp-&gt;cnt;
        }
        result = lseek(fp-&gt;fd, offset, origin);
    }
    <span class="Statement">return</span> (result == -<span class="Constant">1</span>) ? -<span class="Constant">1</span> : <span class="Constant">0</span>;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4531/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-3 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4526</link>
		<comments>http://www.serendip.ws/archives/4526#comments</comments>
		<pubDate>Sun, 21 Mar 2010 14:16:35 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4526</guid>
		<description><![CDATA[演習8-3 この _flushbuf と my_putc だと、fp-&#62;cnt が 0 未満にならずに終了してしまう場合に、どうしてもデータがバッファに残ったまま書き出されない状態になってしまう。 /* _flus [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-3</h3>
<p>この <code>_flushbuf</code> と <code><a href="/archives/4517">my_putc</a></code> だと、<code>fp-&gt;cnt</code> が <code>0</code> 未満にならずに終了してしまう場合に、どうしてもデータがバッファに残ったまま書き出されない状態になってしまう。</p>
<pre><span class="Comment">/*</span><span class="Comment"> _flushbuf : 出力バッファを書き出す</span>
<span class="Comment"> * ファイルが書き込み用にオープンされていなければ即座に MY_EOF を返す</span>
<span class="Comment"> </span><span class="Comment">*/</span>
<span class="Type">int</span> _flushbuf(<span class="Type">int</span> c, MY_FILE *fp)
{
    <span class="Type">int</span> bufsize, n_write;
    <span class="Type">unsigned</span> <span class="Type">char</span> uc = c;

    <span class="Statement">if</span> ((fp-&gt;flag&amp;(_WRITE|_EOF|_ERR)) != _WRITE) {
        <span class="Statement">return</span> MY_EOF;
    }

    <span class="Statement">if</span> (fp-&gt;flag &amp;_UNBUF) { <span class="Comment">/*</span><span class="Comment"> バッファを使わない場合 </span><span class="Comment">*/</span>
        n_write = write(fp-&gt;fd, &amp;uc, <span class="Constant">1</span>);
        bufsize = <span class="Constant">1</span>;
    } <span class="Statement">else</span> {
        <span class="Statement">if</span> (fp-&gt;base == MY_NULL) { <span class="Comment">/*</span><span class="Comment"> バッファがまだ未割り当ての場合 </span><span class="Comment">*/</span>
            <span class="Statement">if</span> ((fp-&gt;base = (<span class="Type">char</span> *) malloc(MY_BUFSIZ)) == MY_NULL) {
                <span class="Statement">return</span> MY_EOF;
            }
            fp-&gt;ptr = fp-&gt;base;
            *fp-&gt;ptr++ = uc;
            fp-&gt;cnt = MY_BUFSIZ - <span class="Constant">2</span>; <span class="Comment">/*</span><span class="Comment"> 最初の文字分を引く (MY_BUFSIZ - 1 - 1)</span><span class="Comment">*/</span>
            <span class="Statement">return</span> <span class="Constant">0</span>;
        }
        <span class="Statement">if</span> (fp-&gt;ptr) {
          <span class="Statement">if</span> (c != MY_EOF) { <span class="Comment">/*</span><span class="Comment"> バッファの最後に c を追加する </span><span class="Comment">*/</span>
            *fp-&gt;ptr++ = uc;
          }
          bufsize = MY_BUFSIZ - fp-&gt;cnt - <span class="Constant">1</span>;
          fp-&gt;ptr = fp-&gt;base;
          fp-&gt;cnt = MY_BUFSIZ - <span class="Constant">1</span>;
          n_write = write(fp-&gt;fd, fp-&gt;base, bufsize); <span class="Comment">/*</span><span class="Comment"> バッファを書き出す </span><span class="Comment">*/</span>
        }
    }

    <span class="Statement">if</span> (n_write != bufsize) {
        fp-&gt;flag |= _ERR;
        <span class="Statement">return</span> MY_EOF;
    }

    <span class="Statement">return</span> uc;
}

<span class="Comment">/*</span><span class="Comment"> バッファに残っているデータを書き出す</span>
<span class="Comment"> * 書き込みエラーがあると MY_EOF を返し、それ以外では 0 を返す</span>
<span class="Comment"> * my_fflush(MY_NULL) で全てのストリームをはき出す</span>
<span class="Comment"> </span><span class="Comment">*/</span>
<span class="Type">int</span> my_fflush(MY_FILE *fp)
{
    <span class="Type">int</span> i;

    <span class="Statement">if</span> (fp == MY_NULL) {
        <span class="Statement">for</span> (i = <span class="Constant">0</span>; i&lt; MY_OPEN_MAX; i++) {
            my_fflush(&amp;_iob[i]);
        }
    } <span class="Statement">else</span> {
        <span class="Statement">if</span> ((fp-&gt;flag&amp;(_WRITE)) == <span class="Constant">0</span>) {
            <span class="Statement">return</span> MY_EOF;
        }
        _flushbuf(MY_EOF, fp);
        <span class="Statement">if</span> (fp-&gt;flag &amp; _ERR) {
            <span class="Statement">return</span> MY_EOF;
        }
    }
    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> まだ書き出されていないデータを my_fflush で書き出し</span>
<span class="Comment"> * まだ読み込まれていないデータを破棄して、バッファを解放する</span>
<span class="Comment"> * エラーがあると MY_EOF を返し、それ以外では 0 を返す</span>
<span class="Comment"> </span><span class="Comment">*/</span>
<span class="Type">int</span> my_fclose(MY_FILE *fp)
{
    <span class="Statement">if</span> (fp == MY_NULL) {
        <span class="Statement">return</span> MY_EOF;
    }
    my_fflush(fp);
    fp-&gt;cnt = <span class="Constant">0</span>;
    fp-&gt;ptr = MY_NULL;
    <span class="Statement">if</span> (fp-&gt;base) {
        free(fp-&gt;base);
    }
    fp-&gt;base = MY_NULL;
    fp-&gt;flag = <span class="Constant">0</span>;
    fp-&gt;fd = -<span class="Constant">1</span>;
    <span class="Statement">return</span> <span class="Constant">0</span>;
}
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4526/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-2 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4517</link>
		<comments>http://www.serendip.ws/archives/4517#comments</comments>
		<pubDate>Sat, 20 Mar 2010 14:21:32 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4517</guid>
		<description><![CDATA[演習8-2 #include &#60;stdio.h&#62; #include &#60;stdlib.h&#62; #include &#60;unistd.h&#62; #include &#60;fcntl.h&#62; #d [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-2</h3>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;unistd.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;fcntl.h&gt;</span>

<span class="PreProc">#define MY_NULL </span><span class="Constant">0</span>
<span class="PreProc">#define MY_EOF (-</span><span class="Constant">1</span><span class="PreProc">)</span>
<span class="PreProc">#define MY_BUFSIZ </span><span class="Constant">1024</span>
<span class="PreProc">#define MY_OPEN_MAX </span><span class="Constant">20</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> 一時に開けるファイルの最大数 </span><span class="Comment">*/</span>

<span class="Comment">/*</span><span class="Comment"> フラグのビットフィールド </span><span class="Comment">*/</span>
<span class="Type">struct</span> flags {
    <span class="Type">unsigned</span> <span class="Type">int</span> is_read    : <span class="Constant">1</span>;
    <span class="Type">unsigned</span> <span class="Type">int</span> is_write   : <span class="Constant">1</span>;
    <span class="Type">unsigned</span> <span class="Type">int</span> is_unbuf   : <span class="Constant">1</span>;
    <span class="Type">unsigned</span> <span class="Type">int</span> is_eof     : <span class="Constant">1</span>;
    <span class="Type">unsigned</span> <span class="Type">int</span> is_err     : <span class="Constant">1</span>;
};

<span class="Type">typedef</span> <span class="Type">struct</span> _iobuf {
    <span class="Type">int</span> cnt;            <span class="Comment">/*</span><span class="Comment"> 残っている文字数 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *ptr;          <span class="Comment">/*</span><span class="Comment"> 次の文字位置 </span><span class="Comment">*/</span>
    <span class="Type">char</span> *base;         <span class="Comment">/*</span><span class="Comment"> バッファの位置 </span><span class="Comment">*/</span>
    <span class="Type">struct</span> flags flag;  <span class="Comment">/*</span><span class="Comment"> ファイル・アクセスのモード </span><span class="Comment">*/</span>
    <span class="Type">int</span> fd;             <span class="Comment">/*</span><span class="Comment"> ファイル記述子 </span><span class="Comment">*/</span>
} MY_FILE;
<span class="Type">extern</span> MY_FILE _iob[MY_OPEN_MAX];

<span class="PreProc">#define my_stdin   (&amp;_iob[</span><span class="Constant">0</span><span class="PreProc">])</span>
<span class="PreProc">#define my_stdout  (&amp;_iob[</span><span class="Constant">1</span><span class="PreProc">])</span>
<span class="PreProc">#define my_stderr  (&amp;_iob[</span><span class="Constant">2</span><span class="PreProc">])</span>

<span class="Type">int</span> _fillbuf(MY_FILE *);
<span class="Type">int</span> _flushbuf(<span class="Type">int</span>, MY_FILE *);

<span class="PreProc">#define feof(p)     ((p)-&gt;flag.is_eof == </span><span class="Constant">1</span><span class="PreProc">)</span>
<span class="PreProc">#define ferror(p)   ((p)-&gt;flag.is_err == </span><span class="Constant">1</span><span class="PreProc">)</span>
<span class="PreProc">#define fileno(p)   ((p)-&gt;fd)</span>

<span class="PreProc">#define my_getc(p)     (--(p)-&gt;cnt &gt;= </span><span class="Constant">0</span><span class="PreProc"> \</span>
<span class="PreProc">        ? (</span><span class="Type">unsigned</span><span class="PreProc"> </span><span class="Type">char</span><span class="PreProc">) *(p)-&gt;ptr++ : _fillbuf(p))</span>
<span class="PreProc">#define my_putc(x, p)  (--(p)-&gt;cnt &gt;= </span><span class="Constant">0</span><span class="PreProc"> \</span>
<span class="PreProc">        ? *(p)-&gt;ptr++ = (x) : _flushbuf((x), p))</span>

<span class="PreProc">#define my_getchar()   my_getc(my_stdin)</span>
<span class="PreProc">#define my_putchar(x)  my_putc((x), my_stdout)</span>

MY_FILE _iob[MY_OPEN_MAX] = { <span class="Comment">/*</span><span class="Comment"> my_stdin, my_stdout, my_stderr: </span><span class="Comment">*/</span>
    { <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, {<span class="Constant">1</span>, <span class="Constant">0</span>, <span class="Constant">0</span>, <span class="Constant">0</span>, <span class="Constant">0</span>}, <span class="Constant">0</span> },
    { <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, {<span class="Constant">0</span>, <span class="Constant">1</span>, <span class="Constant">0</span>, <span class="Constant">0</span>, <span class="Constant">0</span>}, <span class="Constant">1</span> },
    { <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, (<span class="Type">char</span> *) <span class="Constant">0</span>, {<span class="Constant">0</span>, <span class="Constant">1</span>, <span class="Constant">1</span>, <span class="Constant">0</span>, <span class="Constant">0</span>}, <span class="Constant">2</span> }
};

MY_FILE *my_fopen(<span class="Type">char</span>*, <span class="Type">char</span>*);

<span class="Type">int</span> main(<span class="Type">int</span> argc, <span class="Type">char</span> *argv[])
{
    <span class="Type">int</span> c;
    <span class="Type">char</span> mode = <span class="Constant">'r'</span>;
    MY_FILE *fp;

    <span class="Statement">if</span> (argc == <span class="Constant">2</span>) {
        <span class="Statement">if</span> ((fp = my_fopen(argv[<span class="Constant">1</span>], &amp;mode)) == MY_NULL) {
            fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't open </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, argv[<span class="Constant">1</span>]);
            exit(<span class="Constant">EXIT_FAILURE</span>);
        }
        <span class="Statement">while</span> ((c = my_getc(fp)) != MY_EOF) {
            printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant">&quot;</span>, c);
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="PreProc">#define PERMS </span><span class="PreProc">0</span><span class="Constant">666</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> 所有者、グループ、他人に対して RW </span><span class="Comment">*/</span>

<span class="Comment">/*</span><span class="Comment"> my_fopen : ファイルを開いて、ファイル・ポインタを返す </span><span class="Comment">*/</span>
MY_FILE *my_fopen(<span class="Type">char</span> *name, <span class="Type">char</span> *mode)
{
    <span class="Type">int</span> fd;
    MY_FILE *fp;

    <span class="Statement">if</span> (*mode != <span class="Constant">'r'</span> &amp;&amp; *mode != <span class="Constant">'w'</span> &amp;&amp; *mode != <span class="Constant">'a'</span>) {
        <span class="Statement">return</span> MY_NULL;
    }
    <span class="Statement">for</span> (fp = _iob; fp &lt; _iob + MY_OPEN_MAX; fp++) {
        <span class="Statement">if</span> ((fp-&gt;flag.is_read == <span class="Constant">0</span> &amp;&amp; fp-&gt;flag.is_write == <span class="Constant">0</span>)) {
            <span class="Statement">break</span>; <span class="Comment">/*</span><span class="Comment"> found free slot </span><span class="Comment">*/</span>
        }
    }
    <span class="Statement">if</span> (fp &gt;= _iob + MY_OPEN_MAX) { <span class="Comment">/*</span><span class="Comment"> 空きスロットなし </span><span class="Comment">*/</span>
        <span class="Statement">return</span> MY_NULL;
    }

    <span class="Statement">if</span> (*mode == <span class="Constant">'w'</span>) {
        fd = creat(name, PERMS);
    } <span class="Statement">else</span> <span class="Statement">if</span> (*mode == <span class="Constant">'a'</span>) {
        <span class="Statement">if</span> ((fd = open(name, O_WRONLY, <span class="Constant">0</span>)) == -<span class="Constant">1</span>) {
            fd = creat(name, PERMS);
        }
        lseek(fd, <span class="Constant">0L</span>, <span class="Constant">2</span>);
    } <span class="Statement">else</span> {
        fd = open(name, O_RDONLY, <span class="Constant">0</span>);
    }
    <span class="Statement">if</span> (fd == -<span class="Constant">1</span>) { <span class="Comment">/*</span><span class="Comment"> 名前がアクセス不能 </span><span class="Comment">*/</span>
        <span class="Statement">return</span> MY_NULL;
    }
    fp-&gt;fd = fd;
    fp-&gt;cnt = <span class="Constant">0</span>;
    fp-&gt;base = MY_NULL;
    <span class="Statement">if</span> (*mode == <span class="Constant">'r'</span>) {
        fp-&gt;flag.is_read = <span class="Constant">1</span>;
        fp-&gt;flag.is_write = <span class="Constant">0</span>;
    } <span class="Statement">else</span> {
        fp-&gt;flag.is_read = <span class="Constant">0</span>;
        fp-&gt;flag.is_write = <span class="Constant">1</span>;
    }
    <span class="Statement">return</span> fp;
}

<span class="Comment">/*</span><span class="Comment"> _fillbuf : 入力バッファを割り当てて、詰める </span><span class="Comment">*/</span>
<span class="Type">int</span> _fillbuf(MY_FILE *fp)
{
    <span class="Type">int</span> bufsize;

    <span class="Statement">if</span> (!fp-&gt;flag.is_read &amp;&amp; fp-&gt;flag.is_eof &amp;&amp; fp-&gt;flag.is_err) {
        <span class="Statement">return</span> MY_EOF;
    }
    bufsize = fp-&gt;flag.is_unbuf ? <span class="Constant">1</span> : MY_BUFSIZ;
    <span class="Statement">if</span> (fp-&gt;base == MY_NULL) { <span class="Comment">/*</span><span class="Comment"> バッファがまだない </span><span class="Comment">*/</span>
        <span class="Statement">if</span> ((fp-&gt;base = (<span class="Type">char</span> *) malloc(bufsize)) == MY_NULL) {
            <span class="Statement">return</span> MY_EOF; <span class="Comment">/*</span><span class="Comment"> バッファがとれない </span><span class="Comment">*/</span>
        }
    }
    fp-&gt;ptr = fp-&gt;base;
    fp-&gt;cnt = read(fp-&gt;fd, fp-&gt;ptr, bufsize);
    <span class="Statement">if</span> (--fp-&gt;cnt &lt; <span class="Constant">0</span>) {
        <span class="Statement">if</span> (fp-&gt;cnt == -<span class="Constant">1</span>) {
            fp-&gt;flag.is_eof = <span class="Constant">1</span>;
        } <span class="Statement">else</span> {
            fp-&gt;flag.is_err = <span class="Constant">1</span>;
        }
        fp-&gt;cnt = <span class="Constant">0</span>;
        <span class="Statement">return</span> MY_EOF;
    }
    <span class="Statement">return</span> (<span class="Type">unsigned</span> <span class="Type">char</span>) *fp-&gt;ptr++;
}
</pre>
<p>実行結果</p>
<p>ビット演算を使っている版のプログラム <code>fopen</code> と、ビットフィールドを使った版のプログラム <code>fopen2</code> とで比較してみる。</p>
<pre>$ time ./fopen /var/log/system.log &gt;/dev/null

real    0m0.332s
user    0m0.292s
sys     0m0.039s
$ time ./fopen2 /var/log/system.log &gt;/dev/null

real    0m0.330s
user    0m0.290s
sys     0m0.039s
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4517/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習8-1 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4507</link>
		<comments>http://www.serendip.ws/archives/4507#comments</comments>
		<pubDate>Fri, 19 Mar 2010 05:49:08 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4507</guid>
		<description><![CDATA[演習8-1 p208 の syscalls.h のインクルードの代わりに unistd.h をインクルードする。 参考：ふつうの Linux プログラミング p80 ふつうのLinuxプログラミング Linuxの仕組みか [...]]]></description>
			<content:encoded><![CDATA[<h3>演習8-1</h3>
<p>p208 の <code>syscalls.h</code> のインクルードの代わりに <code>unistd.h</code> をインクルードする。<br />
参考：ふつうの Linux プログラミング p80</p>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797328355/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41jYVY2og7L._SL160_.jpg" alt="ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797328355/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4797328355/serendip7822-22/ref=nosim/" title="ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道" target="_blank">amazlet</a> at 10.03.11</div>
</div>
<div class="amazlet-detail">青木 峰郎 <br />ソフトバンククリエイティブ <br />売り上げランキング: 26006</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797328355/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;unistd.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;fcntl.h&gt;</span>

<span class="Type">int</span> main(<span class="Type">int</span> argc, <span class="Type">char</span> *argv[])
{
    <span class="Type">int</span> fd;
    <span class="Comment">/*</span><span class="Comment"> ファイルポインタの代わりにファイルディスクリプタを引数にとる filecopy </span><span class="Comment">*/</span>
    <span class="Type">void</span> filecopy(<span class="Type">int</span>, <span class="Type">int</span>);

    <span class="Statement">if</span> (argc == <span class="Constant">1</span>) { <span class="Comment">/*</span><span class="Comment"> 引数なし、標準入力をコピー </span><span class="Comment">*/</span>
        filecopy(<span class="Constant">0</span>, <span class="Constant">1</span>);
    } <span class="Statement">else</span> {
        <span class="Statement">while</span> (--argc &gt; <span class="Constant">0</span>) {
            <span class="Statement">if</span> ((fd = open(*++argv, O_RDONLY, <span class="Constant">0</span>)) == -<span class="Constant">1</span>) {
                fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;cat: can't open </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, *argv);
                <span class="Statement">return</span> <span class="Constant">1</span>;
            } <span class="Statement">else</span> {
                filecopy(fd, <span class="Constant">1</span>);
                close(fd);
            }
        }
    }

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> filecopy : ファイル ifd をファイル ofd にコピー </span><span class="Comment">*/</span>
<span class="Type">void</span> filecopy(<span class="Type">int</span> ifd, <span class="Type">int</span> ofd)
{
    <span class="Type">int</span> n;
    <span class="Type">char</span> buf[<span class="Constant">BUFSIZ</span>];

    <span class="Statement">while</span> ((n = read(ifd, buf, <span class="Constant">BUFSIZ</span>)) &gt; <span class="Constant">0</span>) {
        write(ofd, buf, n);
    }
}
</pre>
<p>実行結果</p>
<p>上のコード(<code>ex8-1</code>)と7章(p197)の <code>cat</code> 第1版 (<code>my_cat1</code>)とシステムインストール済みの <code>cat</code> (OSX Snow Leopard版) とで比較してみる。</p>
<pre>$ time ./ex8-1 /var/log/system.log &gt;/dev/null

real    0m0.063s
user    0m0.012s
sys     0m0.050s

$ time ./my_cat1 /var/log/system.log &gt;/dev/null

real    0m0.295s
user    0m0.273s
sys     0m0.019s

$ time cat /var/log/system.log &gt;/dev/null

real    0m0.012s
user    0m0.001s
sys     0m0.011s
</pre>
<p>システムコールを使った方が標準ライブラリを使ったものよりも速かった。<br />
当然ながら OSX 付属の <code>cat</code> が最速。</p>
<p><code>filecopy</code> でのバッファリングを使わないバージョンでも試してみる。</p>
<pre><span class="Comment">/*</span><span class="Comment"> filecopy : ファイル ifd をファイル ofd にコピー (バッファリングなし) </span><span class="Comment">*/</span>
<span class="Type">void</span> filecopy(<span class="Type">int</span> ifd, <span class="Type">int</span> ofd)
{
    <span class="Type">int</span> n;
    <span class="Type">char</span> c;

    <span class="Statement">while</span> ((n = read(ifd, &amp;c, <span class="Constant">1</span>)) &gt; <span class="Constant">0</span>) {
        write(ofd, &amp;c, n);
    }
}
</pre>
<p>実行結果</p>
<pre>$ time ./ex8-1 /var/log/system.log &gt;/dev/null

real    0m49.766s
user    0m11.336s
sys     0m38.255s
</pre>
<p>遅っ</p>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4507/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>演習7-9 K&amp;R プログラミング言語C</title>
		<link>http://www.serendip.ws/archives/4502</link>
		<comments>http://www.serendip.ws/archives/4502#comments</comments>
		<pubDate>Sun, 14 Mar 2010 13:21:05 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[language-c]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4502</guid>
		<description><![CDATA[演習7-9 スペースを節約する isupper #include &#60;stdio.h&#62; int my_isupper(unsigned char); int main(void) { char c1 = 'd' [...]]]></description>
			<content:encoded><![CDATA[<h3>演習7-9</h3>
<h4>スペースを節約する <code>isupper</code></h4>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>

<span class="Type">int</span> my_isupper(<span class="Type">unsigned</span> <span class="Type">char</span>);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> c1 = <span class="Constant">'d'</span>;
    <span class="Type">char</span> c2 = <span class="Constant">'D'</span>;

    printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant"> isupper? =&gt; </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, c1, my_isupper(c1));
    printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant"> isupper? =&gt; </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, c2, my_isupper(c2));

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> スペースを節約する isupper </span><span class="Comment">*/</span>
<span class="Type">int</span> my_isupper(<span class="Type">unsigned</span> <span class="Type">char</span> c)
{
    <span class="Statement">if</span> (c &gt;= <span class="Constant">'A'</span> &amp;&amp; c &lt;= <span class="Constant">'Z'</span>) {
        <span class="Statement">return</span> c;
    } <span class="Statement">else</span> {
        <span class="Statement">return</span> <span class="Constant">0</span>;
    }
}
</pre>
<p>実行結果</p>
<pre>$ ./ex7-9a
d isupper? =&gt; 0
D isupper? =&gt; 68
</pre>
<h4>実行時間を短かくする <code>isupper</code></h4>
<pre><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
<span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>

<span class="Type">int</span> my_isupper(<span class="Type">unsigned</span> <span class="Type">char</span>);

<span class="Type">int</span> main(<span class="Type">void</span>)
{
    <span class="Type">char</span> c1 = <span class="Constant">'d'</span>;
    <span class="Type">char</span> c2 = <span class="Constant">'D'</span>;

    printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant"> isupper? =&gt; </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, c1, my_isupper(c1));
    printf(<span class="Constant">&quot;</span><span class="Special">%c</span><span class="Constant"> isupper? =&gt; </span><span class="Special">%d</span><span class="Special">\n</span><span class="Constant">&quot;</span>, c2, my_isupper(c2));

    <span class="Statement">return</span> <span class="Constant">0</span>;
}

<span class="Comment">/*</span><span class="Comment"> 実行時間を短かくする isupper </span><span class="Comment">*/</span>
<span class="Type">int</span> my_isupper(<span class="Type">unsigned</span> <span class="Type">char</span> c)
{
    <span class="Statement">if</span> (strchr(<span class="Constant">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;</span>, c)) {
        <span class="Statement">return</span> c;
    } <span class="Statement">else</span> {
        <span class="Statement">return</span> <span class="Constant">0</span>;
    }
}
</pre>
<p>実行結果</p>
<pre>$ ./ex7-9b
d isupper? =&gt; 0
D isupper? =&gt; 68
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL160_.jpg" alt="プログラミング言語C 第2版 ANSI規格準拠" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語C 第2版 ANSI規格準拠</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4320026926/serendip7822-22/ref=nosim/" title="プログラミング言語C 第2版 ANSI規格準拠" target="_blank">amazlet</a> at 09.11.27</div>
</div>
<div class="amazlet-detail">B.W. カーニハン D.M. リッチー <br />共立出版 <br />売り上げランキング: 9726</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4502/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

