// Declaration of data type where 4 bytes are packed into an unsigned.
int xbyte(packed_t word, int bytenum);
int main()
{
int bytenum = 0;
typedef unsigned packed_t;
packed_t word;
}
// Extract byte from word, return as signed integer.
int xbyte(packed开发者_如何学C_t word, int bytenum)
{
// Failed attempt at xbyte
return ( word >> (bytenum << 3)) & 0xff;
}
I am unsure how to declare the packed_t in this question. I am supposed to use the prototype from the top. How does word even come into play. I am lost this is part of a homework assignment.
You already have a typedef
line. Make it the first line of this piece of code, and you are done. The basic thing is that the typedef
ed name must be visible everywhere you use it.
First, of course, you can typedef packed_t
to any integral type you
want; the typedef must be visible everywhere packed_t
is used,
however.
Secondly, word >> (bytenum << 3)
is a bit of obfuscation. What you
want is word >> (bytenum * 8)
, or even better:
return (word >> (bytenum * CHAR_BIT)) & ((1 << CHAR_BIT) - 1);
(It's hard to say what the best solution is here: the above expression
gives portability even to machines where bytes are not 8 bits, but the
subexpression to the right of the &
is pretty obscure, and certainly
worthy of a comment.)
Finally: should we read anything into the title. If you're trying to return the value of the byte as if it were a signed byte, then you'll need additional code to handle that. For a classical 32 bit two's complement machine, the following will work:
int tmp = word >> (bytenum * 8);
if ( (tmp & 0x80) != 0 )
tmp |= 0xFFFFFF80;
else
tmp &= 0x7F;
return tmp;
More portably (not that portability to machines which aren't 2's complement with 8 bit bytes is very important), you'd have to write:
int tmp = (word >> (bytenum * CHAR_BIT)) & ((1 << CHAR_BIT) - 1);
if ( tmp > SCHAR_MAX )
tmp -= UCHAR_MAX + 1;
return tmp;
But this also depends what is actually required. The value of the nth byte depends on the actual representation of integers in hardware. The code above ignores this, and returns the low order byte as byte 0, not necessarily the first byte. If you really want the nth byte some sort of type punning is required:
return *(reinterpret_cast<signed char*>( &word ) + bytenum);
Without more information as to what is required, it's difficult to say what the correct answer should be.
perhaps a union would be useful here
union packed_t
{
unsigned int unsignedInt;
char signedChar[4];
}
精彩评论