• ベストアンサー

C言語(BCB)で双方向リストを操作する方法

Borland C++ Builder5 でプログラミングしています。 親Formで、ファイルを読み、双方向線形リストを作っています。 子Form(ダイアログ)で、この線形リストにノードを追加したいのですが、うまくコンパイル出来ません。 どなた様か、ご指導お願いします。 まず、構造体として次のように定義しています。(Form1のヘッダーファイル) typedef struct _UkeM{ char id[7]; // 途中略 struct _UkeM *beforP; struct _UkeM *nextP; } UkeM; UkeM *UkeTop, *UkeNow, *UkeEnd; 当然これらの定義は、子Formでも操作したいので、public: として定義されています。 親Formで領域を確保するには、 UkeNow = new UkeM; と実行し、最尾ノードのnextPなどにアドレスを格納しています。 この親Formでの処理はコンパイルも通り正しく実行されています。 さて、子Formで、このリストにノードを作ってつなげたい、と思っています。 子Formでは、単純に Form1->UkeNow = new Form1->_UkeM; とやってみたのですが、「型名が必要」というエラーで通りません。 どうも、newの右側が良くないようです。 子Formで、このリストを参照するだけなら全く問題なく操作できています。 (例えば、Label1->Caption = Form1->UkeNow->id;) newだけがうまく出来ません。 子Formでのnewのやり方についてご指導をお願いします。

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

> ところで、ついでに「突っ込みどころ満載」の部分をご指導いただけないでしょうか? > せっかくなので、ぜひ! std::listを使うべきだということと、予約済み識別子に関しては既に別の方が指摘されています。 std::listに関しては、もしC言語と兼用するのであれば使えない事情も分からなくはありませんが、Formのクラス有効範囲ではそれもなさそうです。 C++限定であれば、UkeMがなぜtypedef名なのかも謎です。 他に、もっと根本的なこととして、 > Form1->UkeNow = new Form1->_UkeM; コンパイルエラーはともかく、なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。

Han1344
質問者

お礼

なるほど。 先のepistemeさんといい、レベルが高くてすごいですね。 >std::listを使うべきだということ C言語の延長で使っているので、この使い方は知りませんでした。 双方向リストは良く使うので、この部分を勉強したいと思います。 何か良い参考書(あるいはサイト)でもあればご紹介下さい。 >C++限定であれば、UkeMがなぜtypedef名なのかも謎です。 このソースをBCB以外で使うことはありませんので、C++限定です。 が、私のレベルでは、なぜ謎なのかも分かりません。 何か名前を付けなくてはいけないので分かり易い名前を付けた、ということなのですが・・・。 >なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。 ある処理を行っている途中で、少量のマスターメンテナンスを行う必要があるのですが、その画面をダイアログで表示したため、子Formで線形リストに更新かけた、という理由です。 このようは単純な発想しかありません。 達人の皆さんはどの様にやるのでしょうか?

その他の回答 (5)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

> >std::listを使うべきだということ > C言語の延長で使っているので、この使い方は知りませんでした。 > 双方向リストは良く使うので、この部分を勉強したいと思います。 > 何か良い参考書(あるいはサイト)でもあればご紹介下さい。 一番わかりやすいのは、「C++標準ライブラリ チュートリアル&リファレンス」です。 > >なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。 > ある処理を行っている途中で、少量のマスターメンテナンスを行う必要があるのですが、その画面をダイアログで表示したため、子Formで線形リストに更新かけた、という理由です。 > このようは単純な発想しかありません。 UkeM型をFormのクラス有効範囲で定義すべきかどうかはわかりませんが、少なくとも線形リストの操作のような低レベルの処理は、Formクラスの内部(具体的にはメンバ関数や随伴関数等)で行うべきです。 そうでなければ、UkeM関連はFormクラスからは切り離すべきです。

Han1344
質問者

お礼

ありがとうございました。 >一番わかりやすいのは、「C++標準ライブラリ チュートリアル&リファレンス」です。 やっぱりこれなんですね? 我々シロートは、これを読むのがむずかしい・・・。 でもがんばってみます。 >UkeM型をFormのクラス有効範囲で定義すべきかどうかはわかりませんが、少なくとも線形リストの操作のような低レベルの処理は、Formクラスの内部(具体的にはメンバ関数や随伴関数等)で行うべきです。 そうでなければ、UkeM関連はFormクラスからは切り離すべきです。 うーん、このレベルの話になると、やはり理解できません。 もう少し勉強しながら理解に努めます。 とりあえず、当面の問題は解決したので、これで完了とします。 std::listについては、今、サンプルプログラムを作って確認をし始めたところです。 単なるリストを作ることは出来ましたが、もう少し複雑なことについてはうまく出来ていません。 あらためて質問をアップします。 その時は、またご指導下さい。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

typedef のところだけ: C++ だと, 他の識別子と衝突しない限り struct/union/class のタグも型名として認識してくれます. だから, struct UkeM { // なんか }; としておくだけで UkeM foo; とできます.

Han1344
質問者

お礼

ありがとうございました。 なるほど、出来ますね。 数行のテストプログラムを作って確認してみました。 以後、このようにいたします。

回答No.3

>「突っ込みどころ満載」の部分をご指導いただけないでしょうか? 僕なら"双方向線形リストを作って"いるのに突っ込む。 わざわざ作らなくても std::list<string> 使えばいい。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

突っ込みどころ満載ですが、それはさておき、 new Form1::UkeM; でよいのでは?

Han1344
質問者

お礼

ありがとうございました。 お蔭様で役に立ちました。 ところで、ついでに「突っ込みどころ満載」の部分をご指導いただけないでしょうか? せっかくなので、ぜひ!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「_ で始まる識別子は使っちゃダメ」といいつつ, Form1 の型は知らないけど new で指定するのは型名だから new なんか::_UkeM の形になるはず.

関連するQ&A

  • [C言語]単連結リストにおける着目ノードの操作

    http://www.bohyoh.com/Books/CalgoA/EX/ALGOEX0901.html 上の線形リストのプログラムにおいて、着目ノードを1個次にずらす操作と、1個前にずらす操作を追加したいのですが、単連結リストでは後者の実現は少しばかりややこしく、困っています。 おそらく先頭ノードから後続ノードへのポインタを辿って行って、着目ノードを探索すれば良いのでしょうが……。 尚、前者において着目ノードが末尾ノードだった場合、後者において着目ノードが先頭ノードだった場合は考えないものとします。 皆様にご教授頂けると幸いです。 /* 着目ノードを一個次のノードにする */ void NextCrnt(List *list) { if (list->crnt == NULL){ puts("着目要素はありません。"); } else { list->crnt = list->crnt->next; } }

  • 線形リスト(C言語)

    線形リストでn番目のIDを表示するプログラムを作っていますが、なぜか実行すると強制終了してしまいます。 コンパイルエラーは起きていないので、原因がさっぱりわかりません。 どなたかご教授お願いします。 #include <stdio.h> #include <stdlib.h> struct list{ int ID; struct list *next; }; int main(void) { struct list *top, *a; int i, n, x; a = NULL; for(i = 1; i < 11; i++) { printf("%d番目のIDを入力: " ,i); scanf("%d" ,&x); top = (struct list *)malloc(sizeof(struct list)); top->ID = x; top->next = a; a = top; } printf("何番目のIDを表示しますか: "); scanf("%d" ,&n); for(i = 1; i < 11; i--) { if(i == n) printf("%d" ,top->ID); top = top->next; } free((top->next->next->next->next->next->next->next->next)->next); free((top->next->next->next->next->next->next->next)->next); free((top->next->next->next->next->next->next)->next); free((top->next->next->next->next->next)->next); free((top->next->next->next->next)->next); free((top->next->next->next)->next); free((top->next->next)->next); free((top->next)->next); free(top->next); free(top); return 0; }

  • 双方向リストの関数

    双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{  struct sList *prev; /* 前のノードのアドレス */  char name[NAME_LENGTH]; /* 名前 */  char grade; /* 成績 */  struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct {  sNode *firstNode; /* リストの先頭ノードのアドレス */  sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /*  双方向リストの末尾にノードを追加する関数 insertLast()  引数   manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス   sNode *node 末尾に追加したいノードのアドレス  返値   なし */ void insertLast(manageList *list, sNode *node ) {  /*** リストの末尾にノードを追加する ***/  return; } /*  双方向リストの新しいノードを作成する関数 makeNewNode()  引数   char *aName 名前(文字列)の先頭アドレス   char aGrade 成績  返値   sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) {  sNode *pNewData;  /* sNode 型のメモリ領域を確保 */  pNewData = (sNode *) malloc( sizeof(sNode) );  /* 名前と成績のデータを設定する */  strcpy( pNewData->name, aName );  pNewData->grade = aGrade;  pNewData->prev = NULL;  pNewData->next = NULL;  return( pNewData ); } /*  main()  引数   なし  返値   int 正常終了の時 0     異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) {  manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */  sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */  sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */  FILE *fp; /* データファイルのファイルポインタ */  char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */  char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */  /* 初期状態では先頭・末尾ノードともNULL */  list.firstNode = NULL;  list.lastNode = NULL;  /* データファイル exer6.txt を読み込み用に開く.    ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/  fp = fopen("exer6.txt","r");  if(NULL == firstNode){   printf( "ファイルが開けませんでした. \n" );   return( -1 );  }  /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */  while( EOF != fscanf( fp, "%s %c", name, &grade ) ) {   /* 新しいノードを作成 */   pNew = makeNewNode( name, grade );   /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/   pNow->next = pNew ;   pNew->prev = pNow ;   pNow = pNew ;  /* ファイルを閉じる */  fclose( fp );  /* 現在見ているノードを末尾ノードにセットする */  pNow = lastNode  /* 末尾のノードから前のノードへたどりながらデータを出力する */  while( NULL != pNow ) {   /* 出力 */   printf( "%s %c\n", pNow->name, pNow->grade );   /* 現在見ているノードを一つ前のノードにする */   pNow = pNow->prev;  }  return( 0 ); }

  • C言語 線形探索

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXBUFFERSIZE 256 struct LinkedListNode{ int data; struct LinkedListNode *next; }; struct LinkedList{ int node_num; struct LinkedListNode *head; }; LinkedList *LinkedListMake(char *filename) { FILE *fp; LinkedList *list; char buffer[MAXBUFFERSIZE]; /* ファイル有無のチェック */ if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "No Such File : %s\n", filename); exit (1); } list = LinkedListAlloc(); if (list == NULL) { /* 領域確保失敗 */ exit (0); /* 終了 */ } while (fgets(buffer, MAXBUFFERSIZE, fp)) { /* ファイル終端に到達するまでループ */ buffer[strlen(buffer) - 1] = '\0'; /* 改行文字を削除 */ LinkedListDataAdd(list, atoi(buffer)); } fclose(fp); return (list); } LinkedList *LinkedListAlloc(void) { LinkedList *list; list = (LinkedList *)malloc(sizeof(LinkedList)); if (list == NULL) { /* 領域確保失敗 */ return (NULL); } list->node_num = 0; list->head = NULL; return (list); } LinkedListNode *LinkedListDataAdd(LinkedList *list, int x) { LinkedListNode *ptr; /* 注目するノードへのポインタ */ LinkedListNode *prev; LinkedListNode *new_node; ptr = list->head; prev = NULL; while (ptr) { /* 終端ノードに到達するまでループ */ if (ptr->data < x) { prev = ptr; /* 直前ノードの更新 */ ptr = ptr->next; /* 注目ノードの更新 */ } else if (ptr->data == x) { /* x は登録済み */ return (NULL); } else { /* x を注目ノードの直前に追加 */ new_node = LinkedListNodeAlloc(); if (new_node == NULL) { /* 領域確保失敗 */ exit (0); /* 終了 */ } new_node->data = x; new_node->next = ptr; /* ポインタの付け替え(注目ノードの直前) */ if (prev != NULL) { /* 連結リストの先頭以降に追加 */ prev->next = new_node; /* ポインタの付け替え */ } else { /* 連結リストの先頭に追加 */ list->head = new_node; } list->node_num++; /* ノード総数の更新 */ return (new_node); } } /* 終端ノードに到達 */ /* x を終端に追加 */ new_node = LinkedListNodeAlloc(); if (new_node == NULL) { /* 領域確保失敗 */ exit (0); /* 終了 */ } new_node->data = x; new_node->next = NULL; /* new_node は新たな終端ノード */ if (prev != NULL) { /* list は少なくともひとつのノードを有している */ prev->next = new_node; /* 更新前の終端ノードの直後が new_node となる */ } else { /* list は空(ノードがひとつも含まれない) */ list->head = new_node; } list->node_num++; /* ノード総数の更新 */ return (new_node); } LinkedList *LinkedListSearch(LinkedList *list, int x)←ここがわかりません★ { for(i = 0; i < node_num)      ??? int main(int argc, char *argv[]) { int a, i, x; printf("xの値を入力"); scanf("%d", &x); LinkedListMake(argv[1]); LinkedListSearch(list, x); 連結リストに格納されたint型データから目的の値を線形探索するプログラムをつくってます。 連結リスト作成関数まではできたので、あと連結リストにおいて目的の値を線形探索する関数LinkedListSearchをつくればだいたい完成だと思うのですが、関数LinkedListSearchの作り方がわかりません。 引数で連結リストのポインタと目的値をとって、目的値が存在すればそのノードのポインタ、存在しない場合はNULLを返すようにするつもりです。 わかる方、是非とも教えてください! お願いいたします。

  • C言語のプログラムを書いたのですが上手く動きません

    C言語の練習問題をプログラミングしたのですが、上手く動きません。 コンパイルはできるのですが、実行すると「Segmentation fault(core dumped)」となります。 問題は、コマンドライン引数としてファイル名を指定したテキストファイルから読み込んだデータを,双方向リストに格納し,順番に表示するというものです。 テキストファイルは 10T5001 C 10T5002 A 10T5003 B 10T5004 C 10T5005 D 10T5006 B 10T5007 A 10T5008 D このように、IDとランクをランクABCDをスペースで区切ったもので、これをランクAから順番に表示させます。 上手く動けば ID: 10T5002, grade: A, ID: 10T5007, grade: A ID: 10T5003, grade: B ID: 10T5006, grade: B ID: 10T5001, grade: C ID: 10T5004, grade: C ID: 10T5005, grade: D ID: 10T5008, grade: D と表示されるはずなんですが・・・ これが僕の書いたプログラムです(長いです。ごめんなさい) #include <stdio.h> #include <stdlib.h> #include <string.h> #define ID_LENGTH 8 /* IDの長さ+ナル文字 */ #define EFOPEN -1 #define ENOMEM -2 #define EINVAL -3 /* 双方向リストのノード */ typedef struct sList /* タグ */ { char id[ID_LENGTH]; /* ID */ char grade; /* ランク*/ struct sList *prev; /* 前のノードのアドレス */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* 双方向リストのノードを作成する関数 makeNewNode() 作成したノードのprevとnextはNULLにする 引数 ・ノードに格納するID ・ノードに格納するランク(A/B/C/D) 戻値 作成したノードの先頭アドレス.メモリの確保に失敗した場合はNULL */ sNode *makeNewNode(char *id, char grade) { sNode *pNewNode; pNewNode = (sNode*)malloc(sizeof(sNode)); if(pNewNode != NULL) { strncpy(pNewNode->id, id, ID_LENGTH-1); pNewNode->grade = grade; pNewNode->prev = NULL; pNewNode->next = NULL; } return pNewNode; } /* 引数で渡された任意のノードの後ろに新しいノードを追加する関数 insertNext() 引数 ・後ろにノードを追加したいノードの先頭アドレス ・追加するノードの先頭アドレス 戻値 なし */ void insertNext(sNode *node, sNode *newNode) { if(node->next == NULL) //一番後ろに追加する場合 { node->next = newNode; newNode->prev = node; } else //まん中に挿入する場合 { newNode->prev = node; newNode->next = node->next; node->next->prev = newNode; node->next = newNode; } } /* main() 引数 int argc コマンドライン引数の数 char *argv[] 与えられたコマンドライン引数の文字列の先頭アドレスの配列 戻値 int 正常終了の時 0 以下の場合は異常終了し,括弧内の値を返す データファイルが開けなかった場合(EFOPEN) makeNewNode()でメモリが確保できなかった場合(ENOMEM) 引数の数が正しくない場合(EINVAL) */ int main(int argc, char *argv[]) { sNode *top; /* リストの先頭ノードのアドレスを保持する変数*/ sNode *new; /* 新しく作成したノードのアドレスを保持する変数 */ sNode *now; /* 現在見ているノードのアドレスを保持する変数 */ FILE *fp; /* データファイルのファイルポインタ */ char id[ID_LENGTH]; /* ファイルから読み込んだIDを一時的に保持する変数 */ char grade; /* ファイルから読み込んだランクを一時的に保持する変数 */ /* コマンドライン引数の数をチェックする 数に過不足があれば,使い方を表示し,異常終了する */ if(argc != 2){ printf("Usage: %s datafilename.\n", argv[0]); return EINVAL; } /* データファイルを読み込み用に開く ファイルが開けなかった場合,エラーメッセージを表示し異常終了する */ fp = fopen(argv[1], "r"); if(NULL == fp){ printf("No such file %s.\n", argv[1]); return EFOPEN; } /* リストの先頭に番兵を立てる */ new = makeNewNode("Banpei", 'A'-1); if (new == NULL){ printf("Error: cannot allocate memory\n"); return ENOMEM; } top = new; /* データファイルから1行ずつデータを読み込み,ランク順にリストに追加していく 既にリストの先頭には番兵ノードがある点に注意 */ while(EOF != fscanf(fp, "%s %c", id, &grade)){ new = makeNewNode(id, grade); if(new == NULL){ printf("Cannot allocate memory.\n"); return EFOPEN; } if(top->next == NULL){ //リストが空の場合 insertNext(top, new); } else{ now = top; while(new->grade > now->grade){ now = now->next; } insertNext(now, new); } } /* できあがったリストの内容を先頭から順に表示する ただし,番兵ノードは表示しない */ now = top; while(now != NULL){ printf("ID: %s, grade: %c\n",now->id, now->grade,); now = now->next; } /* リストのノードを全て(番兵ノードも含む)解放し,リストを空にする */ now = top; while(now->next != NULL){ free(now->prev); now = now->next; } free(now); fclose(fp); return (0); } まだまだ練習中なもので、かなり拙いものだと思いますが、とりあえずまずはプログラム動くようにしたいです。 よろしくお願いします。

  • 単方向リスト

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct Address{ char name[100]; char tel[100]; char email[100]; }; struct AddressList { struct Address addr; //データそのもの struct AddressList *next; //後続ノードへのポインタ struct AddressList *prev; }; struct AddressList *this,*last,*new,*first; struct Address *addr; /*--------ここからmain関数------------*/ int main(void){ int n,i; //何番目に入れるか? char quit[100]; //繰り返しを止める時に利用。 first=last=NULL; //まず初期化 addr =(struct Address *)malloc(sizeof(struct Address)); if(addr==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } while(-1){ printf("整数を入力してください。\n"); scanf("%d",&n); printf("名前を入力してください。\n"); scanf("%s",addr->name); printf("電話番号を入力してください。\n"); scanf("%s",addr->tel); printf("メールアドレスを入力してください。\n"); scanf("%s",addr->email); new =(struct AddressList *)malloc(sizeof(struct AddressList)); //新たに加えるリストの動的メモリー確保 if(new==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } new->addr=addr; //ここでエラーが発生します。 new->next=NULL; incompatible types in assignment とエラーがでます。 型はあってると思うんですが、、、 よろしくおねがいします。

  • 双方向リストについて

    *prevは前の要素へのポインタ *nextは後ろの要素へのポインタ typedef struct list_t { char line[256]; struct list_t *prev; struct list_t *next; } LIST; 削除処理 *pが削除する要素 delete_line(LIST *p) { p->prev->next = p->next; p->next->prev = p->prev; free(p) } *pが挿入する要素 *cが挿入する場所 insert_line(LIST *c, LISt *p) { /*両隣へポインターをつなぐ*/ p->prev = c->prev; p->next = c; /*両隣のポインターをつなぎ換える*/ c->prev->next = p; c->prev = p; } これは、ある本に書かれていたものなのですが、どうしても、理解ができません。図を描きながら追ってみたのですが、cは、挿入する場所を表しているのですが、図で描こうにもどこがその場なのかが、わかりません。あと挿入処理のところでpやcが代入されていますが、pやcは、どこを表しているのですか?この本の説明がおかしいのでしょうか?それとも私の考え方が違うのでしょうか・・・。ご指導いただければありがたいです。

  • C言語のリストのソートについて質問します。

    C言語のリストのソートについて質問します。 こんばんは、aida13です。以前の質問が自己解決しました。回答者のみなさん本当にすみませんでした。 今回はそのアルゴリズムで改善したい点がありましたので投稿させていただきました。以下のソートを実行するとソート自体はうまくいくのですが、見ての通りwhileやifなどを使って何度も実行しなおさないと完全にソートできません(「5 4 3 2 1」→「4 3 2 1 5」(一回ソート))。これを一回でソートできるようにしたいのです。また、降順も同様にそのままsecondとheadを入れ替えたのですが…今度は何度やっても「1 2 3 4 5」→「2 1 3 4 5」(一回ソート)からそれ以上動きません。アドバイスをお願いします。また、出来る限りこの形を保てる形でお願いします。 以下自作ソート #include < stdio.h > #include < stdlib.h > struct ans { int data; struct ans *next; }; struct ans *sort_up(struct ans *head) { int temp; struct ans *second_head; second_head = (struct ans *)malloc(sizeof(struct ans)); second_head = head->next; if( head->next == NULL ) { return head; } else { if( head->data > second_head->data ) { temp = head->data; head->data = second_head->data; second_head->data = temp; sort_up(head->next); } else { sort_up(head->next); } return head; } } struct ans *add_list(int x, struct ans *head) { struct ans *new_head; new_head = (struct ans *)malloc(sizeof(struct ans)); new_head->data = x; new_head->next = head; return new_head; } void show_list(struct ans *head) { if( head == NULL ) { printf("\n\n"); } else { printf("%d ",head->data); show_list(head->next); } } void main() { struct ans *head; head = NULL; head = add_list(1,head); head = add_list(2,head); head = add_list(3,head); head = add_list(4,head); head = add_list(5,head); do { printf("input:"); scanf("%d",&a); if(a==0) { head = sort_up(head); show_list(head); } } while(a==0); }

  • C言語の問題について

    #include <stdio.h> #define NMAX 20 struct node_tag { ??????? }; int main(void) { ??????? struct node_tag *p; int i; for (???????) { ??????? } p = ???????; while (p!=NULL){ printf("%d %s\n", ???????, ???????); p = ??????? } return 0; } 「 日付(整数) と 曜日名(文字) と 次の要素を指すポインタ 」を要素に持つ自己参照構造体 struct note_tag を定義して、この構造体を利用して線形リストを作成し,日付と曜日を表示させるプログラムを作成したいのですが?がわからなくて困ってます・・・どうか教えてください

  • C言語 二分木探索

    今、int型の二分木にデータを追加する関数(引数は二分木へのポインタと追加する値、追加されたノードへのポインタを返す)をつくろうとしてます。 以前リストにデータを追加する関数をつくったのでそれを変更してつくろうとしているのですが途中までいってつまってしまいました。 つくりかたを教えてください。 よろしくお願いします! struct BinaryTreeNode{ int data; struct BinaryTreeNode *l_next; struct BinaryTreeNode *r_next; }; struct BinaryTree{ int node_num; struct BinaryTreeNode *root; }; BinaryTreeNode *BinaryTreeNodeAlloc(void) { BinaryTreeNode *node; node = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode)); if (node == NULL) { return (NULL); } node->l_next = NULL; node->r_next = NULL; return (node); } BinaryTreeNode *BinaryTreeDataAdd(BinaryTree *list, int x) { BinaryTreeNode *ptr; BinaryTreeNode *prev; BinaryTreeNode *new_node; ptr = list->root; prev = NULL; while (ptr) {       ←?? if (ptr->data < x) { prev = ptr; ptr = ptr->next; } else if (ptr->data == x) { return (NULL); } else { new_node = BinaryTreeNodeAlloc(); if (new_node == NULL) { exit (0);                ←?? } new_node->data = x; new_node->next = ptr; if (prev != NULL) { prev->next = new_node; } else { list->head = new_node; } list->node_num++; return (new_node); } } new_node = BinaryTreeNodeAlloc(); if (new_node == NULL) { exit (0); } new_node->data = x; new_node->r_next = NULL; new_node->l_next = NULL; if (prev != NULL) { prev->next = new_node; } else { list->head = new_node; } list->node_num++; return (new_node); }

専門家に質問してみよう