質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

329閲覧

片方向リストの実現について

masuter0413

総合スコア50

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/10/31 14:48

リストでスタックを実現したいのですが、以下の関数の使い分けが全く分かりません。addlist()とmidlist()の違いは何でしょうか。どちらも先生が用意した関数なのですが、説明は以下のようなのですが、どうやってスタックを実現すればいいのでしょうか。とりあえずデータを積む動作を実現したいのです。まずaddlist()の説明は以下のようです。

c

1struct LIST * addList( struct LIST ** pstart){ 2 struct LIST *p, *new; 3 p = *pstart; 4 if((new=(struct LIST *) malloc(sizeof(struct LIST)))==NULL){ 5 return NULL; /* メモリ確保失敗 */ 6 } 7 new->next = NULL; 8 if(p!=NULL){ /* リストに要素が存在するとき */ 9 while(p->next!=NULL){ /* リストの末尾を探す */ 10 p=p->next; 11 } 12 p->next = new; /* リストの末尾につなげる */ 13 }else{ 14 *pstart = new; /* 最初の要素の場所を *pstart に */ 15 } 16 return new; 17 }

リストでは後戻りは出来ないので、先頭のオブジェクトへのポインタは 必ず覚えていなければならない。上の関数 addList() はそうした リストの先頭オブジェクトへのアドレスを引数に取る。関数内部では、 まず、新しいオブジェクトを malloc() で割り当て、 それの後ろにはもうデータがないので最初から next に NULL を代入し ておく。 次に、先頭のオブジェクトへのポインタが NULL でないならば、リストにいくらかの オブジェクトが連なっているのであるから、 先頭から順に次のオブジェクトへのアドレスを取り出し、最後のオブジェクト になるまで移動し、先に確保したオブジェクトをこのリストの最後の オブジェクトの後ろにぶら下げるために、そのアドレス(new)を 最後のオブジェクトの next に入れている。一方、引数を struct LIST ** にしているのは次の削除 との関係で統一をとっているからであり、使うときには実際の リストの先頭へのアドレスを保持しているポインタ変数のアドレスを 渡すようにする。これは特にリストの先頭へのポインタが外部の関数に あるときに、どうやってその先頭へのポインタの中身を書き換えるかと いう問題であり、実際上の例でもリストに要素が一個もない時には、 このリストの先頭へのポインタを pstart に保存しておく必要 があるのであった。従って、この関数を実際に使う場合には以下のように して使う必要がある。

c

1 struct LIST *start=NULL; 2 ... 3 addList(&start); 4

この説明を見る限り,addlist()はスタックを実現する際、先頭は1つだけなので、実行するのは1度だけでいいという事でしょうか。
midlidt()の説明は以下のようです。

c

1struct LIST * midList( struct LIST *before, struct LIST *new){ 2 struct LIST *p = before; 3 new->next = before->next; 4 before->next = new; 5 return new; 6 }

ここで、before はオブジェクトを挿入したい場所の前に位置する リンクのオブジェクトであり、new は新たに挿入したいオブジェクトである。 ポイントは、before の次に new が来るようにし、new の後ろに 元々 before の後ろに位置していたオブジェクトを繋げる事である。 但し、このプログラムでは先頭にオブジェクトを入れることができない 点には注意しよう

データを積む際にはこのmidlist()を使えばいいのでしょうか。けど、malloc()でメモリをかくほしていないので、無理じゃないかと思っているのですが、どうなのでしょう。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttyp03

2018/10/31 23:27

まずは文章に適度な改行を!読みづらい。
guest

回答3

0

ベストアンサー

たぶん、下記のような使用方法と思います。
ソースコードを見れば、だいたいの使用方法がわかると思いますので
復習がてらいろいろと試せば良いと思います。

int main() { struct LIST *start=NULL; addList(&start); printf("構造体のアドレスは%p\n", start); printf("start->nextのアドレスは%p\n", start->next); struct LIST *nextA = addList(&start); printf("nextAのアドレスは%p\n", nextA); printf("start->nextのアドレスは%p\n", start->next); struct LIST *nextB = addList(&start); printf("nextBのアドレスは%p\n", nextB); printf("nextA->nextのアドレスは%p\n", nextA->next); struct LIST *nextC = addList(&start); printf("nextCのアドレスは%p\n", nextC); printf("nextB->nextのアドレスは%p\n", nextB->next); struct LIST *nextD = addList(&start); printf("nextDのアドレスは%p\n", nextD); printf("nextC->nextのアドレスは%p\n", nextC->next); printf("--------------------\n"); midList(nextA, nextC); printf("nextA->nextのアドレスは%p\n", nextA->next); printf("nextBのアドレスは%p\n", nextB); printf("nextC->nextのアドレスは%p\n", nextC->next); return 0; }

投稿2018/11/01 11:16

ai_2013_dev

総合スコア338

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

このmidListは

A -> B

というListがあったときにmidList(A, C)とすることで

A -> C -> B

にする関数みたいです.

けど、malloc()でメモリをかくほしていないので

これに関してはmidListは呼び出し元がすでにCを用意していることを前提にしており,
AとCのnextの張替えしかしていません

投稿2018/10/31 15:20

hiroCSJT

総合スコア93

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

疑問があるなら、その先生に聞きましょう。

ここはあなたの不満を聞く場所ではないです

投稿2018/10/31 14:54

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問