プロが教える店舗&オフィスのセキュリティ対策術

C言語の問題でビット列を表示するプログラムが全くできません。
どなたか分かる人はどうか知恵を貸してください。

ユーザが整数を入力すると、その整数をINT型の変数に入れ、そのビット列を表示するプログラム。
ただ、INT型のビット数は環境によって変わる可能性があるため、sizeof()関数を利用してINT型の変数のビット数を求め、そのビット数分だけ表示する。

A 回答 (7件)

sizeof()関数は、sizeof()演算子ですね。



ループで、1ビットを論理積評価して結果を逆順に表示するのが
簡単ですが、一例として以下も参考にしてみて下さい。

<リスト>
#include <stdio.h>

int main()
{
int i; … 1
unsigned int mask=0x80<<(8*(sizeof(i)-1)); … 2

printf("数値?"); … 3
scanf("%d",&i); … 4
do printf("%1d",i&mask?1:0); while (mask>>=1); … 5
printf("\n"); … 6
return 0; … 7
}

<説明>
1.int 型の変数宣言
2.1オクテット(最小バイトビット数が8ビット)
での最上位ビットを算出する。
つまり、
1オクテット(固定8ビット)の最上位ビットの 0x80 を
(バイトサイズ - 1)× 8 回
左シフトすれば良いわけです。
※2によりビットマスクが算出できます。
3、4.整数入力
5.ビットマスクを最上位から最下位までずらしてそれぞれの
入力整数値とビットマスクの論理積が 0 であれば目的ビットは 0、
論理積が 0以外 であれば目的ビットは 1 と出力します。

たとえば、
int : 2バイト
入力整数値(10進数):32768(16進で 0xF0F0)
(2進で 11110000 11110000)の時、
ビットマスク = 0x80 を (sizeof(int) - 1) * 8 回分、左シフト
= 0x80 を(2 - 1) * 8 回分、左シフト
= 0x8000 (2進で、10000000 00000000)
1回目:11110000 11110000 & 10000000 00000000 = 10000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:1)
ビットマスクを右にずらすので、mask = 01000000 00000000
2回目:11110000 11110000 & 01000000 00000000 = 01000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:11)
ビットマスクを右にずらすので、mask = 00100000 00000000


16回目:11110000 11110000 & 00000000 00000001 = 00000000 00000000
… 10進数で 0 なので「0」を表示(表示結果:11110000 11110000)
ビットマスクを右にずらすので、mask = 0000000 00000000
ループはマスクが 0 になったら抜けるので終了です
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
参考にさせてもらいますね。

お礼日時:2007/09/28 23:43

> sizeof()関数を利用してINT型の変数のビット数を求め



sizeof()関数というのはsizeof演算子のことだとして...

sizeof演算子で知ることができるのは、型が占有する記憶域のバイト数だけです。その中には詰め物ビットが含まれている可能性があるため、単に sizeof(INT) * CHAR_BIT とするだけでは有効ビット数を求めることはできません。
ただし、処理系を特定できるのであれば、この限りではありません。
    • good
    • 0

★訂正。


・printf関数をputchar関数にして下さい。
 あるいは文字定数の '1'や'0' を文字列定数の "1"や"0" にして下さい。
    • good
    • 0

★アドバイス


・このような問題は次のステップで行います。
 (1)INT型のビット数を数える
 (2)数えたビット数から最上位ビットを作成
 (3)最上位ビットより下位へ向かって論理積で0、1を表示
 (4)最下位ビットになるまで繰り返す
 このような感じで行えば良いです。
 ビット演算(論理和、論理積、シフト演算)を使います。
 ビット演算については次のサイトを参考にして下さい。
 http://www9.plala.or.jp/sgwr-t/c/sec14.html
 http://www.geocities.jp/ky_webid/c/049.html
 http://www1.cts.ne.jp/~clab/Contents/Bitindex.html

サンプル:
// INT 型のビット数を数える
int IntBitCount( void )
{
 static const int table[] = {
  0 + 0 + 0 + 0,
  0 + 0 + 0 + 1,
  0 + 0 + 1 + 0,
  0 + 0 + 1 + 1,
  0 + 1 + 0 + 0,
  0 + 1 + 0 + 1,
  0 + 1 + 1 + 0,
  0 + 1 + 1 + 1,
  1 + 0 + 0 + 0,
  1 + 0 + 0 + 1,
  1 + 0 + 1 + 0,
  1 + 0 + 1 + 1,
  1 + 1 + 0 + 0,
  1 + 1 + 0 + 1,
  1 + 1 + 1 + 0,
  1 + 1 + 1 + 1,
 };
 static int count = 0;
 
 if ( count == 0 ){
  INT mask;
  
  for ( mask = ~((INT)0) ; mask != 0 ; mask >>= 4 ){
   count += table[ mask & 0xF ];
  }
 }
 return count;
}
// INT 型のビット列を表示
void PrintBit( INT value )
{
 INT msb = ((INT)1 << (IntBitCount() - 1)); // 最上位ビット
 
 for ( ; msb != 0 ; msb >>= 1 ){
  printf( (value & msb) ? '1' : '0' );
 }
}

その他:
・sizeof演算子を使うということは1バイトを8ビットとして計算することになりますね。
 コンピュータ(環境)によっては1バイトが9ビットだったり、long型が36ビットだったりします。
 INT型も int 型と同じ意味合いで再定義されているとは限りません。多分。
 なので 1 に INT をキャストして最上位ビットを作ったり、ビットを数えています。
 その他はいろいろと工夫して下さい。
・以上。

参考URL:http://www9.plala.or.jp/sgwr-t/c/sec14.html
    • good
    • 0

No.3 です。


入力整数値(10進数):32768(16進で 0xF0F0)
の 32768 は、61680 です。
    • good
    • 0

void hoge(unsigned int x)


{
unsigned int i;
for( i=1<<(sizeof(int)*8-1); i; i>>=1 ){
printf( (x&i) ? "1" : "0" );
}
printf("\n");
}
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
参考にさせてもらいますね。

お礼日時:2007/09/28 23:41

(x >> i) & 1


で x の i ビット目がわかる (シフト演算子などの動作をよく考えればわかる) ので, これを「上位ビットから順に」表示すればいい... のかなぁ?
しかし「sizeof() 関数」って.... そんなのどこにあったっけ?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!