• 締切済み

このソースの意味を教えてください

S117の回答

  • S117
  • ベストアンサー率40% (18/45)
回答No.9

まず前提としてこのソースは「リストの説明をするためのソース」です。 で、問題の部分 p->next = head;  /* 今までの先頭ポインタを次ポインタに */ head = p;     /* 新たな領域を先頭ポインタに */ は強調表現がされています。 つまり、リストへの要素追加は  今までの先頭ポインタを次ポインタに して  新たな領域を先頭ポインタに する という説明がしたかったのでしょう。 この説明を関数がまたがる形で表現したくなかったために、わざわざこの位置に head = p; を記述したと考えられます。 しかしご指摘の通り、add_listのローカル変数headに代入するのは重要ではなく、本当の挿入操作が終わるのは、mainのローカル変数headを書き換えた時点。つまり、add_listが戻った時点なので、あまりいい説明ではありません。 ではどうあるべきなのでしょうか。 add_listの代わりに、 新しいlist構造体を確保し、初期化してそのポインタを返す関数、 struct list *new_list(int key, char *name) を用意し、 呼び出し元(main)で、 /* リストにデータを登録 */ tmp = new_list(key, name); tmp->next = head;  /* 今までの先頭ポインタを次ポインタに */ head = tmp;     /* 新たな領域を先頭ポインタに */ としておけば、要素の挿入操作を一カ所で書けて、さらに余計な代入操作を避けられます。

関連するQ&A

  • C言語の自己参照型プログラムについて

    #include <stdio.h> #include <string.h> #include <stdlib.h> struct list { int key; /* キー */ char name[20]; /* 名前 */ struct list *next; /* 次のデータへのポインタ */ }; struct list *add_list(int key, char *name, struct list *head); void show_list(struct list *p); void free_list(struct list *p); int main(void) { struct list *head; /* 先頭ポインタ */ char name[20]; int key = 0; head = NULL; /* 先頭ポインタにNULLを設定 */ printf("キーと名前(MAX:19文字)を入力(終了:CTRL+Z)\n"); while (scanf("%d %s", &key, name) != EOF) { /* リストにデータを登録 */ head = add_list(key, name, head); } /* リストの表示 */ show_list(head); /* リストの開放 */ free_list(head); return 0; } /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) { struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->name, name); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_list(struct list *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->name); p = p->next; } } /*** リストの開放 ***/ void free_list(struct list *p) { struct list *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } } これを実行すると、 新しく入力された順にリストが表示されます。 そうではなく、キーの昇順に表示したいです。 どなたかそのように実行できるようにプログラムを書き換えてくれませんか? 図々しいですがよろしくお願いいたします。m(_ _)m

  • 難しい・・・

    待ち行列への挿入と削除をするプログラムです。 先頭のkeyはそれぞれ I…単語を待ち行列に追加 D…単語を待ち行列から削除 P…現在の待ち行列に並んでいる要素を表示 Q…終了 を意味し、 入力例として I lose I eow D dummy P dummy I pop P dummy Q dummy のようなものを入力した時 eow eow pop のように表示されるようにしたいと思っています。 しかしできません>< プログラムは以下の通りです。 #include <stdio.h> #include <string.h> #include <stdlib.h> struct q{ char key; char word; struct q *next; /* 次のデータへのポインタ */ }; struct q *add_q(char key, char *name, struct q *head); void show_q(struct q *p); void free_q(struct q *p); int main(void) { struct q *head; /* 先頭ポインタ */ char word[20]; char key = 0; head = NULL; while(1){ scanf("%c %s",&key,word); switch(key){ case 'I': head=add_q(key, word, head); case 'P': show_q(head); case 'D': free_q(head); case 'Q': exit(1); default: printf("This is unexpected command\n"); }} return 0; } /*** リストにデータを登録 ***/ struct q *add_q(char key, char *word, struct q *head) { struct q *p; /* 記憶領域の確保 */ if ((p = (struct q *) malloc(sizeof(struct q))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->word,word); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_q(struct q *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->word); p = p->next; } } /*** リストの開放 ***/ void free_q(struct q *p) { struct q *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } }

  • リストの作成と出力(C言語)

    こんにちは<_ _> リストの問題についてなのですが出力と逆順に出力するプログラムで headと前のデータの間に新しいデータを追加するように作ったのですが 入力した値が帰ってきません・・・ http://www9.plala.or.jp/sgwr-t/c/sec15-5.html などを見て見ましたが原因がいまいちよくわかりません。 どなたか教えてください おねがいします<_ _> #include<stdio.h> #include<malloc.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if(scanf("%s",buffer) == EOF){ break; strcpy(p->name, buffer); } if(buffer == "^Z")break; printf(" "); if(gets(buffer) == EOF){ if(scanf("%s",buffer) == EOF){ break; strcpy(p->tel, buffer); } p->pointer=head; /*今までの先頭ポインタを次のポインタに*/ head=p; } p=head; while(p!=NULL){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } return 0; } struct tfield *talloc(void) /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); } 変数は変えるなとのことです。 あと、 「name tel name tel name tel ^z name tel name tel name tel」 と表示したいのですがCtrl+zを二回押さないとできません><、 当方プログラム1ヶ月の初心者です ご指導どうかよろしくお願いします<_ _>

  • 終了条件Ctrl+zについて,結果表示ついて(C言語)

    こんにちは<_ _> 自己参照構造体に関する問題を解いています。 入力したデータとは逆順につながったリストを作成するという 問題で、結果はともかく逆順表示に出力できましたが 微妙なところでNGが出ています。 まず、 (1)「Ctrl+z」一回で終了しなければならない    以下のプログラムでは二回Ctrl+zを入力しないと    入力が終了できません。 (2)入力時並列させること    以下のプログラムでは入力時    「name tell name tell ・ ・     Ctrl+z」    と入力しなければなりませんが 「name tell name tell」 という風に入力しなければなりません・・・ (3)変数を変化、増減させてはならない     並列させるために変数増やそうと思ったら     bufferだけでやらなければならないみたいです・・・ 三時間ぐらい調べて悩みましたがうまくいきませんでした どうしたら以上のようにできるのかご指導、ご鞭撻のほどを どうかよろしくお願いします<_ _> #include<stdio.h> #include<malloc.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if( p == NULL ){ printf( "メモリを確保できません。\n" ); _exit( 0 ); } if(scanf("%s",&buffer)==EOF){ break; strcpy(p->name, buffer); } buffer=0; if(scanf("%s",&buffer)==EOF){ break; strcpy(p->tel, buffer); } p->pointer = head; head = p; } if(head != NULL){ p=head; while(p!=NULL){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } } return 0; } struct tfield *talloc(void)    /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); }

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • mallocとfree

    struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(1); } とサンプルプログラムがあるのですが、if分の意味がわかりません。 また、mallocを使った場合freeで開放とあるのですが、 どういう意味なのかわかりません。 よろしければ、上記2つの点について教えてください。

  • LinkList使い方の意味がわかりません。。。。。

    LinkList使い方の意味がわかりません。。。。。 とあるサイトで以下のソースを目にしました。 ※以下参照 struct LIST * newList( struct LIST ** pstart){ struct LIST *p, *new; p = *pstart; new = (struct LIST *) malloc(sizeof(struct LIST)); new->next = NULL; if(p!=NULL){ /* リストに要素が存在するとき */ while(p->next!=NULL){ /* リストの末尾を探す */ p=p->next; } p->next = new; /* リストの末尾につなげる */ }else{ *pstart = new; /* 最初の要素の場所を *pstart に */ } return new; } そもそもここでnew->next = NULL;やってますけどmallocされた時点で実値は格納されていない と思うので必然的にNULLポインタになると思っていますが。。。(認識違いますか?) 誰か上記のこと含めLinkListに詳しい方使用方法(考え方)をご教授ください。

  • パスを含むファイルリストを表示する際、 ASCIIコード順になるように

    パスを含むファイルリストを表示する際、 ASCIIコード順になるようにソートして表示するようにするプログラムを作っているのですが、リストの仕組がいまいちよくわからず、うまくソートできません。 /* insert_dirent_cell(): セルをリストの先頭に追加する * 引数: head -- リストの先頭のセルへのポインタ * cell -- リストに加えたいセルへのポインタ * 戻り値: リストの先頭のセルへのポインタ */ struct dirent_cell *insert_dirent_cell(struct dirent_cell *head,struct dirent_cell *cell) { struct dirent_cell *ins_buf; //最初に挿入 if(head == NULL) { head = cell; return cell; } //先頭に挿入 if(strcmp(head->name, cell->name) > 0) { cell->next = head; head->next = cell->next->next; return cell; } //途中に挿入 ins_buf = head; while(ins_buf->next != NULL) { if(strcmp(ins_buf->next->name, cell->name) > 0) { cell->next = ins_buf->next; ins_buf->next->next = cell->next->next; return cell; } ins_buf = ins_buf->next; } //最後に挿入 ins_buf->next = NULL; cell->next = ins_buf; return cell; }

  • ポインターの繋ぎ換え

    動的に確保した領域にデータを入れ、 入れたデータをソートするプログラムを作っているのですが、 ソートする際に(入力3データ)→[head=p->next]→(入力2データ)→[head=p->next]→(入力1データ)→[head=p->next]と最後まで見た場合に再度先頭に戻る方法が分からないのでご教授お願いします。 ■イメージ head=NULL p 動的な領域の確保(p) (入力1)|no.1|Name1|struct sample *next| p->next = head /* NULLを入れる */ head = p; /* 入力したデータを入れる */ 動的な領域の確保(p) (入力2)|no.2|Name2|struct sample *next| p->next = head /* 前回の[入力1]のデータを入れる */ head = p; /* 入力2で入れたデータを入れる */ 動的な領域の確保(p) (入力3)|no.3|Name3|struct sample *next| p->next = head /* 前回の[入力2]のデータを入れる */ head = p; /* 入力3で入れたデータを入れる */ *現状* (入力3)-(入力2)-(入力1)-NULL ↑最後に入力したデータ (降順にソート後) |no.3|Name3|struct sample *next| 動的な領域の確保 |no.2|Name2|struct sample *next| 動的な領域の確保 |no.1|Name1|struct sample *next| 環境:WinXP-SP3 コンパイラ:VisualC++ExpressEdition2008 使用関数:malloc 以上、宜しくお願いします。

  • (構造体)双方向連結リストの作成!

    ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。 どうかお力添え願います。 #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ p -> left = tail; tail = p; } p = tail; head = NULL; while(p != NULL){ p -> right = head; head = p; p = p -> left; } head -> left = tail; p = head; printf("リスト表示\n"); while(p != NULL){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return 0; }