ページ 11

スタック操作について

Posted: 2016年12月11日(日) 14:48
by のの
スタックにデータを入力する時は`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(){
}

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

Posted: 2016年12月11日(日) 15:04
by box
main関数の話の前に、素朴な疑問があります。
のの さんが書きました:

コード:

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

コード:

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

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

Posted: 2016年12月11日(日) 18:54
by C6b14
その通りだとおもいます。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;
		}
	}
}

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

Posted: 2016年12月14日(水) 22:55
by C6b14
[お詫びと訂正]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;
        }
    }
}

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

Posted: 2016年12月14日(水) 23:22
by みけCAT
C6b14 さんが書きました:例えば、++aなら、a = a + 1 を評価し、式の返す値は a+1 になります。しかし、a++ では、a = a + 1 を評価しますが、式の返す値は a になるんです。
この性質を用いると、

コード:

sp++;
stack[sp] = x;

コード:

stack[++sp] = x;
と書けますね。
もちろん2文にしても間違いではないでしょうが。

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

Posted: 2016年12月14日(水) 23:34
by C6b14
あ、その通りですね。大変申し訳ございません。再度お詫び申し上げます。

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

Posted: 2016年12月15日(木) 00:19
by C6b14
[訂正版]動作確認致しました。

コード:

#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;
        }
    }
}

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

Posted: 2016年12月15日(木) 06:42
by anynone3
バブル世代の能無しがさっさと消えてしまえばいい

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

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

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

Posted: 2016年12月15日(木) 11:24
by anynone4
消えたら。見つかったら酷いよ。
ここはあんたよりオカシイ奴等ばかりだから。