• 締切済み

双方向リストについて

今ゲームを作っているのですがわからなくなったので質問させていただきます。問題のソースなのですが、 ファイル1 //============================================================================= // EnemyAttack // 敵の攻撃処理 // ----------------------------------------------------------------------- // INPUT: void 敵の種類 // OUTPUT: void S_OK = 出撃成功 // !S_OK = 出撃失敗 // GLOBAL: g_enemyType 敵の種類データ //============================================================================= void EnemyAttack(void) { for (int i = 0; i < MAX_ENEMY; i++) { if (g_enemy[i].actFlag == ON) { if(g_enemy[i].shotCounter <= 0) { if(g_enemyBullet.p_UnUseStart.g_NextBullet != NULL) { ENEMYBULLET* baseBullet; baseBullet= g_enemyBullet.p_UnUseStart.g_NextBullet; baseBullet->bullet.move.posX=g_enemy[i].move.posX; baseBullet->bullet.move.posY=g_enemy[i].move.posY; DetachNode(baseBullet); AttachNode(&g_enemyBullet.p_UseEnd,baseBullet); g_enemy[i].shotCounter = ENEMY_SHOT_INTERVAL; } } else { g_enemy[i].shotCounter--; } } } } ファイル2 //---------------------------------------------------------- // AttachNode // 取り付け //---------------------------------------------------------- // input: struct pNode* Base //保持先のアドレス // struct pNode* pNode //保持するアドレス // out true //成功 // false //失敗 //---------------------------------------------------------- bool AttachNode(ENEMYBULLET* pBase,ENEMYBULLET* pNode) { ENEMYBULLET* pPraveNode; pPraveNode = pBase->g_PreveBullet; pPraveNode->g_NextBullet = pNode; pNode->g_NextBullet = pBase; pNode->g_PreveBullet = pPraveNode; pBase->g_PreveBullet = pNode; return true; } //---------------------------------------------------------- // AttachNode // 取り外し //---------------------------------------------------------- // input: struct pNode* pBase //ベースとなるアドレス // // out true //成功 // false //失敗 //---------------------------------------------------------- bool DetachNode(ENEMYBULLET* pNode) { ENEMYBULLET* pPrave; ENEMYBULLET* pNext; if(pNode == NULL) { return false; } if(pNode->g_PreveBullet==NULL || (pNode->g_NextBullet == NULL)) { return false; } pPrave= pNode->g_PreveBullet; pNext = pNode->g_NextBullet; pPrave->g_NextBullet = pNext; pNext->g_PreveBullet = pPrave; pNode->g_NextBullet=NULL; pNode->g_PreveBullet=NULL; return true; }なのですが、 void EnemyAttack(void) { for (int i = 0; i < MAX_ENEMY; i++) { if (g_enemy[i].actFlag == ON) { if(g_enemy[i].shotCounter <= 0) { if(g_enemyBullet.p_UnUseStart.g_NextBullet != NULL) { ENEMYBULLET* baseBullet; baseBullet= g_enemyBullet.p_UnUseStart.g_NextBullet; baseBullet->bullet.move.posX=g_enemy[i].move.posX; baseBullet->bullet.move.posY=g_enemy[i].move.posY; DetachNode(baseBullet); AttachNode(&g_enemyBullet.p_UseEnd,baseBullet); g_enemy[i].shotCounter = ENEMY_SHOT_INTERVAL; } } else { g_enemy[i].shotCounter--; } } } }のところで AttachNode(&g_enemyBullet.p_UseEnd,baseBullet); を通ったときはちゃんとg_enemyBullet.p_UseStartとg_enemyBullet.p_UseEndの間に入っているのに、この関数を出ると g_enemyBullet.p_UseEndの間には入らず、 g_enemyBullet.p_UseStart>g_enemyBullet.p_UseEndになってしまいます。どうしたら消えずに処理が出来るのでしょうか?足りないの補足しますのでよろしくお願いします。

  • 79562
  • お礼率68% (164/239)

みんなの回答

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

「この関数を出ると」の「この関数」が何を指しているのかわかりませんが, とにかく「リスト操作をしておかしなことになる」とすれば ・AttachNode を呼び出す直前と呼び出した直後でリストを表示する ・DetachNode を呼び出す直前と呼び出した直後でリストを表示する とかやって, 「どこでおかしくなるのか」を見付けないと手掛りがないよね? また, #2 にも書いておいたんだけど 「実は使い終わった領域を回収し忘れている」ということも考えられなくはないです. ついでだけど, コメントは「正しく」書いてくださいね. コードとあきらかに異なるコメントは意味がないどころか有害ですらあります.

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

一見した感じでは AttachNode, DetachNode は正しいような気がします. だから, このコードに出てこないところ, 例えば InitBanpei なんかが微妙に怪しいのかも. いずれにしても, 最終的には「操作の前後でリストを表示する」ことになるかもしれませんね. あと, 「実は使い終わった領域を回収し忘れている」というオチがないことも確認してください. 以下は余談: ・今の場合にうれしいかどうかは分かりませんが, 双方向リストでは循環リストにすることで番兵を 1つにすることができます. ・タグ名であっても _ で始まる識別子を使うのは危険です. どうせ後で typedef するのだから, タグ名と typedef名をそろえて, 例えば typedef struct ENEMYBULLET { ... } ENEMYBULLET; のようにした方が安全です (「ファイルスコープでは _ で始まる識別子は使えない」と思ってもいい). あるいは逆順に struct ENEMYBULLET ENEMYBULLET; struct ENEMYBULLET { ... }; という宣言順序でもいい. ・コメントとコードがあっていません. ちゃんと適切なコメントをつけてください.

79562
質問者

お礼

回答ありがとうございます。 InitBanpeiは多分間違っていないと思います。一応載せておきます。 //---------------------------------------------------------- // InitBanpei // 番兵の初期化 //---------------------------------------------------------- // input: struct pNode* pNode //番兵のアドレス //---------------------------------------------------------- void InitBanpei(ENEMYBULLET* pStartNode,ENEMYBULLET* pEndNode) { pStartNode->g_PreveBullet=NULL; pStartNode->g_NextBullet=pEndNode; pEndNode->g_PreveBullet=pStartNode; pEndNode->g_NextBullet=NULL; } >最終的には「操作の前後でリストを表示する」ことになるかもしれませんね 操作の前後でリストを表示するとはどういうことでしょうか?

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.1

双方向リストを実現するための構造体の定義を提示してください。 構造体の各メンバーに対する日本語の説明があるとうれしいです。

79562
質問者

お礼

回答ありがとうございます。 istnode.h //弾バッファ struct _tagBulletBuffer { BULLET bullet; // struct _tagBulletBuffer* g_PreveBullet; //前のノード struct _tagBulletBuffer* g_NextBullet;  //次のノード }; typedef struct _tagBulletBuffer ENEMYBULLET; //弾 struct _tagNormalBullet { int shotCounter; //ショットカウンター ENEMYBULLET p_UseStart;  //使用用先頭ノード ENEMYBULLET p_UseEnd;   //使用用終わりノード ENEMYBULLET p_UnUseStart; //使用なし先頭ノード ENEMYBULLET p_UnUseEnd;  //使用なし終わりノード }; です。

79562
質問者

補足

UnUseStartとUnUnseEndは100個のデータを入れることが出来ました。 ファイル1 //============================================================================= // StartProgram // プログラム全体の初期化を行う // ----------------------------------------------------------------------- // INPUT: IDirect3DDevice9* pd3dDevice D3Dデバイス // OUTPUT: HRESULT S_OK = 成功(現在は成功のみ) // ----------------------------------------------------------------------- // GLOBAL: g_myShip 自機データ //============================================================================= HRESULT StartProgram(IDirect3DDevice9* pd3dDevice) {      ・      ・       ・ //使用用弾の番兵の初期化 InitBanpei(&g_enemyBullet.p_UseStart,&g_enemyBullet.p_UseEnd); //未使用弾の番兵の初期化 InitBanpei(&g_enemyBullet.p_UnUseStart,&g_enemyBullet.p_UnUseEnd); ENEMYBULLET* addBullet; //敵弾 for(int i=0;i<MAX_BULLET;i++) { addBullet=(ENEMYBULLET*)malloc(sizeof(ENEMYBULLET)); SetChipLTPos (&addBullet->bullet.chip, 0, 10); SetChipSize (&addBullet->bullet.chip, 8, 8); SetChipCenter(&addBullet->bullet.chip, 8 / 2, 8/2); addBullet->bullet.move.posX=100; addBullet->bullet.move.posY=10; addBullet->bullet.move.velX=-5; addBullet->bullet.move.velY=-5; addBullet->bullet.bodyBottom=0; addBullet->bullet.bodyLeft=0; addBullet->bullet.bodyRight=0; addBullet->bullet.bodyTop=0; AttachNode(&g_enemyBullet.p_UnUseEnd,addBullet); }

関連するQ&A

  • 単行リストのソートのプログラムについて

    単行リストのソースでわからなくなったので質問させていただきます。 #include<stdio.h> //---------------------------------------------------------- // InitBanpei // 番兵の初期化 //---------------------------------------------------------- // input: struct pNode* pNode //番兵のアドレス //---------------------------------------------------------- void InitBanpei(struct node* pStartNode,struct node* pEndNode); //---------------------------------------------------------- // IsBanpei // 番兵チェック //---------------------------------------------------------- // input: struct pNode* pNode //番兵のアドレス // out : true //成功 // false //失敗 //---------------------------------------------------------- int IsBanpei(struct node* pNode); //構造体 struct node { char name[30]; int kokugo; int suugaku; int eigo; int goukei; struct node* pNext; }; int main(void) { FILE* fp; struct node useStart,useEnd; struct node *p,*j,*max,*a; int stich=0; char work[256]; InitBanpei(&useStart,&useEnd); IsBanpei(&useStart); IsBanpei(&useEnd); fp=fopen("data.txt","r"); if(fp==NULL) { printf("ファイルを開けません\n"); return 0; } while(feof(fp)==0) { fgets(work,256,fp); stich++; } stich--; printf("%d\n",stich); if(stich==0) { printf("件数は0です\n"); return 0; } fclose(fp); fp=fopen("data.txt","r"); if(fp==NULL) { printf("ファイルを開けません\n"); return 0; } j=NULL; for(int i=0;i<stich;i++) { a=new struct node; if(a==NULL) { printf("メモリが確保できません\n"); return 0; } fscanf(fp,"%s %d %d %d ",&(a->name),&(a->kokugo),&(a->suugaku),&(a->eigo)); a->goukei=a->kokugo+a->suugaku+a->eigo; a->pNext=j; j=a; } useStart.pNext=j; max=&useStart; p=max->pNext; while(max->pNext!=NULL) { j=p; while(j->pNext!=NULL) { if(max->goukei< j->goukei) { max=j->pNext; p=j; } j=j->pNext; } p->pNext=max->pNext; max->pNext=useStart.pNext; max=max->pNext; } a=useStart.pNext; while(a->pNext!=NULL) { printf("%7s %03d %3d %3d %3d点\n ",a->name, a->kokugo,a->suugaku, a->eigo,a->goukei); a=a->pNext; } } //---------------------------------------------------------- // InitBanpei // 番兵の初期化 //---------------------------------------------------------- // input: struct pNode* pNode //番兵のアドレス //---------------------------- //------------------------------ void InitBanpei(struct node* pStartNode,struct node* pEndNode) { pStartNode->pNext=pEndNode; pEndNode->pNext=NULL; } //---------------------------------------------------------- // IsBanpei // 番兵チェック //---------------------------------------------------------- // input: struct pNode* pNode //番兵のアドレス // out : true //成功 // false //失敗 //---------------------------------------------------------- int IsBanpei(struct node* pNode) { if( pNode->pNext!=NULL) { return -1; } return 0; } のソースなのですが、単行リストを使って大きい順に並び替えをしたいのですがうまくできません。どこを直せばいいのでしょうか?分かる方いらしたらソースを書いてくださると助かります。

  • 双方向リストのバブルソートについて

    双方向リストをバブルソートを用いてソートしたいです。 下記がプログラム(一部)ですが、ソートした後にリスト表示すると 無限ループに陥ります。 どこがいけないのでしょうか。 #include <stdio.h> #include <stdlib.h> struct cell{ int data; struct cell *next, *prev; }; void insert_head(struct cell **head, int num){ struct cell *p, *p1; p = *head; p1 = make_cell(); *head = p1; p1->data = num; p1->next = p; if(p1->next != (struct cell *)NULL){ p1->next = p; p->prev = p1; } } void print_list(struct cell *head){ struct cell *p; p = head; printf("data = \n"); while(p != (struct cell *)NULL){ printf("%d\n", p->data); p = p->next; } } void sort_list(struct cell **head){ struct cell *p, *p2; int i, n; n = 0; p = *head; while(p->next != (struct cell *)NULL){ p = p->next; n++; } for(i = 0, p = *head; i < n-2; i++){ if(p->data > p->next->data){ if(p == *head){ *head = p->next; }else{ p->prev->next = p->next; } p2 = p->next; p->next = p->next->next; p->next->next = p; p->next->next->prev = p; p->next->prev = p->prev; p->prev = p2; }else p = p->next; } } int main(void){ struct cell *head = (struct cell *)NULL; int n; while(1){ printf("1:Insert head 2:Insert tail 3:Delete 4:List 5:Sort 6:Exit\n"); scanf("%d", &n); switch(n){ case 1: printf("num = "); scanf("%d", &n); insert_head(&head, n); break; case 2: printf("num = "); scanf("%d", &n); insert_tail(&head, n); break; case 3: printf("num = "); scanf("%d", &n); delete_cell(&head, n); break; case 4: print_list(head); break; case 5: sort_list(&head); break; case 6: return 0; break; } } }

  • 双方向リストのプログラミングのチェック

    指定したファイルを読み込み、一行ずつ構造体に保存し、表示させる。その後、キーボードから指定した行を削除し、処理後の結果を表示させる・・・といったプログラミングを作成しています。 通常の表示の部分はできましたが、後は指定した行の削除の部分ができません。 あらかじめHPで調べてあるので、削除するときは、その削除したい行をまたいで、前後のリストを繋げるといった概念的なのは大体理解できました。 自分なりに考えたり調べて、下のように打ちました。 ですが、キーボードから入力した値をどう関数に対応させていくのか、 delete_head,delete_tailの関数の部分に出る、head,tailは使えない的なエラーの対処の仕方がわからなく、詰まってます。 アドバイス、他にも直す場所等ありましたらお願いします。 #include<stdio.h> #include<stdlib.h> #define LINE 1000 typedef struct num{ char line[LINE]; struct num *next; struct num *prev; }Num; void normal(Num **,Num **,char *); void reverse(Num *,Num *,char *); void delete_head(void); void delete_tail(void); void delete(Num *target); int main(int argc,char *argv[]) { FILE *fp; char line[LINE]; int i=0,j; Num *head,*tail,*p; head=NULL; tail=NULL; fp=fopen("test.txt","r"); if(fp==NULL){ fprintf(stdout,"File not found.\n"); exit(1); } while(fgets(line,LINE,fp)!=NULL) { normal(&head,&tail,line); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); p=tail; while(p!=head){ printf("%s\n",p->line); p=p->prev; } printf("%s\n",p->line); printf("input number\n"); scanf("%d",&j); p=head; for(i=0;i<=j;i++);{ p=p->next; } if(p==head){ delete_head(void); } else if(p==tail){ delete_tail(void); } else{ delete(p->prev); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); fclose(fp); return 0; } void normal(Num **s,Num **e,char *g){ Num *tmp; int i; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*e)=(*s); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ (*s)->line[i]=g[i];} (*s)->next=*e; (*s)->prev=*s; } else{ tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=(*e); (*e)->next=tmp; tmp->next=(*e); (*e)=tmp; } return ; } void reverse(Num *kan1,Num *kan2,char *g){ Num *tmp; int i; tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=kan1; kan1->next=tmp; tmp->next=kan2; kan2->prev=tmp; return ; } void delete_head(void){ Num *second=head->next; if(secound==NULL){ free(head); head=NULL; tail=NULL; } else{ second->prev=NULL; free(head); head=second; } } void delete_tail(void){ Num *second_last=head->prev; if(second_last==NULL){ free(tail); head=NULL; tail=NULL; } else{ second_last->next=NULL; free(tail); tail=second_last; } } void delete(Num *target){ Num *after_target; Num *before_target; after_target=target->next; before_target=target->prev; after_target->prev=target->prev; before_target->next=target->next; free(target); }

  • 単方向リストに適当な値を入れて、逆順に表示するプログラムの仕組みがわかりません。

    以下のプログラムのReverceShowValue関数の仕組みがわかりません。 申し訳ございませんが、ご教授の方、よろしくお願いします。 #if 1 /* リスト構造の実装 * 再帰関数を用いて逆順に表示 */ #include <stdio.h> #include <stdlib.h> typedef struct object{ int value; struct object *next; }OBJ; OBJ* AllocateBlock(int value) { OBJ *block; block = (OBJ*)malloc(sizeof(OBJ)); if(block == NULL){ printf("Allocate Error\n"); exit(1); } block->value = value; block->next = NULL; return block; } void ReverceShowValue(OBJ *p) { if(p != NULL){ ReverceShowValue(p->next); printf("%d\n", p->value); } } void FreeAllocate(OBJ *p_top) { OBJ *temp; while(p_top != NULL){ temp = p_top->next; free(p_top); p_top = temp; } } int main(void) { OBJ *top = NULL; OBJ *temp; int i; for(i = 0;i < 10;i++){ if(top == NULL){ top = AllocateBlock(i); temp = top; } else{ temp->next = AllocateBlock(i); temp = temp->next; } } ReverceShowValue(top); FreeAllocate(top); return 0; } #endif

  • ポインタの扱い

    すみません、構造体へのポインタの配列の扱いに困っています。 下記ソースの struct list *hashtable[HASHSIZE]; の箇所をmain部に入れた場合の処理がうまくいきません。。 どのように修正すれば良いのでしょうか。 申し訳ありませんが教えてください。 --------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 40 #define MAX_KW_LEN 256 #define NUM_KW 23 #define TRUE 1 #define FALSE 0 struct list { char keyword[MAX_KW_LEN]; struct list *next; }; struct list *hashtable[HASHSIZE]; static char kw[NUM_KW][MAX_KW_LEN] = { "auto", "break", "double", "enum", "char", "continue", "extern", "float", "for", "int", "long", "register", "short", "signed", "static", "struct", "typedef", "union", "unsigned", "return", "void", "volatile", "while" }; int Hash(char *key); void InitHTable(void); int FindKeyWord(char *key); void ListKeyWord(void); void FreeKeyWord(void); int main(void); int Hash(char *key) { int hashval = 0; while (*key != '\0') hashval += *key++; return (hashval % HASHSIZE); } void InitHTable(void) { int i; struct list *p, *q; int hashval; for (i = 0; i < NUM_KW; i++) { printf("%d\n",i); if ((FindKeyWord(kw[i])) == FALSE) { if ((p = (struct list *)malloc(sizeof(struct list))) == NULL) { fprintf(stderr, "メモリ不足です。\n"); exit(2); } strcpy((*p).keyword, kw[i]); hashval = Hash(kw[i]); if (hashtable[hashval] == NULL) { hashtable[hashval] = p; p->next = NULL; } else { q = hashtable[hashval]; while (q->next != NULL) { q = q->next; } q->next = p; p->next = NULL; } } } } int FindKeyWord(char *key) { struct list *p; for (p = hashtable[Hash(key)]; p != NULL; p = p->next) if (!strcmp(key, (*p).keyword)) return (TRUE); return (FALSE); } void ListKeyWord(void) { int i; struct list *p; for (i = 0; i < HASHSIZE; i++) for (p = hashtable[i]; p != NULL; p = p->next) printf("予約語:%s ハッシュ値:%d:\n", (*p).keyword, Hash((*p).keyword)); } void FreeKeyWord(void) { int i; struct list *p, *q; for (i = 0; i < HASHSIZE; i++) for (p = hashtable[i]; p != NULL; ) { q = p->next; free(p); p = q; } } int main(void) { char word[MAX_KW_LEN]; int i; InitHTable( ); ListKeyWord( ); for (i = 0; i < 4; i++) { printf("Cの予約語を入力して下さい "); fgets(word, 128, stdin); if ((FindKeyWord(word)) == TRUE) printf("%s は登録済みです。\n", word); else printf("%s は未登録です。\n", word); } FreeKeyWord( ); }

  • 構造体へのポインタ

    すみません、構造体へのポインタの配列の扱いに困っています。 下記ソースの struct list *hashtable[HASHSIZE]; の箇所をmain部に入れた場合の 他の関数内での使用の仕方が全くわかりません。 どのように修正すれば良いのでしょうか。 申し訳ありませんが教えてください。 --------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 40 #define MAX_KW_LEN 256 #define NUM_KW 23 #define TRUE 1 #define FALSE 0 struct list {  char keyword[MAX_KW_LEN];  struct list *next;   /* 次の list へのポインタ */ }; struct list *hashtable[HASHSIZE]; /* ハッシュテーブル */ /* キーワード ( Cの予約語 ) */ static char kw[NUM_KW][MAX_KW_LEN] = {   "auto", "break", "double",   "enum", "char", "continue", "extern", "float", "for", "int",   "long", "register", "short", "signed", "static",   "struct", "typedef", "union", "unsigned", "return",   "void", "volatile", "while" }; int Hash(char *key); void InitHTable(void); int FindKeyWord(char *key); void ListKeyWord(void); void FreeKeyWord(void); int main(void); int Hash(char *key) {  int hashval = 0;  while (*key != '\0')   hashval += *key++;  return (hashval % HASHSIZE); } void InitHTable(void) {  int i;  struct list *p, *q;  int hashval;  for (i = 0; i < NUM_KW; i++) {   printf("%d\n",i);   if ((FindKeyWord(kw[i])) == FALSE) { /* 登録されていなかったら */             /* メモリを割り付ける */    if ((p = (struct list *)malloc(sizeof(struct list))) == NULL) {     fprintf(stderr, "メモリ不足です。\n");     exit(2);    }    strcpy((*p).keyword, kw[i]);    hashval = Hash(kw[i]);    /* ハッシュ値を求めて */        if (hashtable[hashval] == NULL) { /* 未登録なら */     hashtable[hashval] = p;  /* p の指すアドレスを登録 */     p->next = NULL;    /* リストの末尾に NULL を追加 */    }    else {        /* 既に登録していたら */     q = hashtable[hashval];     while (q->next != NULL) {  /* データがなくなるまで */      q = q->next;    /* リストをたどる */     }     q->next = p;     /* リストの末尾に p の指すアドレスを登録 */     p->next = NULL;    /* その末尾に NULL を追加 */    }   }  } } int FindKeyWord(char *key) {  struct list *p;  for (p = hashtable[Hash(key)]; p != NULL; p = p->next)   if (!strcmp(key, (*p).keyword))  /* 登録済みなら */    return (TRUE);     /* TRUE を返す */   return (FALSE);      /* 未登録ならFALSE を返す */ } void ListKeyWord(void) {  int i;  struct list *p;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; p = p->next) /* p が NULL でなければ */               /* ハッシュ値とキーワードを表示 */    printf("予約語:%s ハッシュ値:%d:\n", (*p).keyword, Hash((*p).keyword)); } /* malloc( ) で割り付けたメモリを解放 */ void FreeKeyWord(void) {  int i;  struct list *p, *q;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; ) { /* p が NULL でなければ */    q = p->next;      /* p->next を保存 */    free(p);       /* メモリを解放 */    p = q;        /* p->next を p に代入 */   } } int main(void) {  char word[MAX_KW_LEN];  int i;  InitHTable( );  ListKeyWord( );  for (i = 0; i < 4; i++) {   printf("Cの予約語を入力して下さい ");   fgets(word, 128, stdin);   if ((FindKeyWord(word)) == TRUE)    printf("%s は登録済みです。\n", word);   else    printf("%s は未登録です。\n", word);  }  FreeKeyWord( ); }

  • リスト構造のプログラミング

    #include<stdio.h> #include<stdlib.h> typedef struct number{ float x; struct number *next; }Num; void append_list(Num **, float); int main(void) { Num *start,*p; float i,d; start=NULL; for(i=0.0;i<10.0;i++){ append_list(&start,i); } p=start; while(p!=NULL){ printf("%f\n",p->x); p=p->next; } p=start; while(p !=NULL){ Num *q; q=p; p=p->next; free(q); } return 0; } void append_list(Num **s, float n) { Num *end, *new; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*s)->x=n; (*s)->next=NULL; return; }end=(*s); while(end->next !=NULL){ end=end->next; } new=(Num *)malloc(sizeof(Num)*1); new->x=n; new->next=NULL; end->next=new; } 0~9までの数値を順番に追加してリスト構造のデータ構造で 保存するプログラミングを作ったのですが、これにキーボード から入力した1つの実数(0~9)を数値の順序を乱さないよう にその数値を持つ要素を追加するにはどうすればよいのでしょうか?

  • 連結リストをソート

    学校の課題なんですが正直手も足も出ません。 どういった流れで作成すればいいんでしょうか。 1.連結リストにデータ(文字列)をソートされた順序に追加するようなプログラムを作成する. 2.連結リストのデータを順にプリントするプログラムを作成する。 3.セルをキーとそれに対応する値を含めるように拡張し、与えられたキーを持つセルを探索して  それに対する値を返すプログラムを作成する。 課題を解く際には以下のプログラムを参考にする #include <stdio.h> struct element{ char data; struct element *next; }; struct elements *new() { return((struct element *)malloc(sizeof(struct element))); } struct element *create() { struct element *p; p=new(); p->next=NULL; return(p); } void insert(struct element *l,int k,char item) { struct element *p; if(k>1) insert(l->next,k-1,item); else{ p=new(); p->data=item; p->next=p; l->next=p; } } void delete(struct element *l,int k) { if(k>1) delete(l->next,k-1); else l->next=l->next->next; } char access(struct element *l,int k) { if(k>1) return(access(l->next,k-1)); else return(l->next->data); }

  • ばばぬきプログラムについて

     下記のようなプログラムで4人のコンピュータにババヌキをさせるプログラムを組んでる最中なんです。  decklistまでは表示できてもshufflelistではコンパイルは通っても実行するとデバックが起きてしまって困っています。while文をなくすとちゃんと返り値を持って表示はできるんですがwhile分で繰り返したとたんデバックが起きるんですがその理由がわかりません。どうして無理でしょうか?ご教授願います。 decklistは整列されリストに保存した山札の関数。 shufflelistはランダムで保存していく関数。 personの関数はdecklistのほうで試したところコンパイルは通るんですがこちらもデバックが起きてしまいます。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define N 53 //デッキのカードの構造体 struct card{ int t; struct card *next; }*deck; //カードを配った後のそれぞれのプレイヤーの情報(仮 struct player{ int card; struct player *nextcard; struct player *nextturn; }; //関数定義 struct card *talloc(void); struct player *lalloc(void); struct card *decklist(void); struct card *shufflelist(void); struct player *person(struct player *P); void displist(void); int main(void){ struct player *A,*B,*C,*D; struct player *p; p=person(A); while(p!=NULL){ printf("%d ",p->card); p=p->nextcard; } return 0; } //card構造体のセルの確保 struct card *talloc(void){ return (struct card *)malloc(sizeof(struct card)); } //player構造体のセルの確保 struct player *lalloc(void){ return (struct player *)malloc(sizeof(struct player)); } //カードを切る前の整列された山札の関数 struct card *decklist(void){ int i,add=1,count=0; struct card *p; deck=NULL; for(i=0;i<53;i++){ if(count==4){ add+=1; count=0; } p=talloc(); p->t=add; p->next=p; count++; p->next=deck; deck=p; } return deck; } //山札をシャッフルした後の山札の関数 struct card *shufflelist(void){ int i,a,count=0,r; struct card *d,*p,*q,*shuffle; p=decklist(); shuffle=NULL; while(p!=NULL){ srand(time(NULL)); r=(int)rand()%(N-count); for(i=0;i<r;i++){ p=p->next; } q=talloc(); q->t=p->t; d=p->next; p->next=d->next; q->next=shuffle; shuffle=q; count++; p->next=p; } return shuffle; } //プレイヤーへカードを配るための関数 struct player *person(struct player *PERSON){ struct player *a; struct card *library; int i; PERSON=NULL; library=decklist(); a=lalloc(); while(a!=NULL){ a->card=library->t; for(i=0;i<4;i++){ library=library->next; } a->nextcard=a; a=PERSON; } a->nextcard=NULL; while(a!=NULL){ printf("%d ",a->card); } return PERSON; }

  • C++ 連結リストの結合について

    現在、C++で連結リストの結合を実現しようとしているのですが、自分のやり方ではどうしてもエラーになってしまい、他にうまい実現方法が思いつかないので質問させていただきます。 以下が私が作ったプログラムなのですが、どこをどう変えたらうまく行くのか、具体的に教えて頂けたら嬉しいです。結合関数はaddAll(List &l)です。よろしくお願いします。 #include <iostream> using namespace std; class Cell{ private: int data; Cell *next; public: Cell(int d, Cell *n = NULL){ data = d; next = n; } friend class List; }; class List{ private: Cell *head; public: List(){ head = NULL; } ~List(){ while (head != NULL)removeFirst(); } void addLast(int data); void removeFirst(); void print(); void addAll(List &l); }; void List::addLast(int data){ if (head == NULL){ head = new Cell(data); } else{ Cell *p = head; while (p->next != NULL){ p = p->next; } p->next = new Cell(data); } } void List::removeFirst(){ if (head == NULL){ return; } else if (head->next == NULL){ delete head; return; } Cell *removed = head; head = head->next; delete removed; } void List::print(){ if (head == NULL){ return; } for (Cell *p = head; p != NULL; p = p->next){ cout << p->data << ' '; } cout << endl; } void List::addAll(List &l){ if (l.head == NULL){ return; } else if (head == NULL){ if (l.head == NULL){ return; } else{ head = l.head; return; } } else{ Cell *p = head; while (p->next != NULL){ p = p->next; } p->next = l.head; } return; } int main(){ List l1; l1.addLast(1); l1.addLast(2); l1.addLast(3); l1.print(); List l2; l2.addLast(4); l2.addLast(5); l2.addLast(6); l1.addAll(l2); l1.print(); return 0; } 実行結果は 1 2 3 1 2 3 4 5 6 と表示されればOKです

専門家に質問してみよう