構造体,ポインタを使った線形リストを扱っている柴田望洋さんの書籍で行き詰りました
ソースコードは
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef enum{
Term,Insert,Append,Delete,Print,Clear
}Menu;
typedef struct __node{
int no;
char name[10];
struct __node *next;
}Node;
void SetNode(Node *x,int no,char *name,Node *next)
{
x->no=no;
x->next=next;//アドレスの格納//
strcpy(x->name,name);
}
Node *AllocNode(void)
{
return calloc(1,sizeof(Node));
}
void InsertNode(Node **x,int no,char *name)
{
Node *y=*x;//先頭をしてもらう**xのアドレス*xを入れる//
*x=AllocNode();
SetNode(*x,no,name,y);
}
void AppendNode(Node **x,int no,char *name)
{
if(*x==NULL)//先頭のアドレスが空なら//
InsertNode(x,no,name);
else{
Node *y=*x;//先頭のアドレスをyによける//
while(y->next!=NULL)
y=y->next;//*x=*x->nextではだめなのか...もしかしたらよけたアドレスと干渉するからではないか?//
y->next=AllocNode();
SetNode(y->next,no,name,NULL);
}
}
void DeleteNode(Node **x)
{
if(*x!=NULL){
Node *y=(*x)->next;
free(*x);
*x=y;
}
}
void ClearList(Node **x)
{
while(*x!=NULL)
DeleteNode(x);
}
void PrintList(Node **x)
{
Node *y=*x;
puts("一覧表");
while(y!=NULL){
printf("会員番号:%d\n",y->no);
printf("名前:%s\n",y->name);
printf("\n");
y=y->next;
}
}
void InitList(Node **x)
{
*x=NULL;
}
void TermList(Node **x)
{
ClearList(x);
}
Node Read(const char *message)
{
Node temp;
printf("%sするデータを入力してください\n",message);
printf("番号:");scanf("%d",&temp.no);
printf("名前:");scanf("%s",temp.name);
return temp;
}
Menu SelectMenu(void)
{
int ch;
do{
printf("\n(1)先頭にノードを挿入(2)末尾にノードを追加\n");
printf("(3)先頭のノードを削除(4)全ノードを表示\n");
printf("(5)全ノードの削除 (0)処理終了:");
scanf("%d",&ch);
}while(ch<Term||ch>Clear);
return (Menu)ch;
}
int main(void)
{
Menu menu;
Node *list;
InitList(&list);
do{
Node x;
switch(menu=SelectMenu()){
case Insert:x=Read("先頭に挿入");
InsertNode(&list,x.no,x.name);
break;
case Append:x=Read("末尾に追加");
AppendNode(&list,x.no,x.name);
break;
case Delete:DeleteNode(&list);
break;
case Print :PrintList(&list);
break;
case Clear :ClearList(&list);
break;
}
}while(menu!=Term);
TermList(&list);
return 0;
}
こんな感じです
構造体,ポインタ
Re: 構造体,ポインタ
void InsertNode(Node **x,int no,char *name)
{
Node *y=*x;//先頭をしてもらう**xのアドレス*xを入れる//
*x=AllocNode();
SetNode(*x,no,name,y);
}
自分の中では
四行目は*x=calloc(1,sizeof(Node))でもいいと思うのですがなぜあえてこのような記述をしたのかがわからないです
著者である望洋さんにしかわからないかもしれませんが,他の方でもこのような記述方法はいろいろあって使う,のならば使い分け?等を教えてほしいです!!
Re: 構造体,ポインタ
>四行目は*x=calloc(1,sizeof(Node))でもいいと思うのですがなぜあえてこのような記述をしたのかがわからないです
?
「コードのある箇所(A)で関数(B)をコールしている記述がある.
そんなことをせずに,その箇所(A)に関数(B)の中身の処理を全部ダイレクトに書けばいいのに,
なぜわざわざ関数を用いた書き方をしているのか」
という事でしょうか?
【関数って何のために書くのか】みたいなことですか?
?
「コードのある箇所(A)で関数(B)をコールしている記述がある.
そんなことをせずに,その箇所(A)に関数(B)の中身の処理を全部ダイレクトに書けばいいのに,
なぜわざわざ関数を用いた書き方をしているのか」
という事でしょうか?
【関数って何のために書くのか】みたいなことですか?
Re: 構造体,ポインタ
なぜわざわざ関数を用いる必要があったのですか?が一番近いです!
また、やはりそれは好みのようなものがあるのか、それとも常識?のレベルでこのように関数を用いる書き方がいいとされているのか、ガキになるところでもあります!
また、やはりそれは好みのようなものがあるのか、それとも常識?のレベルでこのように関数を用いる書き方がいいとされているのか、ガキになるところでもあります!
Re: 構造体,ポインタ
SetNode(), AllocNode(), InsertNode(), AppendNode(), DeleteNode()とあるように、
Nodeを操作する関数群を作りたかったのでしょう。
AllocNode()については、たまたま内容が1行しかないので、
必要性に疑問を持たれているのでしょう。
上記の関数群で、AllocNode()を作らずにcalloc()で済ます場合とどっちが良いでしょうか。
きっと著者は作るべきと思ったのでしょう。
Nodeを操作する関数群を作りたかったのでしょう。
AllocNode()については、たまたま内容が1行しかないので、
必要性に疑問を持たれているのでしょう。
上記の関数群で、AllocNode()を作らずにcalloc()で済ます場合とどっちが良いでしょうか。
きっと著者は作るべきと思ったのでしょう。