<?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>simple idea &#187; Program</title>
	<atom:link href="http://www.k14a.net/archives/category/program/feed" rel="self" type="application/rss+xml" />
	<link>http://www.k14a.net</link>
	<description>simple is beautiful</description>
	<lastBuildDate>Tue, 10 Aug 2010 08:55:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>新入社員応援企画(その4)</title>
		<link>http://www.k14a.net/archives/103</link>
		<comments>http://www.k14a.net/archives/103#comments</comments>
		<pubDate>Mon, 13 Apr 2009 03:19:20 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[pointer]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=103</guid>
		<description><![CDATA[

《問題》
任意の型value1およびvalue2を入れ替える関数swap()を作成しなさい。

《解答例》
数値型でも文字列でも構造体でも入れ替えることができることができるようにするには、どうすればいいのか。
文字列 [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F103%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E6%96%B0%E5%85%A5%E7%A4%BE%E5%93%A1%E5%BF%9C%E6%8F%B4%E4%BC%81%E7%94%BB%28%E3%81%9D%E3%81%AE4%29%22%20%7D);"></div>
<p>《問題》<br />
任意の型value1およびvalue2を入れ替える関数swap()を作成しなさい。<br />
<span id="more-103"></span><br />
《解答例》<br />
数値型でも文字列でも構造体でも入れ替えることができることができるようにするには、どうすればいいのか。<br />
文字列を扱うことから、ポインタのポインタが必要なことはわかる。では、swap()に渡される値がどのような型になるのかは、想定できない。でも、C言語にはvoid*と言うのがある。<br />
これは、どのような型かはわからないけれど、とりあえずなにかのポインタであると言うことがわかる型である。<br />
実際に書くとこうなる。</p>
<pre class="brush: c; ">

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

int     swap(void **value1, void **value2)
{
        void *work = NULL;

        work = *value1;
        *value1 = *value2;
        *value2 = work;

        return(0);
}
</pre>
<p>まるで、文字列のときと同じように見える。と言うかchar**がvoid**に替わっただけ。これで、どのような方が来ても対応できるはず。<br />
ただし、呼び出す側にはちょっと工夫が必要になってくる。</p>
<pre class="brush: c; ">

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

typedef struct person {
        int     id;
        char    name[50];
} PERSON;

int     main(int argc, char *argv[])
{
        int     a = 100;
        int     b = 200;
        int     *pa = &amp;a;
        int     *pb = &amp;b;
        char    x[] = &quot;abc&quot;;
        char    y[] = &quot;xyz&quot;;
        char    *px = x;
        char    *py = y;
        PERSON  emp1;
        PERSON  emp2;
        PERSON  *pe1 = &amp;emp1;
        PERSON  *pe2 = &amp;emp2;

        swap((void **)&amp;pa, (void **)&amp;pb);
        swap((void **)&amp;px, (void **)&amp;py);
        swap((void **)&amp;pe1, (void **)&amp;pe2);

        exit (0);
}
</pre>
<p>swap()を呼び出す場合、引数がポインタのポインタになっているので、それにあわせる必要があるのと、void**なのでキャストをする必要がある。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/103/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新入社員応援企画(その3)</title>
		<link>http://www.k14a.net/archives/95</link>
		<comments>http://www.k14a.net/archives/95#comments</comments>
		<pubDate>Mon, 13 Apr 2009 02:43:59 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[pointer]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=95</guid>
		<description><![CDATA[

《問題》
以下の構造体PERSON型変数value1およびvalue2を入れ替える関数stswap()を作成しなさい。


typedef struct person {
        int     id;
   [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F95%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E6%96%B0%E5%85%A5%E7%A4%BE%E5%93%A1%E5%BF%9C%E6%8F%B4%E4%BC%81%E7%94%BB%28%E3%81%9D%E3%81%AE3%29%22%20%7D);"></div>
<p>《問題》<br />
以下の構造体PERSON型変数value1およびvalue2を入れ替える関数stswap()を作成しなさい。</p>
<pre class="brush: c; ">

typedef struct person {
        int     id;
        char    name[50];
} PERSON;
</pre>
<p><span id="more-95"></span><br />
《解答例》<br />
今回はオリジナルの構造体。さて、この場合数値または文字列のどちらにすればいいのか?<br />
とりあえず、数値型と同じように作ってみる。</p>
<pre class="brush: c; ">

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

int     stswap(PERSON *value1, PERSON *value2)
{
        PERSON  work;

        work = *value1;
        *value1 = *value2;
        *value2 = work;

        return(0);
}
</pre>
<p>実はこれであっさりと動いてしまう。<br />
なぜなら、構造体といえどもひとつの「型」として取扱えるので、数値型と同じように取扱うことができる。逆に言うと、文字列のときが特殊と言うかC言語には「文字列」という型がなく、そのため「文字型の配列」で代用しているため、このようなことが起こる。早い話、C言語に「文字列型」あればよかったと言うことかな。<br />
でも、そんなことをいっても仕方がないので、文字列をきちんと取扱えるようになる必要がある。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新入社員応援企画(その2)</title>
		<link>http://www.k14a.net/archives/85</link>
		<comments>http://www.k14a.net/archives/85#comments</comments>
		<pubDate>Mon, 13 Apr 2009 02:20:39 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[pointer]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=85</guid>
		<description><![CDATA[

《問題》
文字列型変数value1およびvalue2の中身を入れ替える関数sswap()を作成しなさい。ただし、strcpy()、memcpy()などは使用しないこと。

《解答例》
数値型のnswap()の応用版。 [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F85%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E6%96%B0%E5%85%A5%E7%A4%BE%E5%93%A1%E5%BF%9C%E6%8F%B4%E4%BC%81%E7%94%BB%28%E3%81%9D%E3%81%AE2%29%22%20%7D);"></div>
<p>《問題》<br />
文字列型変数value1およびvalue2の中身を入れ替える関数sswap()を作成しなさい。ただし、strcpy()、memcpy()などは使用しないこと。<br />
<span id="more-85"></span><br />
《解答例》<br />
数値型のnswap()の応用版。ただし、文字列のコピーなどを使用しないで作成する。<br />
とりあえず、ポインタを使って書いてみる。</p>
<pre class="brush: c; ">

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

int     sswap(char *value1, char *value2)
{
        char *work = NULL;

        work = value1;
        value1 = value2;
        value2 = work;

        return(0);
}
</pre>
<p>残念ながら、これだとsswap()から戻ると値が戻っていることに気づくはず。<br />
なぜなら、C言語では文字列自体がポインタで表現されているため、*value1、*value2で受け取った値は文字列そのものを受け取ったことになる。すなわち、nswap()でのvalue1、value2と同じ状態になっている。<br />
では、文字列を入れ替えるにはどうすればいいか…ポインタのポインタを使用する。</p>
<pre class="brush: c; ">

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

int     sswap(char **value1, char **value2)
{
        char *work = NULL;

        work = *value1;
        *value1 = *value2;
        *value2 = work;

        return(0);
}
</pre>
<p>こうすることにより、*value1、*value2で文字列が格納されているポインタ(アドレス)にアクセスできるため、ポインタを入れ替えることにより、呼び出し元の変数が指している文字列のポインタを変更することができる。なお、sswap()内では、文字列自体には一切手を付けていない。<br />
まぁ、こんなことをしなくてもstrcpy()を使えば一発なんだけれど、それを言ってしまえば実もふたもなくなるということで…。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/85/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新入社員応援企画(その1)</title>
		<link>http://www.k14a.net/archives/71</link>
		<comments>http://www.k14a.net/archives/71#comments</comments>
		<pubDate>Mon, 13 Apr 2009 01:56:29 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[pointer]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=71</guid>
		<description><![CDATA[

《問題》
数値型の変数value1およびvalue2の中身を入れ替える関数nswap()を作成しなさい。

《解答例》
C言語を学ぶ上でのバイブルともいえる「プログラミング言語C」にも書いてある有名な例題。

普通に [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F71%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E6%96%B0%E5%85%A5%E7%A4%BE%E5%93%A1%E5%BF%9C%E6%8F%B4%E4%BC%81%E7%94%BB%28%E3%81%9D%E3%81%AE1%29%22%20%7D);"></div>
<p>《問題》<br />
数値型の変数value1およびvalue2の中身を入れ替える関数nswap()を作成しなさい。</p>
<p><span id="more-71"></span></p>
<p>《解答例》<br />
C言語を学ぶ上でのバイブルともいえる「プログラミング言語C」にも書いてある有名な例題。<br />
<a href="http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC-ANSI%E8%A6%8F%E6%A0%BC%E6%BA%96%E6%8B%A0-B-W-%E3%82%AB%E3%83%BC%E3%83%8B%E3%83%8F%E3%83%B3/dp/4320026926%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dk14a-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4320026926"><img src="http://ecx.images-amazon.com/images/I/41W69WGATNL._SL75_.jpg" alt="" /></a><br />
普通に書くとたぶんこんな感じになるのかな。</p>
<pre class="brush: c; ">

#include   &lt;stdio.h&gt;
#include   &lt;stdlib.h&gt;
#include   &lt;string.h&gt;
int     nswap(int value1, int value2)
{
        int     work;

        work = value1;
        value1 = value2;
        value2 = work;

        return(0);
}
</pre>
<p>ただ、こうするとnswap()の中では確かにvalue1とvalue2の内容は入れ替わるがnswap()から戻ったら元の状態になっている。<br />
C言語では、関数の引数は<a href="http://ja.wikipedia.org/wiki/%E5%80%A4%E6%B8%A1%E3%81%97#.E5.80.A4.E6.B8.A1.E3.81.97">値渡し</a>となっているため、nswap()が扱うvalue1、value2はそれぞれコピーされたものになる。よって、nswap()内でいくら値を変更しても呼び出した側へ影響を与えることはない。<br />
では、nswap()で引数の内容を変更して戻すにはどうすればいいか…そう、ポインタを使う。</p>
<pre class="brush: c; ">

#include   &lt;stdio.h&gt;
#include   &lt;stdlib.h&gt;
#include   &lt;string.h&gt;

int     nswap(int *value1, int *value2)
{
        int     work;

        work = *value1;
        *value1 = *value2;
        *value2 = work;

        return(0);
}
</pre>
<p>value1およびvalue2をポインタで受けることにより、*value1、*value2で直接呼び出し元の変数にアクセスすることができるようになる。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/71/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>関数ポインタを使ってみる</title>
		<link>http://www.k14a.net/archives/51</link>
		<comments>http://www.k14a.net/archives/51#comments</comments>
		<pubDate>Sun, 29 Mar 2009 13:51:23 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[pointer]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=51</guid>
		<description><![CDATA[

関数ポインタって、引数として変数ではなく関数を渡すもの。百聞は一見にしかずということで、前回使ったキュー&#38;スタックに検索用の関数を追加する。
《que.h(追加分)》


int    que_search( [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F51%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E9%96%A2%E6%95%B0%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B%22%20%7D);"></div>
<p>関数ポインタって、引数として変数ではなく関数を渡すもの。百聞は一見にしかずということで、前回使った<a href="http://www.k14a.net/archives/26">キュー&amp;スタック</a>に検索用の関数を追加する。</p>
<p>《que.h(追加分)》</p>
<pre class="brush: c; ">

int    que_search(
        const void *target, void **data,
        int (*search)(const void *src, const void *dst)
);
</pre>
<p>プロトタイプ宣言にque_search()を追加する。関数ポインタとしてsearch()を受取る。search()には、比較元のデータであるsrcと比較対象のデータであるdstが必要。</p>
<p>《que.c(追加分)》</p>
<pre class="brush: c; ">

int     que_search(const void *target, void **data, int (*search)(const void *src, const void *dst))
{
        QUE     *p = NULL;
        int     status;

        p = root.next;

        for(;;) {
                if (p == &amp;root) {
                        return(1);
                }
                status = search(target, p-&gt;data);
                if (status == 0) {
                        *data = p-&gt;data;
                        free(p);
                        return(0);
                } else {
                        p = p-&gt;next;
                }
        }

        return (0);
}
</pre>
<p>変数targetと、QUEの中に格納されているdataの値を関数ポインタのsearch()に渡して、その結果が0である場合に、一致したとしてQUEの中にあるdataを返す。<br />
ここで、重要なのがsearch()には、上にも書いた二つの引数以外に、戻り値としてsrcとdstが一致した場合には0、不一致の場合には0以外を返す必要がある。</p>
<p>《main.c》</p>
<pre class="brush: c; ">

#include  &quot;que.h&quot;

int     main(int argc, char **argv)
{
        int     status;
        char    *str = NULL;
        char    *src = NULL;

        status = que_enque(&quot;fuga&quot;);
        status = que_enque(&quot;hoge&quot;);
        status = que_enque(&quot;geho&quot;);
        status = que_enque(&quot;one&quot;);
        status = que_enque(&quot;two&quot;);
        status = que_enque(&quot;three&quot;);

        src = strdup(&quot;fuga&quot;);
        status = que_search (src, (void **)&amp;str, datacmp);
        if (status) {
                fprintf(stderr, &quot;%s is not found.\n&quot;, src);
        } else {
                puts(str);
        }
        exit(0);
}

int     datacmp(const void *src, const void *dst)
{
        int     status;

        status = strcmp(src, dst);

        return (status);
}
</pre>
<p>データ比較用関数として、datacmp()を作成。見たとおり内部でstrcmp()を呼んでいるだけなので、特に関数を作る必要はない。ただ、これを応用することによって、文字列以外のデータについても検索することができるようになる。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/51/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>キュー&amp;スタック</title>
		<link>http://www.k14a.net/archives/26</link>
		<comments>http://www.k14a.net/archives/26#comments</comments>
		<pubDate>Wed, 25 Mar 2009 12:42:09 +0000</pubDate>
		<dc:creator>moriken</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Program]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[stack]]></category>

		<guid isPermaLink="false">http://www.k14a.net/?p=26</guid>
		<description><![CDATA[

会社でのC言語研修の問題として、定番だけどキュー&#38;スタックを考えた。
キューとスタックはよく似ていて、違うのはデータの取出す順序が先に入れたものから取出す(キュー)のか、後から入れたものから取出す(スタック) [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.k14a.net%252Farchives%252F26%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22%E3%82%AD%E3%83%A5%E3%83%BC%26%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%22%20%7D);"></div>
<p>会社でのC言語研修の問題として、定番だけどキュー&amp;スタックを考えた。<br />
キューとスタックはよく似ていて、違うのはデータの取出す順序が先に入れたものから取出す(キュー)のか、後から入れたものから取出す(スタック)ぐらい。<br />
そこで、キューとスタックをまとめてあつかえるプログラムを作ってみた。きちんとエラー処理はしていないので、もし使うのであれば、その辺はきちんと作る必要がある。</p>
<p>《que.h》</p>
<pre class="brush: c; ">

#ifndef _QUE_H_
#define _QUE_H_

#include        &lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include        &lt;string.h&gt;

#define         GET_QUE         1
#define         GET_STACK       0

/* structuers   */
typedef struct que {
struct  que     *prev;
struct  que     *next;
        void    *data;
} QUE;

/* function prototype   */
int     que_init();
int     que_enque(void *data);
int     que_deque_first(void **data);
int     que_deque_last(void **data);

#endif  /* _QUE_H_      */
</pre>
<p>《que.c》</p>
<pre class="brush: c; ">

#include        &quot;que.h&quot;

static  QUE     root;

static  int     que_deque(void **data, int get_type);

int     que_init()
{
        memset (&amp;root, 0, sizeof(root));
        root.prev = &amp;root;
        root.next = &amp;root;

        return(0);
}

int     que_enque(void *data)
{
        QUE     *p      = NULL;
        QUE     *last   = NULL;

        p = (QUE *) malloc (sizeof(QUE));

        if (root.next == &amp;root || root.prev == &amp;root) {
                root.next = p;
                root.prev = p;
                p-&gt;prev = &amp;root;
        } else {
                last = root.prev;
                last-&gt;next = p;
                root.prev = p;
                p-&gt;prev = last;
        }

        p-&gt;next = &amp;root;
        p-&gt;data = data;

        return(0);
}

int     que_deque_first(void **data)
{
        int     status;

        if (root.next == &amp;root) {
                return(1);
        }

        status = que_deque(data, GET_QUE);

        return(status);
}

int     que_deque_last(void **data)
{
        int     status;

        if (root.prev == &amp;root) {
                return(1);
        }

        status = que_deque(data, GET_STACK);

        return(status);
}

static  int     que_deque(void **data, int get_type)
{
        QUE     *p      = NULL;

        if (get_type) {
                p = root.next;
                p-&gt;next-&gt;prev = p-&gt;prev;
                root.next = p-&gt;next;
        } else {
                p = root.prev;
                p-&gt;prev-&gt;next = p-&gt;next;
                root.prev = p-&gt;prev;
        }

        *data = p-&gt;data;
        free(p);

        return(0);
}
</pre>
<p>que_deque()内で、キューまたはスタックの切替えを行っている。使用する場合は、ラッパーであるque_deque_first()、que_deque_last()でキューまたはスタックを選択する。</p>

]]></content:encoded>
			<wfw:commentRss>http://www.k14a.net/archives/26/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
