構造体,ポインタ
Posted: 2016年7月28日(木) 13:24
構造体,ポインタを使った線形リストを扱っている柴田望洋さんの書籍で行き詰りました
ソースコードは
#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;
}
こんな感じです
ソースコードは
#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;
}
こんな感じです