- ベストアンサー
ある変数の任意のビット目の数字を入力したい
変数「A」「B」「C」「D」の四つがあり、各値の状態を変数「I」1~4ビット目に記憶します。 そして変数「A」「B」「C」「D」の値をいったんクリアし。 その後にIの1~4ビット目に記憶されている値を再び「A」「B」「C」「D」に戻す・・・ このようなプログラムはどのように書いたらよいでしょうか? 宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
趣旨が解らないのだが、 変数A~Dはブール変数なのかな? であれば if(A){ I = 1; } else { I = 0; } if(B){ I |= 2; } 戻すのなら if( I & 1){ A = 1; } else { A = 0; } if(I & 2){ B = 1; }else{ B = 0; } の様にすればよいのでは。 A~Dが0,1であれば I = A + B * 2 + C * 4 + d * 8; の様なことも可能 何でCでは出来ないと言っているのか意味不明。
その他の回答 (3)
- maru_yoshi_
- ベストアンサー率39% (17/43)
いろいろ疑問のある質問内容なので、以下が求めているプログラムなのかどうかは不明です。 #include <stdio.h> #include <tchar.h> struct tag_bit_field { int a:1; int b:1; int c:1; int d:1; }; struct tag_bit_field set(int a, int b, int c, int d) { struct tag_bit_field temp; temp.a = a ? 1 : 0; temp.b = b ? 1 : 0; temp.c = c ? 1 : 0; temp.d = d ? 1 : 0; return temp; } void get(struct tag_bit_field x, int* a, int* b, int* c, int* d) { *a = x.a ? 1 : 0; *b = x.b ? 1 : 0; *c = x.c ? 1 : 0; *d = x.d ? 1 : 0; } int main() { struct tag_bit_field I; int A, B, C, D; A = B = C = D = 1; /* 変数A,B,C,Dに値を設定 */ printf("A, B, C, D = %d, %d, %d, %d\n", A, B, C, D); I = set(A, B, C, D);/* A,B,C,DをIに保存 */ A = B = C = D = 0; /* 変数A,B,C,Dをリセット */ printf("A, B, C, D = %d, %d, %d, %d\n", A, B, C, D); get(I, &A, &B, &C, &D);/* IからA,B,C,Dを復元 */ printf("A, B, C, D = %d, %d, %d, %d\n", A, B, C, D); return 0; }
- TT414
- ベストアンサー率18% (72/384)
A = I&1 ? Aが1のときの値 : Aが0の時の値 ; B = I&2 ? Bが1のときの値 : Aが0の時の値 ; C = I&4 ? Cが1のときの値 : Aが0の時の値 ; D = I&8 ? Dが1のときの値 : Aが0の時の値 ; または int I,i,*AD[4]={&A,&B,&C,&D}; for(i=0;i<4;i++) *(AD[i]) = I & 1<<(i+1) ? 0以外のときの値 : 0の時の値 ;
- koumei000
- ベストアンサー率38% (13/34)
お使いのプログラミング言語はc, c++, c#のうちどれですか? 趣旨は少々変わるのですが、cなら不可能ですが、それ以外なら「1バイト目」などにこだわらす素直に構造体かクラスを使うことをお勧めします。 ----------------------------- public class Sample または public struct Sample { public int Condition; public int Value; } ----------------------------- のような具合で。(サンプルなので全てintですが、たとえばConditionは列挙体を用いたほうが良かったりします) もし、どうしても「1バイト目に」をこだわるのであればポインタを使えばよいのではないかと。 まず、4ビットのポインタ(c++なら「char*」、c#なら「byte*」または「sybte*」)を宣言し、 そこへ変数Aのアドレス「&A」をキャストして(c++なら「(char*)&A」、c#なら「(byte*)&A」または「(sbyte*)&A」)を代入します。 ポインタは変数のアドレスを保持するのでこのアドレスを元に変数Aの1バイト目、2バイト目といった具合にアクセスできます。 このとき、c#ではメモリの管理を受けているので、勝手にアドレスが変更されるのを防ぐため「fixed」文を使います。また、c#ではポインタを危険なコードとみなしているため「unsafe」キーワードをメソッドやクラス、構造体の宣言の中に書き込む必要があります。 これで変数Aの1バイト目のアドレスが取得できたので、ここへ必要な値を書き込みます。 たとえばポインタ変数「p」が持っているアドレスに書き込むには「*p =」とします。 読み取る場合も同様に「*p」とすればよいです。 2バイト目にアクセスする場合は「p++;」とします。これでpの値が4増える、つまり4ビット後の場所を参照するようになります。 もし、pが8ビットのポインタなら「p++;」としたときにpの値は8増えます。 ポインタは非常に強力かつ危険なコードです。なぜなら下手をすると本来アクセスしたい範囲外の値を書き換えてしまって重大なエラーにつながる恐れがあるからです。(c#のポインタが貧弱なのはそのため。変わりにrefやoutキーワードがある)
お礼
回答有難うございます。 まだ構造体に対する理解が薄いのが悔しいです。 使用言語は「C」です。 C言語ですと不可能なのですね・・・
お礼
ブール変数です。 多少記述が長くなってしまいますが、理解しやすかったです。 お陰でなんとか思うとおりに動かす事が出来ました。 私の理解不足と、説明不足の中他の方々も回答本当に有難うございました。