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

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

ただいまの
回答率

90.04%

if文でのフラグ分岐の効率化について

解決済

回答 6

投稿

  • 評価
  • クリップ 1
  • VIEW 3,377

GOTOken

score 52

if文での複数のフラグ変数の宣言を無くすには

 bool flg = false;
 bool flg1 = false;
 bool flg2 = false;
 bool flg3 = false;
 bool flg4 = false;

if(!flg) 
 {
     flg = true;
     //アイテム入手後の処理のような
  }
if(!flg1) 
 {
   flg1 = true;
    //要素数に達した時に1回通る
  }
if(!flg2) 
 {
   flg2 = true;
    //要素数に達した時に1回通る
  }
if(!flg3) 
 {
   flg3 = true;
    //要素数に達した時に1回通る
  }
if(!flg4) 
 {
   flg4 = true;
    //要素数に達した時に1回通る
  }


このように無駄の多い宣言をしてしまっているような気がするとともに、管理がしにくいと感じています。
switch文での制御もしていたのですが、それでもこのような変数が必要な場面に多々遭遇してしまいます。
Flg変数を使う場合でも、このように大量に宣言しない書き方をご教授していただけると嬉しいです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

+11

「Flagを効率よく管理する」というのはすでにいくつか案が出ているので、ちょっと別視点で。

ゲームを作る(というかアプリ全般にも言える話ですが)場合、フラグを極力減らす方向で考えたほうがよいです。

そして先人たちは色々な便利な手法を編み出し、それらを「デザインパターン」と呼んでいます。
もしかしたら学ぶにはまだ少し早いかもしれませんが、「フラグ管理大変」という思いが出てきたのであれば、一度調べてみてもいいかもしれません。

今回のフラグがどういった形で使われるかによるので一概にどのパターンがいいか、という話はできないのですが、「状態を管理する」という意味では「ステートパターン」あたりから調べてみるといいと思います。

繰り返しますが、もしかしたら学ぶのには少し早いかもしれません。
なので、むずかしいな、とかどう使うかまったく分からん・・となったら、まずはここで回答されている内容をヒントに(デザインパターンを使わずに)実装してみるのがいいと思います。

個人的に、デザインパターンという単語自体を知らずに苦労していた時期があるので、単語だけでも覚えておいてもらえるといいかなと思って書きました。参考になれば。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

コメントに書いてあるような処理をするなら、
状態を保持するオブジェクトを作って、オブジェクトに聞くのでしょうかね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

個人開発で、明日の自分も上手くやってくれると信じてるぜ!ということなら、
bool[] flags;と配列化。(何番が何のフラグかはコメントに書いたりしておく)
if (flags[3]) { }のように使ったりforで回したり出来ます。
類型でDictionary<string, bool>も一応挙げておきます。
(宣言が減るだけでif文の分岐は減らない可能性が高いですけどね……!)

まぁマジックナンバーやらstringで指定するのはあんまり宜しくないので、「本当にその変数が必要なのか」「本当にその型でいいのか」を考慮した方がいいでしょうね。

例示されている「要素数に達した時に1回通る」のようなケースだと上記の配列で上手く動くかもしれませんが、別案としてboolでなくint変数1つにして「達した要素数を入れておく」でもいいかもしれません(これだとif文1つに出来そう)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

public bool FlagAction(bool flag,Action action)
{
  if(!flag)
  { 
     action();
     flag = true;
  }
  return flag;
}

こういう関数を作って、

flag = FlagAction(flag , ()=>{やりたいこと });

という感じで使うのも一案か。

flag変数が多くて大変なら、クラスor構造体を作ればいいじゃないとしか。

実は、flag変数なんて必要ないのもあるとかいうオチがありそうだけど。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

フラグ変数を
unsigned int flags=0;
で定義しておいて、

flags |=1;    // set
flags &= ~1;  // reset
if((flags & 1)!=0)  // check flag

としておけば、unsigned intなら32個までのフラグ操作ができます
おまけに、flags の数値チェックで、32個のフラグの状態チェックを一括でできますね

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/16 07:30

    そのような使い方なら FlagsAttribute をつけた enum がいいと思います。

    キャンセル

  • 2018/08/16 07:33

    おっしゃるとおりです。

    まあ、タグにC/C++もあったんで、こーゆーふーに。

    キャンセル

  • 2018/08/16 18:46

    というかstd::bitsetありますよね、bit節約したいなら

    キャンセル

0

Flgを減らすには状態遷移図を書いて、管理する状態を整理してみればいいと思います。
またその後に再利用しなくてすむ場合なら以下のように状態をFlgに保存しない方法もあります。

if ((fp = fopen(filename, "w")) == NULL) {
  // ファイルデスクリプタがNULLの場合=ファイルのオープンに失敗した場合
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる