Dan said:
Your homework assignment is unclear. What is the 3rd byte of the 32 bit
integer x? Is the counting starting with the most significant byte or
the least significant byte and is the counting 0-based or 1-based?
Because you're an obvious beginner, we shall assume that a byte is 8 bits.
The idea is to bring the byte of interest in the least significant
position of the integer. This is a job for the >> operator, but you'll
have to compute the shift count yourself (even if I wanted to do that
for you, I wouldn't know how, for the reasons explained at the beginning
of my reply).
Once you have the byte there, it is trivial to get rid of all the other
bytes, by masking them away with the bitwise & operator and a suitably
chosen mask (you can trivially figure it out).
The exercise is a bit more interesting if we don't make any assumption
about the byte size. We can get the byte size from <limits.h> as the
macro CHAR_BIT. Once we have it we can build the mask with a loop, but
there are a couple of shortcuts in C: use the macro UCHAR_MAX from the
same header or use the magic expression (unsigned char)(-1).
It'll have to be UCHAR_MAX, I think, because the list
of permitted operators doesn't include casts.
The permitted operators seem to have been chosen so as
to steer the student away from the byte-extraction solutions
that any normal programmer would use, and towards solutions
that good programmers would avoid. Consider:
- Multiplication is forbidden, making it hard to compute
a shift distance from a byte number.
- The array-indexing operator `[]' is forbidden, so the
shift distance can't even be fetched from a pre-
computed table.
- The prohibition on assignment rules out iterative
methods, and multi-step methods in general.
Fortunately, the problem statement only requires that
the code work for "the 3rd byte;" there is no requirement
on what it should do if the second argument is not 3. This
leads to a simple solution, once the counting ambiguity Dan
points out is resolved. Here's what it might look like
if we assume that the least significant byte is the first,
the next-higher byte is the second, and so forth:
#include <limits.h>
unsigned char GetByte(long x, int ignored) {
return (x & (UCHAR_MAX << (CHAR_BIT + CHAR_BIT))
>> (CHAR_BIT + CHAR_BIT);
}
Note 1: It's clumsy to mask before shifting rather than
afterward, but if `x' is negative right-shifting it is
problematic.
Note 2: From the problem statement we know that `x' has
exactly 32 bits and that it contains at least three bytes,
hence CHAR_BIT < 11. From the C Standard we know that
CHAR_BIT is at least 8 and that it is a divisor of the
number of bits in `x'. Putting these together, we can
conclude that CHAR_BIT is exactly 8 for the purposes of
this problem, and this permits some simplification:
/* <limits.h> no longer required */
unsigned char GetByte(long x, int ignored) {
return (x & 16711680) >> '\020';
}
No sane programmer would write such crud, but I think
it solves the problem as stated.