スタック操作について

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

スタック操作について

#1

投稿記事 by のの » 8年前

スタックにデータを入力する時は`i'を入力し数値を入力するスタックからデータをひとつ取り出す場合は`o'を入力し、入力の終了をする時は`e'を入力するとでプログラムが終了し、スタックの内容を表示する場合は`s'を入力するプログラムを作成する時main内はどう書いた良いのでしょうか。

コード:

 #include<stdio.h>
#define stack_size 100

int stack[stack_size];
int sp;

void init_stack(){
  sp=-1;
}

int push(int x){
  if(sp<stack_size-1){
    stack[sp++] = x;
    return 0;
  }
  else{
    puts("スタックが上限に達しているので実行できません。");
    return(-1);
  }
}

int pop(void){
  if(sp>-1){
    return stack[sp--];
  }
  else{
    puts("スタック内が空なので数値を取り出せません。");
    return(-1);
  }
}

void show_stack(){
  int i;
  printf("stack [");
  for (i = -1; i < sp;i++){
    printf("%2d",stack[i]);
  }
  printf("]\n");
}

int main(){
}

box
記事: 2002
登録日時: 14年前

Re: スタック操作について

#2

投稿記事 by box » 8年前

main関数の話の前に、素朴な疑問があります。
のの さんが書きました:

コード:

void init_stack(){
  sp=-1;
}
スタックポインターの初期値が-1のときに
のの さんが書きました:

コード:

int push(int x){
  if(sp<stack_size-1){
    stack[sp++] = x;
pushを行なうと、おかしなことにならないでしょうか。stack[-1]に値を代入しようとしているように見えて仕方がありません。
てか、この手の問題においてはスタックポインターの初期値はゼロ一択であるように思っています。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

C6b14

Re: スタック操作について

#3

投稿記事 by C6b14 » 8年前

その通りだとおもいます。0を起点にしないとおかしいとおもいます。このプログラムは手直しがいりました。”多分間違いはまだある”とおもいますが自分が考えたのはこの様なものです。

コード:

#include<stdio.h>
#define stack_size 100

int stack[stack_size];//スタックメモリー100レジスタ分
int sp;//スタックポインター

void init_stack() {//NULLポインター
	sp = -1;
}
int push(int x) {//プッシュ
	if (sp<stack_size - 1) {//スタックに余裕があれば
		sp++;//スタックポインターの位置を1個進める
		stack[sp] = x;//その位置にプッシュ実行
		return 0;
	}
	else {
		puts("スタックが上限に達しているので実行できません。");
		return(-1);
	}
}
int pop(void) {//ポップ
	int z;
	if (sp>-1) {//NULLポイインターより大きいなら
		z = stack[sp];
		sp--;////スタックポインターの位置を1個戻す
		return z;// ポップ実行
	}
	else {
		puts("スタック内が空なので数値を取り出せません。");
		return(-1);
	}
}
void show_stack() {//スタックを表示
	int i;
	printf("stack [");
	for (i = 0; i < (sp+1); i++) {
		printf("%2d", stack[i]);//スタックポインターの位置までのデータ
	}
	printf("]\n");
}
int main() {
	char c; int y; int ret; init_stack();
	while (1) {
		c=getchar();
		switch (c) {//分岐
		case 'i'://input
			scanf("%d", &y);//数値入力
			push(y);
			break;
		case 'o'://output
			printf("pop=%d\n", pop());
			break;
		case 'e'://exit
			return 0;// exit(0);
			break;
		case 's'://show stack
			show_stack();
			break;
		}
	}
}

C6b14

Re: スタック操作について

#4

投稿記事 by C6b14 » 8年前

[お詫びと訂正]JavaScriptのコードを見ていて”例えば、++aなら、a = a + 1 を評価し、式の返す値は a+1 になります。しかし、a++ では、a = a + 1 を評価しますが、式の返す値は a になるんです。〝という文をみて自分の間違いに気付きました。この部分(POP)については質問者さんのコードが正しく動くのを確認いたしました。訂正してお詫び申し上げます。

コード:

#include<stdio.h>
#define stack_size 100
 
int stack[stack_size];//スタックメモリー100レジスタ分
int sp;//スタックポインター
 
void init_stack() {//NULLポインター
    sp = -1;
}
int push(int x) {//プッシュ
    if (sp<stack_size - 1) {//スタックに余裕があれば
        sp++;//スタックポインターの位置を1個進める
        stack[sp] = x;//その位置にプッシュ実行
        return 0;
    }
    else {
        puts("スタックが上限に達しているので実行できません。");
        return(-1);
    }
}
int pop(void) {//ポップ
    //int z;
    if (sp>-1) {//NULLポイインターより大きいなら
        //z = stack[sp];
        //sp--;////スタックポインターの位置を1個戻す
        return stack[sp--];//z;// ポップ実行
    }
    else {
        puts("スタック内が空なので数値を取り出せません。");
        return(-1);
    }
}
void show_stack() {//スタックを表示
    int i;
    printf("stack [");
    for (i = 0; i < (sp+1); i++) {
        printf("%2d", stack[i]);//スタックポインターの位置までのデータ
    }
    printf("]\n");
}
int main() {
    char c; int y; init_stack();
    while (1) {
        c=getchar();
        switch (c) {//分岐
        case 'i'://input
            scanf("%d", &y);//数値入力
            push(y);
            break;
        case 'o'://output
            printf("pop=%d\n", pop());
            break;
        case 'e'://exit
            return 0;// exit(0);
            break;
        case 's'://show stack
            show_stack();
            break;
        }
    }
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: スタック操作について

#5

投稿記事 by みけCAT » 8年前

C6b14 さんが書きました:例えば、++aなら、a = a + 1 を評価し、式の返す値は a+1 になります。しかし、a++ では、a = a + 1 を評価しますが、式の返す値は a になるんです。
この性質を用いると、

コード:

sp++;
stack[sp] = x;

コード:

stack[++sp] = x;
と書けますね。
もちろん2文にしても間違いではないでしょうが。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

C6b14

Re: スタック操作について

#6

投稿記事 by C6b14 » 8年前

あ、その通りですね。大変申し訳ございません。再度お詫び申し上げます。

C6b14

Re: スタック操作について

#7

投稿記事 by C6b14 » 8年前

[訂正版]動作確認致しました。

コード:

#include<stdio.h>
#define stack_size 100
 
int stack[stack_size];//スタックメモリー100レジスタ分
int sp;//スタックポインター
 
void init_stack() {//NULLポインター
    sp = -1;
}
int push(int x) {//プッシュ
    if (sp<stack_size - 1) {//スタックに余裕があれば
              //スタックポインターの位置を1個進める
        stack[++sp] = x;//その位置にプッシュ実行
        return 0;
    }
    else {
        puts("スタックが上限に達しているので実行できません。");
        return(-1);
    }
}
int pop(void) {//ポップ
    if (sp>-1) {//NULLポイインターより大きいなら
                    //スタックポインターの位置を1個戻す
        return stack[sp--]; // ポップ実行
    }
    else {
        puts("スタック内が空なので数値を取り出せません。");
        return(-1);
    }
}
void show_stack() {//スタックを表示
    int i;
    printf("stack [");
    for (i = 0; i < (sp+1); i++) {
        printf("%2d", stack[i]);//スタックポインターの位置までのデータ
    }
    printf("]\n");
}
int main() {
    char c; int y; init_stack();
    while (1) {
        c=getchar();
        switch (c) {//分岐
        case 'i'://input
            scanf("%d", &y);//数値入力
            push(y);
            break;
        case 'o'://output
            printf("pop=%d\n", pop());
            break;
        case 'e'://exit
            return 0;// exit(0);
            break;
        case 's'://show stack
            show_stack();
            break;
        }
    }
}

anynone3

Re: スタック操作について

#8

投稿記事 by anynone3 » 8年前

バブル世代の能無しがさっさと消えてしまえばいい

C6b14

Re: スタック操作について

#9

投稿記事 by C6b14 » 8年前

C言語はポインターで悩む事が多いhttp://program-lecture.info/c_pointer1.htmlので超初心者向けサイトがたくさんありますよ。この話はややこしくて分からなくても当分は支障ないでしょう。

anynone4

Re: スタック操作について

#10

投稿記事 by anynone4 » 8年前

消えたら。見つかったら酷いよ。
ここはあんたよりオカシイ奴等ばかりだから。

閉鎖

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