リストでスタックを実現したいのですが、以下の関数の使い分けが全く分かりません。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()でメモリをかくほしていないので、無理じゃないかと思っているのですが、どうなのでしょう。
回答3件
あなたの回答
tips
プレビュー