| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| 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 * 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™.