ページ 11

キュー数をカウントするテストプログラム

Posted: 2011年4月24日(日) 22:01
by ロボコン
初めまして。社会人2年目のプログラマーです。
C言語で事前にキュー数をカウントするプログラムが与えられていて、
そのプログラムが正しく動作するか自分でキューを作成して、
正しい結果が得られる事を確認するテストプログラムを
作成するような研修課題があります。

ここで、
キュー数をカウントする関数:unsigned int q_get_cnt( ST_QLIST *)
先頭キューを得る関数 :ST_QNODE* q_get_first( ST_QLIST *)
次キューを得る関数 :ST_QNODE* q_get_next( ST_QNODE *)
です。

自分でmain関数を作って、その中で自分でキューを3つ作って、
q_get_cnt( ST_QLIST *)の戻り値が3と出力されるようなプログラムを
作りたいわけですが、そもそも自分でキューを3つ作る方法が
わからないのです。
上記3つのキュー関数の仕組みは理解しています。(たぶん・・・)
誰か、このmain関数の中身を教えて頂きたく。。

コード:

#include <stdio.h>

/* キューノード構造体 */
struct qnode
    struct qnode *next;   /* 次ノードへのアドレス */
    struct qnode *prev;   /* 前ノードへのアドレス */
};
typedef struct  qnode  ST_QNODE;

/* キューリスト構造体 */
struct qlist
    struct qnode *head;   /* 先頭キューノード */
    struct qnode *tail;     /* 末尾キューノード */
};
typedef struct  qlist  ST_QLIST;

/* プロトタイプ宣言 */
ST_QNODE* q_get_first( ST_QLIST *)
ST_QNODE* q_get_next( ST_QNODE *)
unsigned int q_get_cnt( ST_QLIST *)

ST_QNODE* q_get_first( ST_QLIST *list)
{
      return(list->head);
}

ST_QNODE* q_get_next( ST_QNODE *node)
{
      return(node->next);
}

unsigned int q_get_cnt( ST_QLIST *list)
{
      ST_QNODE *node;
      unsigned int cnt = 0;

      node = q_get_first(list);

      while(node != NULL){
           cnt ++;
           node = q_get_next(node);
      }

      return cnt;
}

int main(void)
{
      unsigned int ret;

      /* ここで自分でキューを3つ作成する方法がわからない */

      ret = q_get_cnt(list);         /* ret=3 となればよい*/
      printf("キュー数は%dです。",ret);
      return 0;
}


Re: キュー数をカウントするテストプログラム

Posted: 2011年4月24日(日) 22:38
by box
ちょっと確認なんですけど、載せられたコードのうち、
事前に与えられたのはどの部分ですか?

構造体定義やプロトタイプ宣言で文法エラーがあって、
コンパイルが通らないのでお聞きしてるんですけれども。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月24日(日) 22:53
by ロボコン
与えられたコードはmain以外の関数です。
コンパイルエラーの件、大変失礼しました。
以下に修正版を送ります。
※main関数は作りかけ途中なので、ここでのコンパイルエラーは
ご容赦下さい。

コード:

#include <stdio.h>
 
/* キューノード構造体 */
struct qnode{
    struct qnode *next;   /* 次ノードへのアドレス */
    struct qnode *prev;   /* 前ノードへのアドレス */
};
typedef struct  qnode  ST_QNODE;
 
/* キューリスト構造体 */
struct qlist{
    struct qnode *head;   /* 先頭キューノード */
    struct qnode *tail;     /* 末尾キューノード */
};
typedef struct  qlist  ST_QLIST;
 
/* プロトタイプ宣言 */
ST_QNODE* q_get_first( ST_QLIST *);
ST_QNODE* q_get_next( ST_QNODE *);
unsigned int q_get_cnt( ST_QLIST *);
 
ST_QNODE* q_get_first( ST_QLIST *list)
{
      return(list->head);
}
 
ST_QNODE* q_get_next( ST_QNODE *node)
{
      return(node->next);
}
 
unsigned int q_get_cnt( ST_QLIST *list)
{
      ST_QNODE *node;
      unsigned int cnt = 0;
 
      node = q_get_first(list);
 
      while(node != NULL){
           cnt ++;
           node = q_get_next(node);
      }
 
      return cnt;
}
 
int main(void)
{
      unsigned int ret;
 
      /* ここで自分でキューを3つ作成する方法がわからない */
 
      ret = q_get_cnt(list);         /* ret=3 となればよい*/
      printf("キュー数は%dです。",ret);
      return 0;
}


Re: キュー数をカウントするテストプログラム

Posted: 2011年4月24日(日) 22:55
by たかぎ
ロボコン さんが書きました:与えられたコードはmain以外の関数です。
要は、実質的な丸投げということですね。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月24日(日) 23:00
by ロボコン
そうですね・・・。
丸投げみたいで申し訳ないです・・・。
自己参照構造体は見慣れない事もあってか、
どうやってキューをプログラムで作るのかが
わからないのです。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 09:15
by non
ノード構造体にデータを格納するメンバーがないのは、どうしてなんだろう。

さて、ノードの追加方法ですが、「リスト構造」で検索すれば、ヒントになるページはいっぱいあると思いますので、自分でまずは調べてみてください。それでもわからないなら、再度ご質問ください。冷たいようですが、研修課題と言うことですので。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 09:19
by たかぎ
non さんが書きました:ノード構造体にデータを格納するメンバーがないのは、どうしてなんだろう。
この設計で正解です。

コード:

struct my_node
{
  ST_QNODE qnode;
  Type value;
};
のようにすれば、どんな型のデータにでも対応できますから。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 12:26
by non
たかぎ さんが書きました:この設計で正解です。
なんか、面倒のような気がしますけど。
普通に、データのメンバーを作った方がシンプルだと思うのですが、プロがおっしゃるのならそうなのでしょうね。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 12:56
by たかぎ
non さんが書きました:なんか、面倒のような気がしますけど。
データの型や個数が変わるたびに、新しい構造体とその操作関数一式を定義しなおすほうがずっと面倒です。
テンプレートが使えないCでは、この方法がもっともシンプルで便利で楽です。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 13:43
by non
たかぎ さんが書きました:データの型や個数が変わるたびに、新しい構造体とその操作関数一式を定義しなおすほうがずっと面倒です。
オブジェクト指向が私にはまったく身についてませんからね。リユースなんて考え方は、さらさらない。(笑)
脳みそを一新しなくては、いけませんね。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 14:25
by たかぎ
non さんが書きました:オブジェクト指向が私にはまったく身についてませんからね。
オブジェクト指向は関係ありませんね。
ちなみに、nodeへのポインタを頼りにvalueにアクセスするには、次のようなマクロを定義すればOKです。

コード:

#define q_get_value(node, struct_type)  (((struct_type*)((char*)(node) - offsetof(struct_type, node)))->value) 
/* 一部バグ修正しました */

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 14:39
by non
なるほど。やっと、意味がわかりました。これなら、そんなに面倒なことではないですね。こんな、考え方はとても思いつきません。ためになりました。

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 19:52
by うしお
>>たかぎさん
#define get_value(node, struct_type) (((struct_type*)((char*)(node) - offsetof(struct_type, node)))->Value)
この右側から1番目のnodeは「マクロ引数のノード」ではなく「メンバのノード名」を入れるのが正しくありませんか?
勘違いでしたらすみません
※文章の表現を修正しました

Re: キュー数をカウントするテストプログラム

Posted: 2011年4月25日(月) 20:09
by たかぎ
うしお さんが書きました:#define get_value(node, struct_type) (((struct_type*)((char*)(node) - offsetof(struct_type, node)))->Value)
この右側から1番目のnodeは「マクロ引数のノード」ではなく「メンバのノード名」を入れるのが正しくありませんか?
勘違いでしたらすみません
適当に書いたので間違っていますね。
マクロ引数とメンバ名が同じなことがそもそもの問題です。