Sie sind auf Seite 1von 5

1. What is the most efficient way to store flag values?

A flag is a value used to make a decision between two or more options in the execution of a program. For
instance, the /w flag on the MS-!S dir command causes the command to displa" filenames in several
columns across the screen instead of displa"ing them one per line. #n which a flag is used to indicate which
of two possible t"pes is held in a union. $ecause a flag has a small number of values %often onl" two&, it is
tempting to save memor" space b" not storing each flag in its own int or char.
'fficienc" in this case is a tradeoff between si(e and speed. )he most memor"-space efficient wa" to store a
flag value is as single bits or groups of bits *ust large enough to hold all the possible values. )his is because
most computers cannot address individual bits in memor", so the bit or bits of interest must be extracted
from the b"tes that contain it.
)he most time-efficient wa" to store flag values is to keep each in its own integer variable. +nfortunatel",
this method can waste up to ,- bits of a ,.-bit variable, which can lead to ver" inefficient use of memor". #f
there are onl" a few flags, it doesn/t matter how the" are stored. #f there are man" flags, it might be
advantageous to store them packed in an arra" of characters or integers. )he" must then be extracted b" a
process called bit masking, in which unwanted bits are removed from the ones of interest.
Sometimes it is possible to combine a flag with another value to save space. #t might be possible to use high-
order bits of integers that have values smaller than what an integer can hold. Another possibilit" is that some
data is alwa"s a multiple of . or 0, so the low-order bits can be used to store a flag.
2. What is meant by "bit masking"?
$it masking means selecting onl" certain bits from b"te%s& that might have man" bits set. )o examine some
bits of a b"te, the b"te is bitwise 1A2ed1 with a mask that is a number consisting of onl" those bits of
interest. For instance, to look at the one/s digit %rightmost digit& of the variable flags, "ou bitwise A2 it with
a mask of one %the bitwise A2 operator in 3 is 4&5
flags 4 -6
)o set the bits of interest, the number is bitwise 1!7ed1 with the bit mask %the bitwise !7 operator in 3 is 8&.
For instance, "ou could set the one/s digit of flags like so5
flags = flags | 1;
!r, e9uivalentl", "ou could set it like this5
flags |= 1;
)o clear the bits of interest, the number is bitwise A2ed with the one/s complement of the bit mask. )he
1one/s complement1 of a number is the number with all its one bits changed to (eros and all its (ero bits
changed to ones. )he one/s complement operator in 3 is ~. For instance, "ou could clear the one/s digit of
flags like so5
flags = flags & ~1;
!r, e9uivalentl", "ou could clear it like this5
flags &= ~1;
Sometimes it is easier to use macros to manipulate flag values.
'xample :rogram 5 Macros that make manipulating flags easier.
/* Bit Masking */
/* Bit masking can be used to switch a character
between lowercase and uppercase */
#define BIT_POS(N) ( 1U << (N) )
#define SET_FLAG(N, F) ( (N) |= (F) )
#define CLR_FLAG(N, F) ( (N) &= -(F) )
#define TST_FLAG(N, F) ( (N) & (F) )
#define BIT_RANGE(N, M) ( BIT_POS((M)+1 - (N))-1 << (N) )
#define BIT_SHIFTL(B, N) ( (unsigned)(B) << (N) )
#define BIT_SHIFTR(B, N) ( (unsigned)(B) >> (N) )
#define SET_MFLAG(N, F, V) ( CLR_FLAG(N, F), SET_FLAG(N, V) )
#define CLR_MFLAG(N, F) ( (N) &= ~(F) )
#define GET_MFLAG(N, F) ( (N) & (F) )
#include <stdio.h>
void main()
{
unsigned char ascii_char = 'A'; /* char = 8 bits only */
int test_nbr = 10;
printf("Starting character = %c\n", ascii_char);
/* The 5th bit position determines if the character is
uppercase or lowercase.
5th bit = 0 - Uppercase
5th bit = 1 - Lowercase */
printf("\nTurn 5th bit on = %c\n", SET_FLAG(ascii_char, BIT_POS(5)) );
printf("Turn 5th bit off = %c\n\n", CLR_FLAG(ascii_char, BIT_POS(5)) );
printf("Look at shifting bits\n");
printf("=====================\n");
printf("Current value = %d\n", test_nbr);
printf("Shifting one position left = %d\n",
test_nbr = BIT_SHIFTL(test_nbr, 1) );
printf("Shifting two positions right = %d\n",
BIT_SHIFTR(test_nbr, 2) );
}
BIT_POS(N) takes an integer 2 and returns a bit mask corresponding to that single bit position
%BIT_POS(0) returns a bit mask for the one/s digit, BIT_POS(1) returns a bit mask for the two/s digit, and
so on&. So instead of writing
#dfin !_"#!$ %0&'
#dfin B_"#!$ (1&)
"ou can write
#dfin !_"#!$ BIT_POS(1))
#dfin B_"#!$ BIT_POS(1*)
which is less prone to errors.
)he S+T_"#!$(N, ") macro sets the bit at position " of variable N. #ts opposite is -#._"#!$(N, "), which
clears the bit at position " of variable N. Finall", TST_"#!$(N, ") can be used to test the value of the bit at
position " of variable N, as in
if (TST_FLAG(flags, A_FLAG))
/* do something */;
)he macro BIT_.!N$+(N, /) produces a bit mask corresponding to bit positions N through /, inclusive.
;ith this macro, instead of writing
#dfin "I.ST_O-T!#_0I$IT 1 23 111 32
#dfin S+-ON0_O-T!#_0I$IT 4' 23 111000 32
"ou can write
#dfin "I.ST_O-T!#_0I$IT BIT_.!N$+(0, )) 23 111 32
#dfin S+-ON0_O-T!#_0I$IT BIT_.!N$+(*, 4) 23 111000 32
which more clearl" indicates which bits are meant.
)he macro BIT_S5I"T(B, N) can be used to shift value B into the proper bit range %starting with bit N&. For
instance, if "ou had a flag called - that could take on one of five possible colors, the colors might be defined
like this5
#define C_FLAG BIT_RANGE(8, 10) /* 11100000000 */
/* here are all the values the C flag can take on */
#define C_BLACK BIT_SHIFTL(0, 8) /* 00000000000 */
#define C_RED BIT_SHIFTL(1, 8) /* 00100000000 */
#define C_GREEN BIT_SHIFTL(2, 8) /* 01000000000 */
#define C_BLUE BIT_SHIFTL(3, 8) /* 01100000000 */
#define C_WHITE BIT_SHIFTL(4, 8) /* 10000000000 */
#define C_ZERO C_BLACK
#define C_LARGEST C_WHITE
/* A truly paranoid programmer might do this */
#if C_LARGEST > C_FLAG
Cause an error message. The flag C_FLAG is not
big enough to hold all its possible values.
#endif /* C_LARGEST > C_FLAG */
)he macro S+T_/"#!$(N, ", 6) sets flag " in variable N to the value 6. )he macro -#._/"#!$(N, ") is
identical to-#._"#!$(N, "), except the name is changed so that all the operations on multibit flags have a
similar naming convention. )he macro $+T_/"#!$(N, ") gets the value of flag " in variable N, so it can be
tested, as in
if (GET_MFLAG(flags, C_FLAG) == C_BLUE)
/* do something */;
3. Are bit fields portable?
$it fields are not portable. $ecause bit fields cannot span machine words, and because the number of bits in
a machine word is different on different machines, a particular program using bit fields might not even
compile on a particular machine.
Assuming that "our program does compile, the order in which bits are assigned to bit fields is not defined.
)herefore, different compilers, or even different versions of the same compiler, could produce code that
would not work properl" on data generated b" compiled older code. Sta" awa" from using bit fields, except in
cases in which the machine can directl" address bits in memor" and the compiler can generate code to take
advantage of it and the increase in speed to be gained would be essential to the operation of the program.
. !s it better to bitshift a value than to multiply by 2?
An" decent optimi(ing compiler will generate the same code no matter which wa" "ou write it. +se whichever
form is more readable in the context in which it appears. )he following program/s assembler code can be
viewed with a tool such as 3!'<#'; on !S/;indows or the disassembler %usuall" called 1dis1& on +2#=
machines5
'xample5 Multipl"ing b" . and shifting left b" - are often the same.
void main()
{
unsigned int test_nbr = 300;
test_nbr *= 2;
test_nbr = 300;
test_nbr <<= 1;
}
". What is meant by high#order and low#order bytes?
;e generall" write numbers from left to right, with the most significant digit first. )o understand what is
meant b" the 1significance1 of a digit, think of how much happier "ou would be if the first digit of "our
pa"check was increased b" one compared to the last digit being increased b" one.
)he bits in a b"te of computer memor" can be considered digits of a number written in base .. )hat means
the least significant bit represents one, the next bit represents .>-, or ., the next bit represents .>.>-, or
0, and so on. #f "ou consider two b"tes of memor" as representing a single -?-bit number, one b"te will hold
the least significant @ bits, and the other will hold the most significant @ bits. Figure shows the bits arranged
into two b"tes. )he b"te holding the least significant @ bits is called the least significant b"te, or low-order
b"te. )he b"te containing the most significant @ bits is the most significant b"te, or high- order b"te.
$. %ow are 1$# and 32#bit numbers stored?
A -?-bit number takes two b"tes of storage, a most significant b"te and a least significant b"te. #f "ou write
the -?-bit number on paper, "ou would start with the most significant b"te and end with the least significant
b"te. )here is no convention for which order to store them in memor", however.
Aet/s call the most significant b"te / and the least significant b"te #. )here are two possible wa"s to store
these b"tes in memor". Bou could store / first, followed b" #, or # first, followed b" /. Storing b"te / first in
memor" is called 1forward1 or 1big-endian1 b"te ordering. )he term big endian comes from the fact that the
1big end1 of the number comes first, and it is also a reference to the book Culliver/s )ravels, in which the
term refers to people who eat their boiled eggs with the big end on top.
Storing b"te # first is called 1reverse1 or 1little-endian1 b"te ordering. Most machines store data in a big-
endian format. #ntel 3:+s store data in a little-endian format, however, which can be confusing when
someone is tr"ing to connect an #ntel microprocessor-based machine to an"thing else.
A ,.-bit number takes four b"tes of storage. Aet/s call them /7, /l, #7, and #l in decreasing order of
significance. )here are 0D %0 factorial, or .0& different wa"s in which these b"tes can be ordered. !ver the
"ears, computer designers have used *ust about all .0 wa"s. )he most popular two wa"s in use toda",
however, are %/7, /l, #7, #l&, which is big-endian, and %#l, #7, /l, /7&, which is little-endian. As with -?-
bit numbers, most machines store ,.-bit numbers in a big-endian format, but #ntel machines store ,.-bit
numbers in a little-endian format.

Das könnte Ihnen auch gefallen