• ベストアンサー

3ビットのフラグを持つ2個の変数の組み合わせによる分岐の上手な書き方

お世話になります。 C言語において、3つの状態を持っている変数で状態の組み合わせによって分岐するプログラムを作りたいと思っています。 3ビットのフラグによって2進数で001,010,100の3個のどれかの状態であるとして、以下の条件で分岐させるさせたいです。 ・2個とも同じ状態のとき ・片方が001,010で、もう一方が100 ・片方が001で、もう一方が010 自分では以下のように書いたのですが、条件式もっと簡潔に書くことはできないでしょうか?よろしくお願いいたします。 #include<stdio.h> typedef struct{ int name;//識別番号 unsigned int flag:3;//状態を表すフラグ }Status; int main(void) { Status a,b;//例として2変数のみ定義 a.name=10; a.flag=1; b.name=20; b.flag=2; if(!(a.flag^b.flag)){ printf("2個とも同じ状態のとき\n"); } else if( ( (a.flag&1 || a.flag&2) && b.flag&4 ) || ( a.flag&4 && (b.flag&1 || b.flag&2 ) ) ){ printf("片方が001か010で、もう一方が100\n"); } else if( (a.flag&1 && b.flag&2) || (a.flag&2 && b.flag&1) ){ printf("片方が001で、もう一方が010\n"); } }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

すいません。間違えました。 flg = a.flg | b.flg; if(a.flg == b.flg){ printf("2個とも同じ状態のとき\n"); } else if(flg > 4){ printf("片方が001か010で、もう一方が100\n"); } else if(flg == 3){ printf("片方が001で、もう一方が010\n"); } でした。

その他の回答 (6)

  • ddnp009
  • ベストアンサー率25% (15/58)
回答No.7

簡潔に書くなら if ( a ^ b ){  if ( ( a | b ) >> 2 ){   /* 3ビット目が立っている → 少なくとも片方が100 */  } else {   /* 010, 001 */  } } else {  /* 同じ */ } '値'ではなく、『'ビット'に注目している』ことをソースで表現。 従って、数値と比較したり、switch~caseによる分岐がずらずら続くようなのは避けたいところ。

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.6

switch 文を使うという手もあります。状態が増えても減ってもすぐに対応できます。 int flag = ( a.flag << 3 ) | b.flag; if( a.flag == b.flag ) { printf("2個とも同じ状態のとき?n"); } else { switch( flag ) { case 014: case 024: case 041: case 042: printf("片方が001か010で、もう一方が100?n"); break; case 012: case 021: printf("片方が001で、もう一方が010?n"); break; default: printf("???????????n"); break; } ]

回答No.4

a.flgとb.flgは、001,010,100しかないんですよね?101とか110とかにはならないんですよね。 とすれば&を使う必要は無いと思います。 flg = a.flg | b.flg; if(a.flg == b.flg){ printf("2個とも同じ状態のとき\n"); } else if(flg > 4){ printf("片方が001か010で、もう一方が100\n"); } else if(flg == 2){ printf("片方が001で、もう一方が010\n"); } 一度flgにまとめて入れてしまえば何度も計算しなくてすみますし、文字数も少なくなると思います。

回答No.3

orz ボロボロだ。 重ね重ねすみません。 2つ目のほうも記述にミスが・・・。 else if( (a.flag&1 && b.flag&2) || (a.flag&2 && b.flag&1) ){  ↓ if( (a.flag|b.flag) = 0x03 ) でオネガイシマス。 > 1つのデバッグは3つのバグを産む・・・誰の言葉だったろう。

回答No.2

すみません、1個目のほうの最初の式で = が抜けちゃってますね。 else if( ( (a.flag&1 || a.flag&2) && b.flag&4 ) || ( a.flag&4 && (b.flag&1 || b.flag&2 ) ) ){  ↓ if( (a.flag^b.flag) >= 0x05 ) で。

回答No.1

if(!(a.flag^b.flag)){ は、自分もこうするかと。 else if( ( (a.flag&1 || a.flag&2) && b.flag&4 ) || ( a.flag&4 && (b.flag&1 || b.flag&2 ) ) ){ は・・・ふむ。 if( (a.flag^b.flag) > 0x05 ) else if( (a.flag&1 && b.flag&2) || (a.flag&2 && b.flag&1) ){ は・・・ if( (a.flag|b.flag) = 0x03 ) で実装出来るかな。  if( (a.flag^b.flag) >= 0x05 ) 001^001 = 000 ( 0x00 ) × 001^010 = 011 ( 0x03 ) × 001^100 = 101 ( 0x05 ) ○ 010^010 = 000 ( 0x00 ) × 010^100 = 110 ( 0x06 ) ○ 100^100 = 000 ( 0x00 ) × if( (a.flag|b.flag) > 0x03 ) 001|001 = 010 ( 0x00 ) × 001|010 = 011 ( 0x03 ) ○ 001|100 = 101 ( 0x05 ) × 010|010 = 100 ( 0x04 ) × 010|100 = 110 ( 0x06 ) × 100|100 = 1000 ( 0x08 ) × 結構適当ですが。