TIP: Click on subject to list as thread! ANSI
echo: aust_c_here
to: Anton Maurovic
from: Roy McNeill
date: 1994-12-28 12:10:24
subject: Bit-sized variables again

Hi Anton



 AM> Do you think this code is what I've been talking about (or something

 AM> like it)? Thanks (now and in advance) for your help.



Well, talk about learn sumfin every day. I'd never heard of bit

fields before, so had to give myself a crash course last night.

I've whipped up a demo program that might help you get the hang of them.



Bit fields can only be used inside structures, unions, and C++

classes. If you want to access an 8 bit byte both as a whole, and

split up into bitfields, you have to create a union, telling the

compiler that you want the byte (unsigned char is an 8 bit byte on

my compiler, although I've used int here) and the bitfield to

occupy the same space.



The book has a portability warning on these things, saying that

different machines may order them in different ways. I think this

would apply only if you were using large fields, gretaer than 16

bits say, but I'm not sure.



And thank you for letting me know about this trick, I'll have a use

for it.



/* program nama BITFIELD.C */

#include 

typedef unsigned int    uint;



/* I used unsigned int rather than unsigned short below, because my compiler

   in ANSI mode says bitfields gotta be int or unsigned int.  Whatever, make

   sure that all of your dealings with these bitfields involve unsigned types,

   unless you are comfortable with two's complement arithmetic.*/



typedef struct _lcr {    /* (the _lcr tag is actually redundant here) */

        uint   databits           : 2;

        uint   stopbits           : 1;

        uint   parity             : 2;

        uint   stuckparity        : 1;

        uint   breakenable        : 1;

        uint   dlab               : 1; /* Numbers *do* specify no. of bits. */

} LCR;  /* I prefer all caps for complex typedefs */



/* note that "databits" will be least significant, ie appear at
the right hand

   end of the assembled byte, and "dlab" will be most significant. */



union bitunion

{

 LCR bits;

 uint byte;  /* (uint is bigger than a byte, but never mind...) */

};



/* function declarations */

void printheading(void);

void printvars(void);

char *binprint(uint number, int numbits);



/* global variables */

char outbuf[9];     /* output string buffer */

union bitunion bun; /* the actual union we'll be playing with */



int main(void)

{

 int i; char ch;

 printheading();

 /* to test the prog, let's output all zeroes */

 bun.byte = 0;

 printvars();

 /* and all ones. */

 bun.byte = 0xFF; /* hex FF is 255 decimal, 11111111 binary */

 printvars();

 printf("\n");    /* blank line */



 /* now let's set a few individual bits */

 bun.byte = 0;  /* preclear all of them by setting the entire byte to zero*/

 bun.bits.stopbits = 1;  /*set an individual bit */

 printvars();

 bun.bits.dlab = 1;      /* and another one */

 printvars();

 bun.bits.databits = 3;  /* this is a two bit field, can be 0,1,2, or 3 */

 printvars();

 bun.bits.databits = 2;

 printvars();

 bun.bits.databits = 1;

 printvars();

 bun.bits.databits = 0;

 printvars();

 printf("\n Press a key to continue...\n"); /* so we don't fill
the screen */

 ch = getc(stdin);

 printheading();

 /* Now let's set a field to a value that's too big. The value will be

    truncated, only the bits that fit will be taken, the higher order bits

    *won't* overflow into the rest of the byte (this is a good thing,

    actually), and, perhaps most importantly, there is *no* warning. You're

    entirely on your own, here. */

 bun.byte = 0; /*start with all zeroes */

 bun.bits.stopbits = 1;

 printvars();

 bun.bits.stopbits = 2;

 printvars();

 bun.bits.stopbits = 3;

 printvars();

 bun.bits.stopbits = 4;

 printvars();

 printf("\n");

 /* do it again with a 2 bit field */

 bun.byte = 0; /*start with all zeroes */

 for(i=0; i<9; i++)

    {

     bun.bits.parity++;

     printvars();

    }

 return (0);

}

/* ----- functions ------ */

void printheading(void)

{

 puts(" Dlab    Break    Stuck    Parity   Stopbits Databits Complete\n"

      "         enable   parity                              number\n");

}

void printvars(void)

{

 printf( "%3s ", binprint(bun.bits.dlab, 1));

 printf( "%8s ", binprint(bun.bits.breakenable, 1));

 printf( "%8s ", binprint(bun.bits.stuckparity, 1));

 printf( "%8s ", binprint(bun.bits.parity, 2));

 printf( "%8s ", binprint(bun.bits.stopbits, 1));

 printf( "%10s ", binprint(bun.bits.databits, 2));

 printf( "%11s\n", binprint(bun.byte, 8));

}

char *binprint( uint number, int numbits)

/* returns a pointer to a char string containing a binary version of
"number",

   which consists of "numbits" bits. */

{

 int i;

 /* start at the least significant bit, test it, then shift the number right */

 for(i=0; i> 1;   /* right shift the number by one bit */

    }

 outbuf[numbits]='\0';       /* terminate the string */

 return  outbuf;

}

/* end program */



--- PPoint 1.88


* Origin: Silicon Heaven (3:711/934.16)
SEEN-BY: 711/809 934
@PATH: 711/934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.