質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

1回答

438閲覧

スタックをうまく動かす

kakakaaka

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/11/11 10:36

編集2022/01/12 10:55
#include <stdio.h> #include <string.h> #define MAX 100 int stack[MAX]; //stackは配列を利用して実現 int top = 0; //stackは最上部(データ実際に格納する場所) int push(int x); int pop(); //配列を利移用して、スタックデータ構造を実現する // push : データの格納 int push(int x){ if(top == MAX) return -1; //満杯なら-1をエラーとして返す stack[top] = x; //データの格納 top++; //次に格納する位置へtopを移動(1つ増やす) return 1; } //pop : データ取り出し int pop(){ --top; //現在データが格納されているところにtopを移す return stack[top]; //最上部のデータを取り出して返す } int main(){ char *p_push = "push"; char *p_pop = "pop"; char input[10]; int su; for(int i=0; i<10; i++){ printf("Input operation: push/pop:"); scanf("%d", input); if(strcmp(input, p_push) == 0){ printf("Input data : "); scanf("%d", &su); push(su); }else if(strcmp(input, p_pop) == 0){ printf("poped data : %d\n",push(su)); }else{ printf("Stack is empty! "); break; } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

入力を判別するサンプルです。

C

1#include <stdio.h> 2#include <string.h> 3 4int main(void) { 5 char *push = "push"; 6 char *pop = "pop"; 7 char input[10]; 8 9 for(int i = 0; i < 10; i++) { 10 scanf("%s", input); 11 12 if(strcmp(input, push) == 0) { 13 printf("push\n"); 14 } 15 else if(strcmp(input, pop) == 0) { 16 printf("pop\n"); 17 } 18 else { 19 printf("other\n"); 20 } 21 } 22}

scanf部分が脆弱ですが、そこに凝るのが課題ではないと思うので...

投稿2017/11/11 10:48

LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakakaaka

2017/11/11 11:25

char *push = "push"; char *pop = "pop"; ここはなにをしているのですか?
LouiS0616

2017/11/11 11:28

文字列"push"の先頭アドレスをポインタ変数pushに代入しています。 次のように書いてもよいです。 char push[] = "push"; char pop[] = "pop";
kakakaaka

2017/11/11 11:30

なぜそのようにするのですか?
LouiS0616

2017/11/11 11:34

『どうしてポインタにする必要があるか』 C言語では、文字列はchar型変数の配列として表現するからです。 『どうしてわざわざ変数に代入しているのか』 strcmpの引数に文字列をそのままどばっと渡してもいいです。 まあそこは設計に依ります。 さて、どっちですかね。
kakakaaka

2017/11/11 11:38

どっちも知りたかったことですね。 ポインタについて聞きたいのですが、ポインタは抽象的で住所に例えると?県?市?丁目のように具体的にではなく?駅から5分みたいにあいまいなもので 計算には使えないと解釈しているのですがおかしいですか?
LouiS0616

2017/11/11 11:41

ポインタはただの数値です。アドレスを示す用途に用いられるだけです。 確かに掛け算とか割り算したり、ポインタ同士で足し引きしたりするような数値ではないですが、関数に放り込んだりするのはいたって一般的な用法です。
kakakaaka

2017/11/11 11:43

a = 1;より *a = 1のほうがデータが少なくなるとかあるんですか?
LouiS0616

2017/11/11 11:46

整数の場合特にないですね。 アドレスをコピーする方がかえって手間がかかることもあります。 ポインタが力を発揮するのは、配列や構造体を取り扱うときです。
LouiS0616

2017/11/11 11:47

あ、あとポインタ渡しのときも効力を発揮します。 この場合は整数を突っ込むことも多々あります。
kakakaaka

2017/11/11 11:50

今の現状を貼りました。 これはポインタについて言われてますか?
LouiS0616

2017/11/11 11:53

基本的に先頭のエラーから潰していきましょう。 main.c: In function 'main': main.c:29:3: error: expected ',' or ';' before 'char' ...char input[10]; ...^~~~ ※空白をドットで代替しています。 さて、これはポインタに関係するでしょうか。びっくりするくらい簡単な理由ですよ。
kakakaaka

2017/11/11 11:55

びっくりするぐらい簡単でした。 ;いれました。
LouiS0616

2017/11/11 11:58 編集

そのとおりです。 まだエラーが出ますが、これは関数名と変数名がかぶっているからです。 ポインタpushなら、p_pushとかstr_pushとかに変えてしまえばよいです。
kakakaaka

2017/11/11 12:12

Input operation: push/pop : push Input data : 8 Input operation: push/pop : pop poped data : 56 Input operation: push/pop : pop poped data : 0 Input operation: push/pop : pop poped data : 0 Input operation: push/pop : 動くのですが何かおかしいです。
LouiS0616

2017/11/11 12:14

gccのWallオプションを有効にすると、次のような警告が出ます。 In function 'main': 37:14: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int *' [-Wformat=] ....scanf("%s", &su);
LouiS0616

2017/11/11 12:14

まあ要するに、単一の整数を受け取るときのscanfの使い方が間違っているからです。
kakakaaka

2017/11/11 12:17

%dに変えろということで間違いないですか?
LouiS0616

2017/11/11 12:18

その通りですが、実行すればわかることにも思います。
kakakaaka

2017/11/11 12:20

それで実行してみたのですが Input operation: push/pop : push Stack is empty! とすぐに打ち切られました
LouiS0616

2017/11/11 12:26

ご提示のコードでは、入力が不正な場合はそのように処理を打ち切るようになっていますね。 ですので、問題は『push』が正しくinputに与えられていないことです。 たぶん改行コードが紛れ込んでいるとか、そういうのだと思うのですが... ただ、私の環境では再現しないのですよね... どのような実行環境でしょうか?
kakakaaka

2017/11/11 12:29

repl.itというサイトですね。
LouiS0616

2017/11/11 12:32

やはり再現しません。OSは何でしょうか?
kakakaaka

2017/11/11 12:33

ありますか? 見つからないですね。
LouiS0616

2017/11/11 12:43

うーん... 私もWin10なんですよねぇ... ウェブブラウザも関係ないでしょうし... 一応もう一度現状のコードを貼っていただけますか?
LouiS0616

2017/11/11 12:52

再現しました。 scanfの書式指定子は、型によって変えなければなりません。 文字列を取得したい場合は%sを、整数値を取得したい場合は%dを指定してください。
LouiS0616

2017/11/11 12:55

あとは、細かなミスが数点ですね。 ・"pop"と入力して分岐した先に、なぜかpushがある。 ・"Stack is empty!"は、おそらくpopするときに出るエラーのはず。 ・poped ⇒ popped 音がはずみますので。
kakakaaka

2017/11/11 14:01

else if(pop(su) == 0){ printf("Stack is empty! "); break; } 付け加えても0が入ってしまいます。 なぜでしょうか?
LouiS0616

2017/11/11 14:10

具体的にどう付け加えたのかわからないです。
kakakaaka

2017/11/11 14:49

if(strcmp(input, p_push) == 0){ printf("Input data : "); scanf("%d", &su); push(su); }else if(strcmp(input, p_pop) == 0){ printf("popped data : %d\n",pop(su)); }else if(pop(su) == 0){ printf("Stack is empty! "); break; }
LouiS0616

2017/11/11 14:51

どのように動作させたいのか明確にした上で、if-else文の使い方を参考書で調べてみてください。 その組み方だとpopと打ち込んで"Stack is empty!"と出てくることは万に一度もありません。
kakakaaka

2017/11/11 14:56

pop(su)が何も持ってないときにpopを打ち込んだら"Stack is empty!"と表示させたいのですが、pop(su)は最初から0を持っているのでpop(su)が0を持っているとき"Stack is empty!"と表示させようと思いました。
LouiS0616

2017/11/11 15:01

}else if(strcmp(input, p_pop) == 0){ printf("popped data : %d\n",pop(su)); }else if(pop(su) == 0){ printf("Stack is empty! "); break; } この二つの処理は『排他関係』にあります。ですので、同時に実行されることはありません。 そもそもelse ifの存在意義が排他処理みたいなものなので... (厳密にはC言語にelse-if文などないが、それはまた別の話)
kakakaaka

2017/11/11 15:04

上にあるのが優先されるのですか?
LouiS0616

2017/11/11 15:09 編集

(コメントが重複してしまいました)
LouiS0616

2017/11/11 15:08

まあ、そうですね。 優先というか、条件合致以後のelse節の条件式は評価されないです。 (※ここでいう『評価されない』とは、良い/悪いという意味ではない。 『実行されない』『参照されない』の方が初心者としてはわかりやすいかもしれない。)
kakakaaka

2017/11/11 15:12

pop(su)はなぜ最初に0を持っているのでしょうか?
kakakaaka

2017/11/11 15:12

pop(su)はなぜ最初に0を持っているのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問