Milad Khajavi
Milad Khajavi

Reputation: 2859

how to manipulate bit of integer type in c?

I have written this program:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

struct A {
  bool a;
  bool b;
  bool c;
  bool d;
};

struct B {
  int a;
};

int main() {
  struct A* pa = malloc( sizeof(struct A) );
  struct B* pb = (struct B*) pa;
  pa->a = 0;
  pa->b = 1;
  pa->c = 0;
  pa->d = 0;

  printf("value of pint is %i\n", pb->a);
  return 0;
}

I expect that it print 2 (0010) but the output is 256. Any one cloud help that what is wrong with this code?

Upvotes: 0

Views: 195

Answers (5)

raj raj
raj raj

Reputation: 1922

After you initialize pa, you have

*pa = { 0x00, 0x01, 0x00, 0x00 }

since each bool is one byte. And when you type cast this into an int value, you get (in little endian machine) *pb as

*pb = 0x00000100

which is obviously 256. Got it?

If you want, you may define struct A as:

struct A {
  bool a:1;
  bool b:1;
  bool c:1;
  bool d:1;
};

but do not typecast a pointer of struct A to that of struct B since both structures's sizes are then different.

This may be helpful to you in future:

union A {
    struct {
    bool bit0:1;
    bool bit1:1;
    bool bit2:1;
    bool bit3:1;
    bool bit4:1;
    bool bit5:1;
    bool bit6:1;
    bool bit7:1;
    };
    unsigned char cByte;
};

By defining so, you can access this as bit-wise or byte-wise.

Upvotes: 2

Zang MingJie
Zang MingJie

Reputation: 5275

Try

struct A {
  bool a:1;
  bool b:1;
  bool c:1;
  bool d:1;
};

the :1 part force compiler alloc 1 bit instead of 1 byte for each member variable, so the memory layout of struct A will look like this one (assume little endian):

|-byte 1-|-byte 2-|-byte 3-|-byte 3-|
 uuuudcba uuuuuuuu uuuuuuuu uuuuuuuu

where u donates for unused. when cast it to integer, you will get an integer view of:

uuuuuuuu uuuuuuuu uuuuuuuu uuuudcba

And because of different bit-order of different compiler implementation, you may get also get reversed result 4 (0100) instead of 2 (0010)

Upvotes: 0

unxnut
unxnut

Reputation: 8839

You are printing the number in little Endian notation. Effectively, what you printed is:

0 * 256^0 + 1 * 256^1 + 0 * 256^2 + 0 * 256^3

If you decide to use bitfields (as suggested by someone else), you should use %x to print in hexadecimal. If you strictly want to print in binary, you will have to do it using a loop going over individual bits.

Upvotes: 1

Suvarna Pattayil
Suvarna Pattayil

Reputation: 5239

%i prints an integer.

bool is an unsigned integer type large enough to store the values 0 and 1.

You can print a bool this way:

printf("%d\n", b);

Upvotes: 1

Daniel Fischer
Daniel Fischer

Reputation: 183888

I expect that it print 2 (0010) but the output is 256. Any one cloud help that what is wrong with this code?

A bool takes up at least one byte. In your case, apparently exactly one byte, and your platform is little-endian (with 8-bit char). So the second (least significant) byte is 1, all other bytes 0, makes 1*256.

Note that the type-punning via pa and pb violates strict aliasing.

Use a union to portably type-pun.

Upvotes: 3

Related Questions