• ベストアンサー

C言語での構造体

C言語で、 キュー構造を作りたいのですが、うまくできません。 途中まで作ったのですが、うまく動きませんでした。 EnqueueやDequeueでデータの出し入れをするのですが、そのままではデータを取り出したときにデータが先頭に来ないので、refreshで先頭に持ってくるようにプログラムを組みました。 ----------------------------------------------------- #include<stdio.h> #define MAXQUEUE 10 typedef struct queue{ int head, tail; char entry[MAXQUEUE]; } Queue; //キュー構造にデータを入れる。 void Enqueue(char item,Queue *q){ q->entry[q->tail]=item; q->tail++; } //キュー構造からデータを取り出す。 void Dequeue(char *item,Queue *q){ *item=q->entry[q->head]; q->head++; } //キュー構造内のデータを先頭にずらす。 void refresh(Queue *q){ while(q->head==0){ q->entry[q->head-1]=q->entry[q->head]; q->head--; q->tail--; } } void main(){ Queue qu; Enqueue('w1',&qu); Enqueue('w2',&qu); Enqueue('w3',&qu); Enqueue('w4',&qu); Dequeue(&qu,&qu); Dequeue(&qu,&qu); refresh(&qu); } ---------------------------------------------------------------- mainからEnqueueやDequeueを呼び出すときに、引数として何を渡せばいいのでしょうか?構造体をそのまま渡してみたのですが、「error C2664: 'Dequeue' : 1 番目の引数を 'Queue *' から 'char *' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。」というエラーを吐いてしまいます。 分かりづらい説明で申し訳御座いませんが、ご回答宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

ANo.2 = Interest です。ここじゃあソースコード読みずらかったですね。 ここを読んでもらった方が早いことに気付きました。 http://www.nurs.or.jp/~sug/soft/super/fifo.htm

その他の回答 (2)

  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

参考までに。私が昔作ったFIFO(=Queue)のソースをUpします。 // fifo.h ------------------------------------------------------ /// 定数の定義 #define FIFO_OK 0 // 成功 #define FIFO_ERROR_FATAL -1 // 復旧できない深刻なエラー #define FIFO_ERROR_NULL_POINTERR -2 // 無効なポインタ #define FIFO_ERROR_BUFFSIZE -3 // バッファサイズ不足 #define FIFO_ERROR_EMPTY -4 // データが空 /// データ構造の定義 typedef struct{ int rp; // 書き込み位置 int wp; // 読み出し位置 char *buffer; // データ保存領域へのポインタ short bufferSize; // データ保存領域の大きさ }FIFO; /// プロトタイプ宣言 int FIFO_init(FIFO *buf, short size, char *bufTop); int FIFO_put(FIFO *buf, char c); int FIFO_get(FIFO *buf, char *c); int FIFO_isEmpty(FIFO *buf); int FIFO_clear(FIFO *buf); // fifo.c ----------------------------------------------------- /** FIFOを初期化する。 @param buf FIFOのデータ構造へのポインタ @param[in] size FIFOのバッファサイズ(バイト数) @param[in] bufTop データ保存領域の先頭アドレス @retval FIFO_OK (0) 成功 @retval FIFO_ERROR_FATAL (-1) 復旧できない深刻なエラー @retval FIFO_ERROR_NULL_POINTERR (-2) 無効なポインタ @retval FIFO_ERROR_BUFFSIZE (-3) バッファサイズ不足 */ int FIFO_init(FIFO *buf, short size, char *bufTop) { if( NULL == buf || NULL == bufTop ){ return FIFO_ERROR_NULL_POINTERR; } if( 0 >= size ){ return FIFO_ERROR_BUFFSIZE; } buf->rp = 0; buf->wp = 0; /* if( NULL == buf->buffer ){ // バッファ用メモリをヒープ領域から確保する。 buf->buffer = (char *)malloc( size * sizeof(char) ); if( NULL == buf->buffer ){ // メモリを確保できない場合、深刻なエラーとして処理を抜ける。 return FIFO_ERROR_FATAL; } } */ buf->buffer = bufTop; buf->buffer[0] = '\0'; buf->bufferSize = size; return FIFO_OK; } /** FIFO にデータを一つ入れる。 @param buf FIFOのデータ構造へのポインタ @param[in] c 入れるデータ @retval FIFO_OK (0) 正常終了 @retval FIFO_ERROR_NULL_POINTERR (-2) 無効なポインタ @retval FIFO_ERROR_BUFFSIZE (-3) バッファサイズ不足 @note バッファが満杯になったら古いデータから落としていく。 */ int FIFO_put(FIFO *buf, char c) { int wp, rp, next; if( NULL == buf ){ return FIFO_ERROR_NULL_POINTERR; } if( NULL == buf->buffer ){ return FIFO_ERROR_NULL_POINTERR; } if( 0 == buf->bufferSize ){ return FIFO_ERROR_BUFFSIZE; } wp = buf->wp; next = (wp + 1) % (buf->bufferSize); // バッファが満杯なら読み出し位置を1つ進めて古いデータから落としていく。 if( next == buf->rp ){ rp = buf->rp; buf->rp = (rp + 1) % (buf->bufferSize); } buf->buffer[ wp ] = c; // 次の書き込み位置を更新する。 // 書き込み位置がバッファの末尾まできたら先頭に戻る。 buf->wp = next; return FIFO_OK; } /** FIFOからデータを取り出す。 @param[in] buf FIFOのデータ構造へのポインタ @param[out] c 取り出したデータを格納する領域へのポインタ @retval FIFO_OK (0) 正常終了 @retval FIFO_ERROR_NULL_POINTERR (-2) 無効なポインタ @retval FIFO_ERROR_EMPTY (-4) FIFOが空 */ int FIFO_get(FIFO *buf, char *c) { int rp; if(NULL == buf){ return FIFO_ERROR_NULL_POINTERR; } if(NULL == c){ return FIFO_ERROR_NULL_POINTERR; } rp = buf->rp; if( FIFO_isEmpty(buf) ){ return FIFO_ERROR_EMPTY; } else{ *c = buf->buffer[rp]; // 次の読み込み位置を更新する。 // 読み込み位置がバッファの末尾まできたら先頭に戻る。 buf->rp = (rp + 1) % (buf->bufferSize); return FIFO_OK; } } /** FIFOが空なら 1 を返す。 @param[in] buf FIFOのデータ構造へのポインタ @retval 1 バッファは空 @retval 0 データが入っている */ int FIFO_isEmpty(FIFO *buf) { // rp == wp はバッファが空であることを意味する。 return (buf->rp == buf->wp) ? 1 : 0; } /** FIFOのバッファをクリアする。 @param[in] buf FIFOのデータ構造へのポインタ @retval FIFO_OK (0) 正常終了 @retval FIFO_ERROR_NULL_POINTERR (-2) 無効なポインタ */ int FIFO_clear(FIFO *buf) { if( NULL == buf || NULL == buf->buffer ){ return FIFO_ERROR_NULL_POINTERR; } buf->rp = 0; buf->wp = 0; return FIFO_OK; }

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.1

ざっと見た所感を述べます。 指摘1 初期化してください。 C言語の場合、初期化しないと どんな値が入っているか分かりません。 × Queue qu; /* 不定のまま */ ○ Queue qu = {0}; /* 全部0 */ ○ Queue qu; /* 不定のまま */ memset(&qu, 0, sizeof(qu)); /* 全部0 */ これをすることでrefresh関数もいらなく なるかと。 指摘2 宣言が void Enqueue(char item,Queue *q) なのに、 Enqueue('w1',&qu); というのは変です。 普通 char というと、半角1文字のことをいうので。 Enqueue('a', &qu); という感じになると思います。 指摘3 宣言が void Dequeue(char *item,Queue *q) ということは、第1引数は、 char の変数のアドレスを渡せ、ということです つまりこのように使います char a = 0; Dequeue(&a, &qu); ・・・ 以上、参考になれば。