- ベストアンサー
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"); } }
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
すいません。間違えました。 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)
簡潔に書くなら if ( a ^ b ){ if ( ( a | b ) >> 2 ){ /* 3ビット目が立っている → 少なくとも片方が100 */ } else { /* 010, 001 */ } } else { /* 同じ */ } '値'ではなく、『'ビット'に注目している』ことをソースで表現。 従って、数値と比較したり、switch~caseによる分岐がずらずら続くようなのは避けたいところ。
- chirubou
- ベストアンサー率37% (189/502)
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; } ]
- silverbear
- ベストアンサー率25% (163/639)
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にまとめて入れてしまえば何度も計算しなくてすみますし、文字数も少なくなると思います。
- Chronos198
- ベストアンサー率30% (105/349)
orz ボロボロだ。 重ね重ねすみません。 2つ目のほうも記述にミスが・・・。 else if( (a.flag&1 && b.flag&2) || (a.flag&2 && b.flag&1) ){ ↓ if( (a.flag|b.flag) = 0x03 ) でオネガイシマス。 > 1つのデバッグは3つのバグを産む・・・誰の言葉だったろう。
- Chronos198
- ベストアンサー率30% (105/349)
すみません、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 ) で。
- Chronos198
- ベストアンサー率30% (105/349)
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 ) × 結構適当ですが。