構造体,ポインタ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
abc

構造体,ポインタ

#1

投稿記事 by abc » 7年前

構造体,ポインタを使った線形リストを扱っている柴田望洋さんの書籍で行き詰りました

ソースコードは
#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;
}
こんな感じです

abc

a

#2

投稿記事 by abc » 7年前

このコードについてなのですがまず初めに

コード:

Node *AllocNode(void)
{
 return calloc(1,sizeof(Node));
}
の部分の関数名の前にアスタリスクがあります,そういった関数がどう動くかがいまいちわかりません.

すごく初歩的なことかと思われますがご存知でしたらどなたかお願いします
また,フォーラムルールも読まずに投稿した自分をお許しください..

アバター
usao
記事: 1887
登録日時: 11年前

Re: 構造体,ポインタ

#3

投稿記事 by usao » 7年前

>関数名の前にアスタリスク

アスタリスクまでが 戻り値の型 です.
(戻り値はポインタ型)

コード:

Node* AllocNode(void)
と書けば少しだけわかりやすいかもしれません.

abc

Re: 構造体,ポインタ

#4

投稿記事 by abc » 7年前

コード:

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))でもいいと思うのですがなぜあえてこのような記述をしたのかがわからないです
著者である望洋さんにしかわからないかもしれませんが,他の方でもこのような記述方法はいろいろあって使う,のならば使い分け?等を教えてほしいです!!

アバター
usao
記事: 1887
登録日時: 11年前

Re: 構造体,ポインタ

#5

投稿記事 by usao » 7年前

>四行目は*x=calloc(1,sizeof(Node))でもいいと思うのですがなぜあえてこのような記述をしたのかがわからないです



「コードのある箇所(A)で関数(B)をコールしている記述がある.
 そんなことをせずに,その箇所(A)に関数(B)の中身の処理を全部ダイレクトに書けばいいのに,
 なぜわざわざ関数を用いた書き方をしているのか」
という事でしょうか?

【関数って何のために書くのか】みたいなことですか?

abc

Re: 構造体,ポインタ

#6

投稿記事 by abc » 7年前

なぜわざわざ関数を用いる必要があったのですか?が一番近いです!
また、やはりそれは好みのようなものがあるのか、それとも常識?のレベルでこのように関数を用いる書き方がいいとされているのか、ガキになるところでもあります!

たいちう
記事: 418
登録日時: 13年前

Re: 構造体,ポインタ

#7

投稿記事 by たいちう » 7年前

SetNode(), AllocNode(), InsertNode(), AppendNode(), DeleteNode()とあるように、
Nodeを操作する関数群を作りたかったのでしょう。

AllocNode()については、たまたま内容が1行しかないので、
必要性に疑問を持たれているのでしょう。
上記の関数群で、AllocNode()を作らずにcalloc()で済ます場合とどっちが良いでしょうか。
きっと著者は作るべきと思ったのでしょう。

閉鎖

“C言語何でも質問掲示板” へ戻る