• ベストアンサー

ビット列を表示するプログラム

C言語の問題でビット列を表示するプログラムが全くできません。 どなたか分かる人はどうか知恵を貸してください。 ユーザが整数を入力すると、その整数をINT型の変数に入れ、そのビット列を表示するプログラム。 ただ、INT型のビット数は環境によって変わる可能性があるため、sizeof()関数を利用してINT型の変数のビット数を求め、そのビット数分だけ表示する。

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

  • ベストアンサー
noname#50176
noname#50176
回答No.3

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 になったら抜けるので終了です

bad-pc
質問者

お礼

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

その他の回答 (6)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.7

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

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

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

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★アドバイス ・このような問題は次のステップで行います。  (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
noname#50176
noname#50176
回答No.4

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

回答No.2

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"); }

bad-pc
質問者

お礼

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

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

関連するQ&A

  • abcが、入力された文字列内にあるかどうかを表示するプログラム

    文字列strの中にabcが含まれていれば、1を返し、含まれていなければ0を返すプログラムが分かりません。 C言語の問題で下記のものが分かりません。どなたか知恵を貸してください。 ユーザが文字を入力し、CTRL+Zが押されるまで、半角英数字の入力(最大でも1000文字)を受け付ける。文字列「abc」が、入力された文字列内にあるかどうかを表示するプログラムを作成する。ユーザが入力した文字列が3文字未満はabcがありませんと表示させる。 そのプログラム内で以下の関数を完成させる。 int str_srch_abc(char str []) 文字列strの中にabcが含まれていれば、1を返し、含まれていなければ0を返す関数とする。 (例えばabcは連続でabcの時だけ1を返し、asbscなどはoを返します。) ちなみに自分なりにやってみたのですが、ここまでしかできませんでした。 #include<stdio.h> int main() { int str_srch_abc(char str []); char str[1000]; int ch=0, j=0; printf("半角英数字を入力してください"); scanf("%s",str); while((ch=getchar())!=EOF){ str[j]=ch; j++; } str[j]='\0'; printf("%s",str); return(0); }

  • 3つほどプログラムをおしえてください。

    (1)100までの整数をいくつか入力し、10刻みでの個数を表示し、負の数が入力されると整数の入力を終わるプログラムです。各範囲の個数は配列に格納する。 実行結果 65 30 21 95 5 -1 0--- 9 : 1 10--- 19 : 0 20--- 29 : 1 30--- 39 : 1 40--- 49 : 0 50--- 59 : 0 60--- 69 : 1 70--- 79 : 0 80--- 89 : 0 90---100 : 1 (2)数字の文字列を入力し、その文字列に含まれる各数字(文字)'0','1',~'9'の個数を表示するプログラムの作成。 実行結果 1231234567 0: 0 1: 2 2: 2 3: 2 4: 1 5: 1 6: 1 7: 1 8: 0 9: 0 (3) 変数xは、0~1までの0.01刻みの値(101個)を取るとする。このとき、2次関数 f(x)=3x^2+2x+1の値が2.0<f(x)<3.0となるxの値をの個数を求めるプログラムの作成。ただし、xを引数としf(x)の値を返す関数を作成して、それを使用する。 実行結果 number=21 やってるうちにわけがわからなくなってしまいます。どなたかよろしくおねがいします。

  • char型でビット列表示

    char型の変数にビット配列を代入しそれを文字として出力させたいのです。 どこが間違っているのか分かりませんが一応流れを書いたプログラムを載せておきます。 char binary = 0; int i; for(i=0;i<8;i++){ if(省略) binary = binary & 11111110; else binary = binary | 00000001; binary = binary << 1; } printf("実行結果 %c",binary); 実行結果 00110110 というように最下位ビットに0か1を代入し、左シフトをし、というのを繰り返しprintf("%c",binary)でビット列を表示させたいのですが、これを実行すると結果は文字化けしたようなものが表示されます。 charの配列を作ってビット列を表示させるやり方はわかるのですが、学校の課題みたいなもので配列を使ってはいけないみたいなのです。 教科書を読んでも分からないので困っています。 よろしくお願いします。

  • 関数とビット列

    C言語勉強中です。下記本から抜粋したものですが、 関数の流れや、1U、~0Uなどの意味がわかりません。 それぞれ関数の中でどのような処理をしているのでしょうか? scanfで正数入力し、print_bitsにnxを渡し、そこのxを1と&して 2進の0か1を表示させるのはなんとなく解るのですが、PCのCPUの ビット数を確認する為?の動きなどがわかりません。 どうか、解説していただける方、よろしくお願いします。 #include <stdio.h> int count_bits(unsigned x) {     int count = 0;     while (x) {           if (x & 1U) {              count++;           }           x >>= 1;      }      return (count); } int int_bits(void) {      return (count_bits(~0U)); } void print_bits(unsigned x) {      int i;      for (i = int_bits() - 1; i >= 0; i--) {           putchar(((x >> i) & 1U) ? '1' : '0');      } } int main(void) {      unsigned nx;      printf("非負の整数を入力してください:");      scanf("%u", &nx);      print_bits(nx);      putchar('\n');      return (0); }

  • プログラムについてです。

    main関数内でキーボードから入力された2つの整数について、その整数値の和差乗除をユーザ定義関数shisoku()内で計算し、main関数内で結果を出力するプログラムを作成せよ。 ただし、すべて局所変数で構成し、大域変数を使ってはならない。 僕は和差、乗除はできるんですが和差乗除ができません。

  • プログラミングにビットについて

    独学でプログラミングを勉強しているものですが、ビットについてまだ完全に理解できていません。 ビットというのは、メモリだとか、容量だとかという大雑把なことは分かっているのですが 詳しく完全に理解できてるわけではありません。 そこで 今日変数の復習をしていた所 教本の説明の欄の ○○(数字)ビット符号付き整数 みたいなものに疑問をもちまして 例えばintなら32ビット符号付き整数というような説明の形なのですが この場合のintの説明の解釈というのは 二進数で0一つで1ビットを占めているとして 32ビット符号付き整数というのは 二進数で言う+(-)0x31の数値を表現することができ、 なので この場合、+(-)を1ビット占めているので表現できる数字は10進数で言う+(-)2^31-1が限界ということでいいのでしょうか?

  • 分数の足し算をさせるプログラムが分かりません。どなたか分かりませんか?

    分数の足し算をさせるプログラムが分かりません。 C言語の問題で分数の足し算までは一応できるんですが、答えがでたときに整数で出すやり方と約分して表す方法が分かりません。 どなたか知恵を貸してくれませんか? ユーザから4つの整数を入力し、はじめに入力された2個の整数と後に入力された2個の整数を分数と考え、その分数の和を表示するプログラムを作成せよ。 例えば、「3」「4」「5」「6」と入力されたときは、3/4 + 5/6を計算する。 そのプログラム内では分数の和を計算する関数を作成する。 さらに、 約分を行う関数を 再帰呼び出しを利用して作成する。 void yakubun(int *a1, int *a2) 例えば、以下の場合1/2と表示される。 int i=10,j=20; yakubun(&i,&j); printf(“%d / %d”, i, j); ちなみにここまでできました↓ #include<stdio.h> void bunsu_tasizan(int a1,int a2,int b1,int b2, int *c1,int *c2 ) { *c1=(a1*b2)+(b1*a2); *c2=(a2*b2); } int main() { int x1,x2,y1,y2,z1,z2; printf("整数を入力してください"); scanf("%d",&x1); scanf("%d",&x2); scanf("%d",&y1); scanf("%d",&y2); if(x2==0||y2==0||x2==0&&y2==0) printf("0以外を入力してください"); else{ bunsu_tasizan(x1,x2,y1,y2,&z1,&z2); printf("%d/%d",z1,z2);} return (0); }

  • ビット列を走査するプログラムの関数化

    char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。 他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。 (つまり、条件分岐を関数化したものをfor文内で用いたい) うまい方法が思いつかずに困っています。もし良い方法をお気づきの方がおられたらご助力下さい。 //===============================================// //=================以下ソース====================// //===============================================// //ビット配列correct_ciphertextとPbinを比較するプログラム //LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める //Pbinは固定値を与えている #include <stdio.h> #include <string.h> unsigned int mes[2]; unsigned int key[2]; char Pbin[64]; char Kbin[64]; char ciphertext[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; void ConvertPtextToBin_ForHost(unsigned int mes[]){ unsigned int tmp_mes[2] = {mes[0], mes[1]}; int i, j; for(j=0;j<=1;j++){ for(i=0;i<=31;i++){ Pbin[j*32 + 31-i] = tmp_mes[j] % 2; tmp_mes[j] = tmp_mes[j] / 2; } } } int main(int argc, char *argv[]){ //initialize mes[0] = 0x00000000; mes[1] = 0x00000000; int i, j, k; int x=0, y=0; while(1){ printf("mes[1] = %d\n", mes[1]); ConvertPtextToBin_ForHost(mes); for(i=0; i<64; i++){ printf("%d", Pbin[i]); if((i+1)%8 == 0) printf(" "); } printf("\n"); //************************* //ビット走査 //************************* for(k=0; k<64; k++){ if( (ciphertext[63-k] == Pbin[63-k]) ){ //同じビットであれば、次のビットを走査する }else{ printf("Error\n");//後ろから走査していって、1ビットでも違うものがあれば違うビット列と判断する break; } } //ここに来たら違うビット列だったということ if(k != 64){ mes[1]++; printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", k); printf("This was %d*%dth Search...\n\n", y, x); x++; if(x>=65535){i=0; y++;} }else{ //k=64つまり、最後のビットまで同じビットだったということ⇒つまり、「発見」 printf("Match ciphertext\n"); printf("This was %d*%dth Search...\n\n", y, x); break; } //*********************** //ビット走査の終了 //*********************** } }

  • プログラムの組み方が分かりません。

    ある課題で以下の問題が出題されました。 >>>> 2つのint型変数x,yにキーボードから値を入力し、その大小を判定する関数funcを作成せよ。この課題では、大きいと判定された数が代入された変数のアドレスがmain関数に戻されるものとする。 ============ #include<stdio.h> int *func(int *a,int *b) { /* 2つの値の大小判定を行い、アドレスを返す */ } main(void) { int x, y, *z; /* 変数 x,yにキーボードからデータを入力する */ /* 関数funcの呼び出し */ /* 変数zを用いて値の出力を行う */ } ============ <<<< 2行目の*funcというように、関数の頭に*が付くプログラムは初めてで、 どういう意味かもさっぱりわかりません。 それも含め、この問題はどういう風解けばいいのか、教えてください。 お願いします。

  • 文字列から整数導き出したい

    お世話になります。 現在、簡易的な占いのプログラムを作ってみています。 フォームに入力された文字から占いの結果を表示するようなものを 作りたいのですが、中々うまくいきません。 仕組み的にはフォームから文字列をPOST⇒10進数の整数に変換⇒10進数の整数に対応する占い結果を表示という形を考えています。 文字列をbin2hex関数で16進数にはできるのですが、16進数から10進数変換する方法がわかりません。 何かより方法がありましたらご教授ください。

    • ベストアンサー
    • PHP

専門家に質問してみよう