C言語関係掲示板

過去ログ

No.1069 スタックのpop,とpush関数

[戻る] [ホームページ]
No.14032

スタックのpop,とpush関数への質問です。
投稿者---うぶ(2004/05/14 18:08:54)


popとpushの関数を作ろうと思ってプログラムを書いたんですが、
void push(double val);
double pop(); 

で下のプログラムをそのまま抜き出してそれぞれ関数にしようとすると、
どうしてもセグメントエラーが出てしまいます。
どう改善すればいいのでしょうか。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct cell {
  double num;
  struct cell *next;
};

int main()
{
  struct cell *head=NULL, *p;
  double data;
  char ans[10];

/* 挿入操作 */
printf("\n操作を選択してください (push/pop/end) --->");
scanf("%s", ans);


while (strcmp(ans, "end") != 0) {


/* push操作 */
 if(strcmp(ans, "push") == 0) {
  printf("データを入力してください  ==>");
  scanf("%lf", &data);
  p = (struct cell *)malloc(sizeof(struct cell));
  p->num = data; p->next = head;
  head=p;
 }

/* pop操作 */
 else {
  if (head == NULL) {
    printf("スタックにデータがありません。 \n"); break; }
  p=head;
  head=p->next;
free((void *)p);
  printf("popされた値は %f です。\n", p->num);
 }


printf("操作を選択してください (push/pop/end) --->");
scanf("%s", ans);
}

printf("プログラムを終了します。\n");
return 0;
}




No.14033

Re:スタックのpop,とpush関数への質問です。
投稿者---ぽこ(2004/05/14 18:33:05)


>で下のプログラムをそのまま抜き出してそれぞれ関数にしようとすると、
>どうしてもセグメントエラーが出てしまいます。
>どう改善すればいいのでしょうか。

上記のプログラムは動いているんですよね?
セグメントフォールトが出る方のプログラムを載せないと、"何が悪いのか"分からないのでは?
また、Push()とPop()のどちらを呼んだ時にセグメントフォールトが出るのでしょうか?





No.14034

Re:スタックのpop,とpush関数への質問です。
投稿者---ぽこ(2004/05/14 18:36:47)


/* pop操作 */
else {
if (head == NULL) {
printf("スタックにデータがありません。 \n"); break; }
p=head;
head=p->next;
free((void *)p);
printf("popされた値は %f です。\n", p->num);
}

追記:
 Pop操作にて、free(p)の後にp->numを参照するのはまずい気がします。


No.14035

Re:スタックのpop,とpush関数への質問です。
投稿者---うぶ(2004/05/14 18:42:43)


セグメントエラーが出るプログラムは

/* push操作 */
if(strcmp(ans, "p") == 0) {
push(data);
}

/* pop操作 */
else if(strcmp(ans, "o") == 0) {

printf("popされた値は %f です。\n", pop());
}

で読み込む関数は

void push(double data)
{
struct cell *p, *head;
printf("データを入力してください  ==>");
scanf("%lf", &data);
p = (struct cell *)malloc(sizeof(struct cell));
p->num = data; p->next = head;
head=p;
}

double pop(void)
{
struct cell *head, *p;
if (head == NULL) {
printf("スタックにデータがありません。 \n"); exit(1); }
p=head;
head=p->next;
free((void *)p);
return p->num;
}

としました。


No.14037

Re:スタックのpop,とpush関数への質問です。
投稿者---ニタチ(2004/05/14 19:34:22)


>void push(double data)
>{
> struct cell *p, *head;
> printf("データを入力してください  ==>");
> scanf("%lf", &data);
> p = (struct cell *)malloc(sizeof(struct cell));
> p->num = data; p->next = head;
> head=p;
>}
>
>double pop(void)
>{
> struct cell *head, *p;
> if (head == NULL) {
> printf("スタックにデータがありません。 \n"); exit(1); }
> p=head;
> head=p->next;
>free((void *)p);
>return p->num;
>}

 main()とpush()、pop()で宣言された、それぞれの *head と *p は、
 全くの別物です。ですから、いくらpush、popしようがmain()の
 *head、*p が指し示す実体には何の影響もありません。
 main()の *head をpush()、pop()に渡し、それを処理してはどうでしょう?

 それから、ぽこさんがおっしゃるように、↓は良くないと思います。

  >free((void *)p);
  >return p->num;



No.14038

Re:スタックのpop,とpush関数への質問です。
投稿者---うぶ(2004/05/14 20:50:11)


> main()の *head をpush()、pop()に渡し、それを処理してはどうでしょう?
  すみません。その渡し方が具体的に分かりませんでした。
  例えば関数のvoid push(double data)のdouble dataを
  structのポインタに変えればよいのでしょうか?

>
> それから、ぽこさんがおっしゃるように、↓は良くないと思います。
>
>  >free((void *)p);
>  >return p->num;


一応下記のようにしてみました。
double pop(void)
{ double val;
struct cell *p, *head, phead;
head = &phead;
if (head == NULL) {
printf("スタックにデータがありません。 \n"); exit(1); }
val=head->num;
p=head;
head=p->next;
free((void *)p);
return val;
}


No.14039

Re:スタックのpop,とpush関数への質問です。
投稿者---ぽこ(2004/05/14 21:35:08)


>  すみません。その渡し方が具体的に分かりませんでした。
>  例えば関数のvoid push(double data)のdouble dataを
>  structのポインタに変えればよいのでしょうか?

void push(struct cell * head, double val);
double pop(struct cell * head);

で、いいのではないのでしょうか?


No.14052

Re:スタックのpop,とpush関数への質問です。
投稿者---うぶ(2004/05/15 17:49:13)


>void push(struct cell * head, double val);
>double pop(struct cell * head);
>
昨日からその方法にして悩んでみたんですけど、
自分はポイントの使い方が理解できなくて
下記のようにしか作れなかったんですけど、
そうしたら“popされた値は 0.00000 です。”
になってしまいました。どうしてなんでしょう、教えてください><


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct cell {
  double num;
  struct cell *next;
};

void push(struct cell * head, double data);
double pop(struct cell * head);

int main()
{
  struct cell *head=NULL, p;
  double data, val;
  char ans[10];


printf("\n操作を選択してください (push/pop/end) --->");
scanf("%s", ans);


while (strcmp(ans, "e") != 0) {


/* push操作 */
  head = &p;
 if(strcmp(ans, "p") == 0) {
  push(head, data);
 }

/* pop操作 */
 else  if(strcmp(ans, "o") == 0) {
  printf("popされた値は %f です。\n", pop(head));
 }


printf("操作を選択してください (push/pop/end) --->");
scanf("%s", ans);
}

printf("プログラムを終了します。\n");
return 0;
}


void push(struct cell *head, double data)
{
  struct cell *p;
  printf("データを入力してください  ==>");
  scanf("%lf", &data);
  p = (struct cell *)malloc(sizeof(struct cell));
  p->num = data; p->next = head;
  head=p;
}

double pop(struct cell *head)
{
  double val;
  struct cell *p, phead;
  head = &phead;
  if (head == NULL) {
  printf("スタックにデータがありません。 \n"); exit(1); }
  val=head->num;
  p=head;
  head=p->next;
  free((void *)p);
return val;
}




No.14053

Re:スタックのpop,とpush関数への質問です。
投稿者---あかま(2004/05/15 19:38:06)


とりあえず、元のプログラムを動くようにしてみました。
大体は出来てました。
headを関数に渡して値を変更するには「ポインタのポインタ」が必要になってややこしいので、グローバルにしました。
そうするとpush,popの引数はいらなくなりますのでこれも消しました。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct cell {
  double num;
  struct cell *next;
};

void push(void);
double pop(void);

struct cell *head=NULL;
  
int main()
{
  double data, val;
  char ans[10];


printf("\n操作を選択してください (push/pop/end) --->");
scanf("%s", ans);


while (strcmp(ans, "e") != 0) {


/* push操作 */
 if(strcmp(ans, "p") == 0) {
  push();
 }

/* pop操作 */
 else  if(strcmp(ans, "o") == 0) {
  printf("popされた値は %f です。\n", pop());
 }


printf("操作を選択してください (push/pop/end) --->");
scanf("%s", ans);
}

printf("プログラムを終了します。\n");
return 0;
}


void push()
{
  struct cell *p;
  double data;
  printf("データを入力してください  ==>");
  scanf("%lf", &data);
  p = (struct cell *)malloc(sizeof(struct cell));
  p->num = data; p->next = head;
  head=p;
}

double pop()
{
  double val;
  struct cell *p, phead;
  if (head == NULL) {
  printf("スタックにデータがありません。 \n"); exit(1); }
  val=head->num;
  p=head;
  head=p->next;
  free((void *)p);
return val;
}




No.14054

Re:スタックのpop,とpush関数への質問です。
投稿者---あかま(2004/05/15 20:01:26)


一応貼っとく「ポインタのポインタ」版。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct cell {
  double num;
  struct cell *next;
};

void push(struct cell ** head);
double pop(struct cell ** head);

int main()
{
  struct cell *head=NULL, p;
  double data, val;
  char ans[10];


printf("\n操作を選択してください (push/pop/end) --->");
scanf("%s", ans);


while (strcmp(ans, "e") != 0) {


/* push操作 */
 if(strcmp(ans, "p") == 0) {
  push(&head);
 }

/* pop操作 */
 else  if(strcmp(ans, "o") == 0) {
  printf("popされた値は %f です。\n", pop(&head));
 }


printf("操作を選択してください (push/pop/end) --->");
scanf("%s", ans);
}

printf("プログラムを終了します。\n");
return 0;
}


void push(struct cell **head)
{
  struct cell *p;
  double data;
  printf("データを入力してください  ==>");
  scanf("%lf", &data);
  p = (struct cell *)malloc(sizeof(struct cell));
  p->num = data; p->next = *head;
  *head=p;
}

double pop(struct cell **head)
{
  double val;
  struct cell *p;
  if (*head == NULL) {
  printf("スタックにデータがありません。 \n"); exit(1); }
  val=(*head)->num;
  p=*head;
  *head=p->next;
  free((void *)p);
return val;
}




No.14055

質問に答えて頂いてどうも有難う御座いました。
投稿者---うぶ(2004/05/15 21:15:33)



あかまさん、ありがとうございます!!
二つもプログラム作っていただいて、今その二つと元のを見比べて
どこが違うのか、ポインタについてもう一度きちんと勉強しています。
ぽこさん、ニタチさん、質問に答えて頂きホントにありがとうございました。



管理者用メニュー    ツリーに戻る    ホームページ    レンタル掲示板サービス