リストの構造体のデータをソートしているコードがあるんですが、その中の
exchange()関数のところを図を使って書こうと思ったのですが、うまくいきません。
その前に書かれているコードの正確な理解が出来ていないと思います。
exchange()関数のところでご教授してもらいました説明を参考に、コメントをつけました。
if (s->next != 0){}の下の文r->before = s;からs->next = r;までは
if (s->next == 0){}という条件のことでしょうか。
if{},else{}文でしているのは、「ポインタのポインタ」のつなぎ替えと思うのですが、
if{}文で何をしているのか
条件は&((*p)->next) == q でqが(*p)->nextのアドレスをポイントしている。または
&((*q)->next) == pでpが(*q)->nextのアドレスをポイントしている場合。
ということは分かりました。
else{}文で何をしているのか
上のif{}文の条件でないときの作業だと思うのですが、
if (s->next != 0){}から下のコード(r->before = s;から)を
どなたか詳しく、やさしい説明をしてもらえませんか。
よろしくお願いいたします。
//codepad.org/B83f1FSq //正常動作(リスト構造) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> // #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; }; void data_show(struct address* head); void data_sort(struct address** head); void chop(char *p){ for (; *p; p++) ; p--; while (*p == '\r' || *p == '\n') *(p--) = 0; } void list_add(struct address **head, char *name, char *address, char *tel, char *mail) { struct address *p; if ((p = malloc(sizeof(struct address))) != 0) { strcpy(p->name, name); strcpy(p->address, address); strcpy(p->tel, tel); strcpy(p->mail, mail); p->next = *head; if (p->next != 0) p->next->before = p; p->before = 0; *head = p; } } void data_show(struct address *head) { if (head != 0) { printf(" %s, %s, %s, %s\n", head->name, head->address, head->tel, head->mail); data_show(head->next); } } 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) return head; else return p; } //大小を入れ替える void exchange(struct address **p, struct address **q) { struct address *r, *s, *t; assert(*p != 0 && *q != 0); if (p == q) return; r = *p; s = *q; if (&((*p)->next) == q || &((*q)->next) == p) { if (s->next != 0){ s->next->before = r; } s->before = r->before; r->before = s; *p = s; *q = s->next; s->next = r; return; } else { if (s->next != 0) s->next->before = r; if (r->next != 0) r->next->before = s; t = s->before; s->before = r->before; 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); //関数listmin(head)は、名前からリストの全ての要素をチェックして、 //いちばん小さいnameを持つ要素を返していると思われます。 //そうでないと正しくソートされません。 if (p == 0)break; exchange(head, p); //大小を入れ替える head = &((*head)->next); //見つけたいちばん小さい要素を関数exchange(head, p)で先頭に移動しています。 } } } void release(struct address **head) { if (*head != 0) { release( &((*head)->next) ); free(*head); *head = 0; } } int main() { struct address *head; FILE* fp; static char buff[N], name[N], address[N], tel[N], mail[N]; char *token=","; head = 0; if ((fp = fopen(FILENAME,"r")) != 0) { while(fgets(buff, N, fp) != 0){ //本当の大元の文字列を書き換えないようにするために //bufを確保してコピーし、それをstrtok()の引数にしている。 char *p; chop(buff); printf( "ファイルから読んだ文字列:%s\n", buff ); p = strtok(buff, token); if ( p != NULL ) { strcpy(name, p); } else { printf( "氏名の切り出しに失敗しました。\n"); break; } p = strtok(NULL, token); if ( p != NULL ) { strcpy(address, p); } else { printf( "住所の切り出しに失敗しました。\n"); break; } p = strtok(NULL, token); if ( p != NULL ) { strcpy(tel, p); } else { printf( "電話番号の切り出しに失敗しました。\n"); break; } p = strtok(NULL, token); if ( p != NULL ) { strcpy(mail, p); } else { printf( "メールアドレスの切り出しに失敗しました。\n"); break; } list_add(&head, name, address, tel, mail); } fclose(fp); } data_sort(&head); data_show(head); release(&head); return 0; } /* 実行結果 naka@naka ~ $ cd kadai/kadai9-8 naka@naka ~/kadai/kadai9-8 $ gcc -o kad9-8b kad9-8b.c -Wall naka@naka ~/kadai/kadai9-8 $ kad9-8b ファイルから読んだ文字列: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 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 yamada, tone, 090-1122, mail-9 naka@naka ~/kadai/kadai9-8 $ */ /* 実行結果 naka@naka ~ $ cd kadai/kadai9-8 naka@naka ~/kadai/kadai9-8 $ gcc -o kad9-8b kad9-8b.c -Wall naka@naka ~/kadai/kadai9-8 $ kad9-8b ファイルから読んだ文字列: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 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 yamada, tone, 090-1122, mail-9 naka@naka ~/kadai/kadai9-8 $ */ /* 実行結果 naka@naka ~ $ cd kadai/kadai9-8 naka@naka ~/kadai/kadai9-8 $ gcc -o kad9-8b kad9-8b.c -Wall naka@naka ~/kadai/kadai9-8 $ kad9-8b ファイルから読んだ文字列: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 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 yamada, tone, 090-1122, mail-9 naka@naka ~/kadai/kadai9-8 $ */ /* 実行結果 naka@naka ~ $ cd kadai/kadai9-8 naka@naka ~/kadai/kadai9-8 $ gcc -o kad9-8b kad9-8b.c -Wall naka@naka ~/kadai/kadai9-8 $ kad9-8b ファイルから読んだ文字列: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 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 yamada, tone, 090-1122, mail-9 naka@naka ~/kadai/kadai9-8 $ */
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/01/28 05:59
退会済みユーザー
2018/01/28 06:01
2018/01/28 07:08
退会済みユーザー
2018/01/28 07:11
退会済みユーザー
2018/01/28 07:12
2018/01/28 07:21
退会済みユーザー
2018/01/28 07:28
退会済みユーザー
2018/01/28 07:57
2018/01/30 01:27