• ベストアンサー

困っています

どうしても、--unsigned型のビット内容表示--の所が意味が分かりません。分かりやすく教えてください。宜しくお願いします。 /* 0~UINT_MAXを2進・8進・16進で表示 */ #include <stdio.h> #include <limits.h> /*--- 整数xのセットされたビット数を返す ---*/ int count_bits(unsigned x) { int count =0; while (x) { if (x & 1u) count++; x>>=1; } return (count); } /*---- unsigned型のビット数を返す ----*/ int int_bits(void) { return (count_bits(~0U)); } /*---- unsigned型のビットを内容を表示 ---*/ 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 i; for (i=0; i<UINT_MAX; i++) { print_bits(i); printf(" %6o %5u %4X\n", i, i, i); } return(0); }

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

  • ベストアンサー
  • lawson
  • ベストアンサー率44% (29/65)
回答No.7

############################################### No5さんへ、 >putchar(((x>>i) & 1U) ? '1' : '0'); どう考えても、 putchar((x>>i) & 1U); でいいと思うのだが? 間違っている?僕。 http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html を見てください。 putchar( にint型の1を与えると、SOHを出力するという意味になりませんか? putchar( にint型の0を与えると、NULLを出力するという意味になりませんか? 文字の1,0をpuchar(に与えるためには、 0x31 や 0x30 を与える必要がありますね。 文字定数 '1'は0x31と同じ意味です。 文字定数 '0'は0x30と同じ意味です。 なので、こうなります。 putchar(((x>>i) & 1U) ? '1' : '0'); ############################################### #####################################333 質問者さんへ >int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) その通りですが。 もう一度、聞きますが・・。 シフト演算子の挙動は知ってますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? それがわかってれば、わかるはずですが・・・。 >print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。 0000------0000001とビットごとの論理積をとって、上位ビットから(左側のビット)pucharで出力したいから。 int_bits() -1の-1が必要なのは、 Nビットある情報についてN-1ビット目から0ビット目まで処理したいからです。 例えば、 3ビットある情報は、 0ビット目、1ビット目、2ビット目の3ビットだとします。 int_bits()自体が3を返すなら、 int_bits()-1をループカウンターの初期値とすれば 2,1,0という変化で、ループ処理できます。 2ビット分シフトすると、0ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 1ビット分シフトすると、1ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 0ビット分シフトすると、2ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 もう一度聞きますが。 3項演算子の挙動は知ってますか? シフト演算子の挙動は知ってますか? C言語の式の評価値は非ゼロを真と見なすことを 知ってますか? ~0Uなどの補数演算子の~は理解しますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? No5さんぐらいの明確な質問があると回答しやすいのですが・・・。 ###############################################

その他の回答 (7)

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.8

> print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。  では、このforが何回ループするか、その間のiの値は何かを考えてみようか。ここではunsigned intは16ビットとする。 for (i=int_bits() -1; i>=0; i--) すなわち for (i=16 -1; i>=0; i--) すなわち for (i=15; i>=0; i--) iの値は、15から0まで変化する。16回ループする訳だ。次に、ループ内の(x>>i)を考える。 i=15の時(x>>i)はxを15回ビットシフトしたもの、つまり最上位ビットが最下位ビットの位置に来る i=14の時(x>>i)はxを14回ビットシフトしたもの、上から2ビット目が最下位ビットの位置に来る ・・・ i=1の時(x>>i)はxを1回ビットシフトしたもの、下から2ビット目が最下位ビットの位置に来る i=0の時(x>>i)はxを0回ビットシフトした、つまりビットシフトを行わないので、最下位ビットが最下位ビットの位置 以上から、iの値をシフトするビット数として使うので同じint_bits回ループするのでも for (i = 0; i < int_bits(); i++) ではいけないし for (i = int_bits(); i > 0; i--) でもいけないのが分かってもらえるかと思う。この辺が「このおっさん何を言いよるんやろ」となってしまうなら、今までの回答者が言う通りもう少しC言語の基礎を学ぶ方が良いのではないかな。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.6

>int_bits()の関数は、結局、何ビットあるか数えているということですか? unsignedのビット数を数えています。 >print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません あとのシフトする数に使っているからですね。 例えば5ビットのデータで 5ビット右シフトしたらなくなっちゃいますよね 10000 5ビットのデータビットサイズは、5 01000 1ビット右(無符号で)シフト 00100 … 00001 4ビットシフト(ここでビットがあるかどうか調べる)

  • nk2
  • ベストアンサー率23% (6/26)
回答No.5

putchar(((x>>i) & 1U) ? '1' : '0'); どう考えても、 putchar((x>>i) & 1U); でいいと思うのだが? 間違っている?僕。 unsigned intは通常32bitsです。 int_bits()が32返すとすると、 x = 1111111111111111111111111111101 i = 1 のとき、 x >> i より x = 0111111111111111111111111111110 になります。 1Uは0000000000000000000000000000001 を示していますので、 0111111111111111111111111111110 & 0000000000000000000000000000001 は0ですよね?

jjjj27
質問者

補足

int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

最上位のビットからビットの位置に合わせて右シフトして1か0を判定して文字'1'か'0'を標準出力に出力する

  • lawson
  • ベストアンサー率44% (29/65)
回答No.3

####################################### No2さんのsizeofを使わない理由が参考になりました。 どうして、こんな回りくどい方法を・・・ と思ってました。 おもしろい発見をしました。 ####################################### えーっと。本題に入りますが・・・。 なにがわからないのか明確にしたほうがいいですよぉー。 例えば、 3項演算子の挙動は知ってますか? シフト演算子の挙動は知ってますか? C言語の式の評価値は非ゼロを真と見なすことを 知ってますか? ~0Uなどの補数演算子の~は理解しますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? 「--unsigned型のビット内容表示--の所が意味が分かりません」 とありますが。 意味がわからないものが本質的にどれであるかを よく考えて、明確に質問しないと期待通りの 回答を得ることは難しいです。 「意味がわからないものが本質的にどれであるかを よく考えて、明確に質問する」 能力がないのであれば、基礎からやり直したほうが よいでしょう。 以上。

jjjj27
質問者

補足

int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.2

 #1です。  先ほど、sizeofを使わない理由を置いておいてしまったが、投稿直後に思い出した事がある。それは、「世の中にはcharが8ビットじゃないマシンもある」という事だ。  とある国のコンピュータで、charが9ビット、short、int、longが全て36ビットというマシンがある。sizeof(unsigned int)×8ではこのマシンには対応できないね。  そういう意味なのかも知れない。

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

 解説しづらいなぁ。  count_bits()は、「unsigned int型の、(引数で指定された)とある数値で1になっているビットの数」を返す。これは良いかな?  int_bits()は、「unsigned int型で0の反転」すなわち「unsigned int型で全て1になっているもの」を引数にcount_bits()を呼び出す。結果として「unsigned int型のbit数」を返すわけだ。  「え? そんな事しなくてもsizeofを使えば良いんじゃないの?」と思うかも知れないが、思うかもしれないが・・・・う~ん、私もそう思う。sizeofはコンパイル時にサイズを「定数として」コードに埋め込むが、上記のint_bitsだってコンパイル時に大きさを決定するしねぇ・・・・。  まぁ、とりあえず置いとこう。  それを踏まえて、 void print_bits(unsigned x)  /* 引数で指定された、とある値 */ { int i; for (i=int_bits() -1; i>=0; i--)  /* 正確にunsigned intのビット数だけループ */ putchar(((x>>i) & 1U) ? '1' : '0');  /* xの、ループ内の指定ビットが立っているなら1を、立っていなければ0を画面に出力 */ } 後はmain()でこいつを0からUINT_MAXまで繰り返している訳だ。 これで分かってもらえたかどうか不安なので、また質問を投げていただければ・・・・。

jjjj27
質問者

補足

int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。 

関連するQ&A

  • 関数とビット列

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

  • ビット構成について

    今、ビットについて勉強しているのですが、わからないところがありますので、質問しました。わかる方がいれば、わかりやすく教えてください。(例として、整数xは10とした場合をしてもらえる助かります。) 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 count_bits(unsigned x){ int count = 0; while (x){ if (x & 1U) count++; x >>= 1; } return (count); } についてですが、整数Xを10とした場合、私の考えではcount=2となると思うのですが・・・。 次に int int_bits(void){ return (count_bits(~0U)); } についてなのですが、count_bits関数で整数Xを10とした場合count=2となったあと、int_bits関数では全ビットを1にするということみたいですが、count_bits関数でおこなった作業をどうint_bits関数で処理するのかわかりません。 最後が for文の中の、(i = int_bits() - 1 ; i >= 0; i--) についてですが、整数10のときの i = int_bits() はどうなっているのでしょうか?? わかりにくい質問ですみません。 回答宜しくお願いします。

  • unsigned型のビット構成を表示するプログラムが理解できません。

    unsigned型ビット構成の表示プログラム #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); } このプログラムで10を入力したら、00000000000000000000000000000001010と表示され。 18だと00000000000000000000000000000010010と表示される原理が理解できません。 自分なりにプログラムを追ってこういう考えてます。 まず、10を入力したらcount_bitsの関数の処理からスタート。 while(x){ if(x&1U)count++; x>>=1; if(x&1U)の処理を行い。x=10はbit単位表示で、1010として考え。一番右側の101「0」とunsigned型の1との論理比較を行う。0と1なので偽で何もせずにif文を抜けて、x>>=1;を行いx=0101となり。while(x)から再びif(x&1U)行う。x=0101の一番右側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=1としてif文を抜け、x>>=1;を行いX=0010になり。三度目のif(x&1U)の処理を行う。0010の一番左側のunsigned型の1との論理比較を行い0と1なので偽でif文を終了。x>>=1;を行い0001となり、再びif(x&1U)行う。 00 01の一番左側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=2となり、x>>=1;を行い0000なのでwhile(x)を抜けて返り値2をint_bitsへ返して関数は終了 int_bitsではunsinged型の2が戻り値としてprint_bitsへ返し、int_bitsの関数は終了。 print_bitsの処理が始まり。for(i=int_bits()-1;i>=0;i--)の処理がスタート。 i=int_bits()-1の処理でiは2-1でi=1からスタート。 putchar(((x>>i)&1U)?'1':'0');の処理。 (x>>i)でx=10,i=1なので1010>>1だから0101。 0101の一番右側の1とunsigned型の1と論理比較を行う 真なのでputcharは'1'を一度表示。 for文に戻りiをデクリメントとしてi=0なのi>=0から 一度、putchar(((x>>i)&1U)?'1':'0');処理。 (x>>i)は0101>>0の0右シフト行い0101。 unsignedと1を0101の一番右側の1と論理比較を行う 真なのでputcharは'1'を一度表示。 for文に戻りiをデクリメントとしてi=-1なのでi>=0からfor文を終了してprint_bitsの処理を終了。mainの関数処理に戻り。putchar('\n');を出力して関数処理は終了。表示として「11」が表示される。18も同様に考えているので、「11」が表示されてしまうのでは?という考えに陥ってます。実際は、両方とも正しくunsigned型ビット構成の表示されるので、自分の考え方が間違えている。なのですが、どう間違えているかがわかりません。 多少説明文の省略しているためわかりにくいかもしれませんが、間違えを指摘していただけないでしょうか?

  • c言語による2のべき乗

    右、左シフトと2のべき乗による乗除算が同じことを証明するプログラムを作っているのですがうまくいきません。 プログラムを載せるのでどこが間違っているのかご教授お願いします。 #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, no, n1, n2; printf("非負の整数を入力してください:"); scanf("%u", &nx); printf("何ビットシフトしますか?:"); scanf("%u", &no); n1=nx * (2^no); n2=nx / (2^no); printf("\n整数 = "); print_bits(nx); printf("\n左にシフトした値 = "); print_bits(nx << no); printf("\n右にシフトした値 = "); print_bits(nx >> no); printf("\n2のべき乗で乗算した値 = "); print_bits(n1); printf("\n2のべき乗で除算した値 = "); print_bits(n2); putchar('\n'); return(0); }

  • C言語 unsigned 表示

    #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)); } unsigned rrotate(unsigned x1 ,int n){ int bits=int_bits(); n%=bits; return(n? (x1>>n)|(x1<<(bits-n)):x1); } int main (void){ unsigned nx,b; b=rrotate(nx,2); printf("%u\n",b); return(0); } 3221225476や1073741829と表示されることがあります。 入力値を4で割った数を表示するには、どうしたらよいでしょう・ 御指摘お願いします。

  • ビット操作について

    void print_bit(unsigned x) { for(int i=int_bit()-1;i>=0;i--) { putchar(((x>>i) & 1U)?'1':'0');      } } int main(void) { print_bit((~0>>16)); return0; } と入力したのですが、結果が 111111111111111111111111111111 と出てしまうのですが。 自分的には0000000000000000111111111111111と出したいのですが。 どうしたらいいのでしょうか? できるならどうしてこのような結果になったのか教えていただけたらな と思います。よろしくお願いします。

  • オーバーフローについて。

    /* 符号無しの算術演算がオーバーフローを起こさないことを確認 */ という、ソースについて教えてください。 #include <stdio.h> #include <limits.h> int mani(void) { unsigned x = UINT_MAX - 1; printf("unsigned型の最大値:%u\n", UINT_MAX); printf("x = %n\n", x); printf("x + 3 = %u\n", x + 3); printf("x * 2 = %u\n", x * 2); return(0); } まず、 (1)unsigned x = UINT_MAX - 1; についてですが、何故1を引く必要があるのでしょうか? 別に1を引かなくてもいい気がするのですが・・・ (2)printf("x + 3 = %u\n", x + 3);  printf("x * 2 = %u\n", x * 2); についてですが、x = 65534 に + 3 にしたり、* 2 にすることで、何が言いたいのかがわからないので、教えてください。

  • 共用体のサンプルコード : 内容がわかりません

    #include <iostream> using namespace std; union bits{ bits(double n); void show_bits(); double d; unsigned char c[sizeof(double)]; }; bits::bits(double n) { d = n; } void bits::show_bits() { int i, j; for(j = sizeof(double)-1; j>=0; j--){ cout << "バイト単位のビットパターン" << j << ":"; for(i=128; i ; i >>=1) if(i &c[j]) cout <<"1"; else cout << "0"; cout <<endl; } } int main () { bits ob(1991.829); ob.show_bits(); return 0; } このコードが何をしているのか解説していただけないでしょうか?

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

  • C言語 外部変数について

    #include<stdio.h> int count; int f(int x){  int i;  for(i=0 ; x < 10 ; i++){   x*=2;   count++;   }  return x; } int main(void){  count=0;  printf("%d %d",f(1),count);  return 0; } のようなプログラムを作って実行してみたところ f(1)の部分は1024と自分の目的通りの結果が返ってきましたが countの部分が0とでてきてしましました 関数内で10回の繰り返しを行ったので 10がはいってると思ったのですが どこを直せば10の値がでてきますか?