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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

4280閲覧

C++での関数の実行順序がわからない

kokorin

総合スコア73

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/03/30 05:08

編集2019/03/30 05:10

前提・実現したいこと

実行したコードは最下部にあります(不要な行は削除してあります)。

stackで逆ポーランド記法の問題を解くプログラムで、引き算のとき、
例えば入力として 4 3 - が与えられたとして、
push(pop() - pop())push(-(pop() - pop())) の結果が同じで困惑しています。
どちらも1と表示されます。
なぜ、結果が変わらないのか分かりますでしょうか。

該当行を、

c++

1int a = pop(); 2int b = pop(); 3push(b - a);

に置き換えると、意図したとおりに動くので、関数の実行順序が問題になっているものと思われるのですが。。。

c++

1#include <bits/stdc++.h> 2using namespace std; 3 4const int MAX = 101; 5int top = 0; 6int S[MAX]; 7 8void push(int); 9int pop(); 10 11int main() { 12 char s[10]; 13 while (scanf("%s", s) != EOF) { 14 if (s[0] == '-') { 15 16 // 問題の行 17 push(pop() - pop()); 18 19 } else { 20 push(atoi(s)); 21 } 22 } 23 cout << pop() << endl; 24} 25 26void push(int x) { 27 S[++top] = x; 28} 29int pop() { 30 return S[top--]; 31}

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは。

C++では、2項演算子の左右にある値を評価する順序は処理系に任せられています。
左から順番に評価されるとは限りません。
例えば、foo()+bar()のおいて、foo()がbar()より先に実行されることもあれば、bar()がfoo()より先に実行されることもあるという意味です。
'foo() + bar() * baz()`も同様です。foo()、bar()、baz()の実行順序は未定です。それらの結果を演算する順序は演算子の優先順位に従って処理されます。

ですので、副作用のある式(例えば++nなども)とその副作用を受ける項を1つの式に含めるのは禁忌です。

投稿2019/03/30 05:25

編集2019/03/30 05:27
Chironian

総合スコア23272

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

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

kokorin

2019/03/30 06:11

左から評価されるのが当たり前だと思ってたのですが、そうではないんですね。 ありがとうございました!
guest

0

C++では、a() - b()とした場合に、a()b()のどちらが先に実行されるかは決まっていません

特定の順序で実行する必要があるなら、2つのpop()を別な文にする必要があります。

投稿2019/03/30 05:22

maisumakun

総合スコア145183

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

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

maisumakun

2019/03/30 05:25

順番が決まっていないので、最適化で「push(-(pop1() - pop2()))」を「push(pop2() - pop1())」とコンパイラが変えてしまっても構いません。
kokorin

2019/03/30 06:17

コンパイラで変えることも可能なのですね。 いろいろC++では勝手が違って戸惑いますが、ゆっくり勉強していきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問