• ベストアンサー

構造体について

構造体について分からない点があり,教えて頂きたく投稿いたします. 現在,以下のような構造体を作成しています. typedef struct{ int data; struct node *NEXT; }node; また,それを管理するためのリストを以下の構造体にて宣言しました. typedef struct{ node *crnt; node *last; }node_list; また,使用する関数内での宣言は以下の通りです. node_list *non_dscvr_node_list; //未探査ノードを格納する node *crt_dscvr_node; //現在探査中のノードを示す node *start; そして, start->data = 10; start->NEXT = NULL; non_dscvr_node_list->crnt = start; non_dscvr_node_list->last = start; : : crt_dscvr_node = non_dscvr_node_list->crnt; non_dscvr_node_list->crnt = crt_dscvr_node->NEXT; //ここでエラーがでる. エラーの詳細は以下の通りです. warning: assignment from incompatible pointer type 私としては,リストに格納されている先頭ノードをポップして,次のノードを先頭にしたつもりだったのですが,ポインタタイプに互換性がないと怒られてしまいました. 少し調べては見ましたが,nodeの構造体を管理するために別に構造体を定義しているページがあまり見あたりません. 従って,そのようなページがあれば教えて頂きたいと思います. このような方法はあまりよくないのでしょうか. 併せて教えていただけますようお願いいたします.

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

  • ベストアンサー
回答No.3

typedef struct node{ // 追記:構造体タグ   int data;   struct node *NEXT; // ※ } node; typedef struct node_list{ // 追記:構造体タグ   node *crnt;   node *last; } node_list; とする事で解決すると思います。 もともとNEXTは、構造体タグ名が存在しないものとしてのポインタとして定義されています。 (※ struct nodeは名前を付けては定義されていない) 従って、void*で定義されていると思います。 実験してみたのですが、   non_dscvr_node_list->crnt = (node*)crt_dscvr_node->NEXT;// キャストで型の整合性を取る とするとポインタ互換性のエラーは取れます。 しかし、この対処では局所対処で意味がないので、 NEXTが指す構造体を定義するために、構造体タグ名を追記しました。

hydrangeas0722
質問者

お礼

ありがとうございます. 無事解決に至りました. 構造体の使い方を間違っていたようです. typedef struct a{  : }b; とすると, struct a = b として使用できるようになるのですね. 構造体タグを定義しないとvoid型として定義されてしまうというのは初めて知りました. まだまだ精進いたします. わざわざテストまでして頂き,ありがとうございました.

その他の回答 (2)

回答No.2

typedef struct node_t {   int data;   struct node_t *NEXT; } node; …とやったらどうなります?

hydrangeas0722
質問者

お礼

ありがとうございます. 無事解決に至りました.

  • crew21
  • ベストアンサー率26% (58/222)
回答No.1

typedef で モロに node てのを定義するのはだいじょぶかな。 コンパイラのヘッダで node てのがもしあるとそういうワーニング出るかもです。 無難に node じゃなくて、mytestnode とかにしてもダメでしょうか。 ※すいません。長くて全部読んでないです。パッと見で思いついたこと書きました。

hydrangeas0722
質問者

お礼

回答ありがとうございました. 無事解決に至りました. 長くて申し訳ありません. これからはもう少しコンパクトに説明できるように致します.

関連するQ&A

  • List構造

    Listの尻にノードを追加する関数で困っています。 以下に、ソースの一部を掲載させていただきます。 typedef struct __node{ int data; struct __node *next; }Node; ... /*リストの尻にノードを追加する関数 * 引数: head. リストの先頭ノードのポインタ data. リストの尻に追加したいint型の変数*/ void Insert_Tail(Node *head, int data) { Node *ptr = head; if(ptr == NULL){ /*<ノードが存在しない時には追加されない>*/ /*領域の確保*/      head = (Node*)calloc(1,sizeof(Node)); /*データをセット*/ head->data = data; head->next = NULL; return ; }else{ /*<ノードが存在するときには正常に動作>*/ while(ptr->next != NULL){ ptr = ptr->next; } /*領域の確保*/ ptr->next = (Node*)calloc(1,sizeof(Node));      /*データのセット*/ ptr->next->data = data; ptr->next->next = NULL; } } コメントアウトにも書かせていただきましたが、ノードがすでに存在するときには、正常にノードの最後に追加してくれるのですが、ノードが存在しない時にはリストに追加してくれません。 どうかご指導、ご指摘の程お願いします。

  • C言語の構造体についてなんですが。

    struct LIST {     struct Num* number;     struct LIST* next;/* 次の要素へのポインタ */ }*root; struct Num{     int a;     struct Num* next; /* 次の要素へのポインタ */ }*numroot; と構造体を定義したときに、 main(){     struct LIST *p;     for(p = root; p != NULL; p = p->next) ; } とすれば、pの先頭からNULLまでを参照していくことは分かるんですが、pのnumberの先頭からNULLまでの参照方法(プログラムのfor文の記述方法)がイマイチわかりません。つまり、構造体の構造体をどのように参照するかということです。 これを実現したい理由は、構造体内での数の格納を配列(固定長)ではなく可変長で格納したいからです。 分かる方は解答をお願いします。

  • ポインタ版リスト構造によるスタックの実装

    C言語を用いてアルゴリズムの勉強をしています。 現在、ポインタ版リスト構造によるスタックを実装し、入力された文字列の中で括弧の整合性を判定するプログラムを作成しているのですが、難航しています。 プログラムの内容は、以下の通りです。 入力:a{z[e(b){j}(p)]w}(j) 結果:整合 入力:a{z[e(b){j}(p)}w](j) 結果:不整合 ですが、所持している参考書の例題プログラムには、スタックに入れる要素が整数値のものしかなく、文字をスタックに入れるところからわかりません。 また、先輩に尋ねたところ、以下のような構造体を使うと良いとアドバイスされました。 typedef struct { int max; int num; List stk; } Stack; typedef struct { Node *head; Node *crnt; } List; typedef struct node { char data; struct node *next; } Node; 先輩には申し訳ないのですが、余計にわからなくなってしまいました。 この構造体を用いてプログラムをかける方、ご指導のほどよろしくお願いします。

  • 構造体とポインタ配列

    現在C言語の勉強をしております。 環境はwindowsXP、コンパイラはVC6.0です。 構造体と、ポインタの配列についてなのですが、 以下のような構造体が宣言されている時に、リスト構造にデータがいくつか入っているとします。 // 構造体 typedef struct address { unsigned char names[NAME_SIZE+1]; /* 名前 */ char tels[TEL_SIZE + 1]; /* 電話番号 */ struct address *prev; /* 前へのポインタ */ struct address *next; /* 次へのポインタ */ }Address, *a_pt; そのリスト構造を先頭要素か順番にポインタ配列に格納するには以下の方法ではおかしいでしょうか? /* ポインタ配列を用意する */ Address *array[MAX_COUNT]; /* top_ptは先頭のポインタです */ pt = top_pt; /* データがなくなるまで配列へ格納する */ while(pt != NULL){ array[count++] = pt; pt = pt->next; } /* 配列の最後はNULLとする */ array[count] = NULL; また、配列の中身を確認する方法としては、 printf("配列の中身:%s\n", array[0]->names); では、アドレスが表示されてしまうのかな・・と思ったら、accessViolationで落ちてしまいました・・・。 中身はどうしたらデバッグ出来ますでしょうか? そもそも、以下の2つは何か違いはありますか? Address *ptA[100]; a_pt ptB[100]; 皆さん、どうかよろしくお願いいたします。 理解不能な場合はご指摘ください。

  • 線形リストのコードでどーしても理解できない個所があります。

    線形リストのコードでどーしても理解できない個所があります。 (以下、コード部分) typedef struct __node { char name[20]; char tel[16]; struct __node *next; } Node; typedef struct { Node *head; Node *tail; } List; Node *AllocNode(void) { return ((Node *)calloc(1, sizeof(Node))); } /*--- 新たに生成したノードを先頭へ挿入 ---*/ void InsertNode(List *list, const char *name, const char *tel) { Node *ptr = list->head; list->head = AllocNode(); strcpy(list->head->name, name); strcpy(list->haed->tel, tel); list->head->next = ptr; } /*--- pが指すノードの直前にノードを挿入 ---*/ void PutNodeP(List *list, Node *p, const char *name, const char *tel) { if (p == list->head) InsertNode(list, name, tel); else { Node *temp = AllocNode(); if (p == list->tail) list->tail = temp; else *temp = *p; strcpy(p->name, name); strcpy(p->tel, tel); temp->next = p; } } 上の29行目以降の≪pが指すノードの直前にノードを挿入≫についてです。 if文部分については理解できますが、else文部分について、何をやっているのかわからないです。Cの基本的な部分(ポインタも含めて)については充分に理解しているつもりです。 どなたか御教授頂けないでしょうか。 長々と書いてしまいましたがよろしくお願いします。

  • 構造体のリストをソートしたい。

    ある名簿のリストを作りました。 以下のような構造体で、 typedef struct meibo{ char name[10]; int old; struct meibo *next; }MEIBO; これを、ポインタp->next->nameをたどっていって、名前が辞書順になるようにリストを作ったのですが、 これを年齢順にソートして表示させたいんです。 どんな方法があるんでしょうか? 一旦すべてを配列に格納して、クイックソート…とかも考えたのですが、すごく領域をとるし、なんか2度手間(最初から配列に順に格納していけばよかったなぁ・・・と。 それでもやっぱり最初から名列順にするときから配列に入れておくほうがいいのでしょうか? 教えてください。 (最初から年齢を比較してリストを作れば・・ってのはなしで、名列順のリストが存在するものとしてください。)

  • 構造体へのポインタの動的確保について

    構造体へのポインタを動的確保しようとmalloc関数を使用すると segmentation faultが起きます。 typedef struct cell{ char *word; int count; struct cell *next; }node_t; という構造体で node_t *ptr=(node_t*)malloc(sizeof(node_t)*num); という風に動的確保しようとするとsegmentation faultが起きました。 gdbを使って調べると Starting program: /home/programII/week05/a.out file1 file2 Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 というメッセージが返ってきます。 これはライブラリとのリンクが正しく行われていないということでしょうか? しかし、ポインタの動的確保以外でmalloc関数を使用すると 正常に動作するのでライブラリ自体が無いわけではないようです。 ptr[2]といった風にポインタを参照したいのですが上手くいきません。 よろしくお願いします。

  • リスト

    プログラムのデータ構造の勉強を進めてるのですが リストのところである問題がどうしてもリスト(ポインタ)で解けません 基礎的なことがわかるのですが(ノードの使い方などマロックなど) その問題は人の名前を入力し国語、数学、英語の点数を入力して3教科の点数を合計し名前、それぞれの点数、合計の表示、そしてまた入力を続けると指示した場合また名前3教科の点数をいれてと繰り返すのですが、繰り返したときに今まで入っているデータの人々の合計を比較して表示を昇順にしなくちゃなりません。どうすればいいか検討もつきません。 typedef struct _node { char name[10]; int Jap; int math; int eng; struct _node *next; } Node; で構造体はいいのでしょうか? できればくわしくプログラムを教えてください。 お願いします。

  • 構造体について

    以下のような構造体の宣言が合ったとき struct list { int a; char b[20]; struct list *next; }; struct list *add_list( int a, char *str, struct list *head );・・・1 struct list *del_list( int a, struct list *head );・・・2 1は引数の数が同じため問題ないのですが、2はどういう意味になるのでしょう?

  • データ構造について構造体を使ったテクニックについての質問(ほぼ初心者)

    大学の研究で困っています。 数値計算をC(C++)でやろうとしています。 枝が一本あって、その枝はノードのリストで作られています。その一つ一つのノードからまた新しい枝が作られています。新しい枝がない場合、float(精度を考えるとdoubleにしたい)型の情報を一つ持ちます。 全部で1億個くらいのノードをもつ予定です。(発展系はその二乗三乗と増えていきます。)そこでメモリを効率的に使うプログラミングを考えているのです。 struct leaf{ int init; struct node top; } struct node{ struct node *next; union pnt { float *value; struct leaf *sub; } p; } この文法で動くのかまた他の方法があるかを聞きたくて書き込みしました。よろしくお願いします。(VC++、Win、2GHz)