リストの構造体のデータをソートしているコードがあるんですが、
exchange()関数のところを図を使って書こうと思ったのですが、うまくいきません。
図で説明してもらえませんか。
exchange()関数のところでデータが同じ場合にはそのままreturnして
*p,*qをr、sで保存しているところまでは分かるのですが、そのあとが
さっぱりわかりません。
if (&((*p)->next) == q || &((*q)->next) == p)のところで
&((*p)->next) == q、&((*q)->next) == pは具体的にどういうことなんでしょうか。
if (s->next != 0){}の下の文r->before = s;からs->next = r;までは
if (s->next == 0){}という条件のことでしょうか。
if (s->next != 0){
s->next->before = r;
//「sの次が存在するなら、そいつの手前をrにする」と読める。
//つまり" r ← sの次 " ってゆー上り方向のリンクを張り替えたってこと。
のようなわかり易い説明をしてもらいました。
ポインタのポインタは復習してみました。
コメントを付けていますが、自分でもよくわかりません。
いつも同じような質問で申し訳ありませんが、どなたか説明をしてもらえませんか。
よろしくお願いいたします。
// 電話帳プログラム #define N 256 #define FILENAME "address.csv" struct address{ char name[N]; char address[N]; char tel[N]; // 電話番号 char mail[N]; struct address *next; struct address *before; }; //(*head)->nameと(*head)->next)のnameとを比べて //小さいほうのポインタのポインタを返却値にしている。 struct address **listmin(struct address **head) { struct address **p; if (*head == 0) return 0; if ((*head)->next == 0) return head; if (strcmp((*head)->name, (*(p = listmin(&((*head)->next))))->name) < 0) // #include <string.h> // int strcmp( const char *str1 , const char *str2 ); // str1<str2ならば負の値を返す。 return head; else return p; } void exchange(struct address **p, struct address **q) { struct address *r, *s, *t; assert(*p != 0 && *q != 0); //assertマクロは関数形式マクロで、引数に偽(すなわち0)が指定されると、 //ソースファイル名や行番号等の情報を標準エラー出力に出力し、 //プログラムを終了させます。 if (p == q) return; r = *p; s = *q; if (&((*p)->next) == q || &((*q)->next) == p) { // (*p)はポインタで,(*p)->nextも次のポインタである。 // q(ポインタのポインタ)と(*p)->nextを比較するには&((*p)->next)とする。 if (s->next != 0){ s->next->before = r; //「sの次が存在するなら、そいつの手前をrにする」と読める。 //つまり" r ← sの次 " ってゆー上り方向のリンクを張り替えたってこと。 } r->before = s; //rは*pであるから,*p->before = sである。s==*qなので //*p->beforeに*q(これはポインタ)を代入する。 s->before = r->before; // s->beforeに*q(これはポインタ)を代入する。 *p = s; //sは*qだから*pに*q(これはポインタ)を代入する。 *q = s->next; //s->nextは(*q)->nextであるから*qに(*q)->next(これはポインタ)を代入する。 s->next = r; //rは*pであるから,(*q)->nextに*p(これはポインタ)を代入する。 return; } else { if (s->next != 0){ // (*q)->nextが0でないとき s->next->before = r; // (s->next)->before=*p } t = s->before; // s->before==(*q)->before // t=(*q)->before s->before = r->before; // s->beforeにr->before==(*p)->before(これはポインタ)を代入する。 if (r->next != 0){ // (*p)->nextが0でないとき r->next->before = s; // (r->next)->before=*q } r->before = t; t = r->next; r->next = s->next; s->next = t; *p = s; *q = r; } } void data_sort(struct address **head) { struct address **p; if (*head != 0) { for (;;) { p = listmin(head); //(*head)->nameと(*head)->next)のnameとを比べて //小さいほうのポインタのポインタを返却値にしている。 //帰ってきたhead(小さいほうのポインタのポインタ),または //p(小さいほうのポインタのポインタ) if (p == 0) break; exchange(head, p); //大小を入れ替える head = &((*head)->next); } } } データ address.csv yamada,tone,090-1122,mail-9 hosi,nagoya,5436,mail-7 kato,kanagawa,080-8888,mail-2 koko,yosida,090-2314,mail-6 naka,kamikosaka,080-4444,mail-1 nakada,nogata,090-6376,mail-8 saito,yamanashi,080-6666,mail-3 suzuki,saitama,090-2222,mail-5
回答3件
あなたの回答
tips
プレビュー