lovecreatesbeauty wrote:
[color=blue]
> /*
>
> It seems that when an int with width of four bytes is assigned to a one
> byte width char, the first three bytes from left to right are discarded
> and the rightest byte is assigned to that char.[/color]
That's how it usually works out. From the language's
point view you're assigning values rather than chunks of
the representation, and the value stored in the char is
derived from the value of the int via a conversion.
Your example code uses unsigned ints and chars, for
which things will work as you describe. For signed variants
the question of representation comes into play, and things
could turn out differently on a system that doesn't use
two's complement arithmetic. Such systems are surpassingly
rare nowadays, but ...
[color=blue]
> So, I can just assign an int to a char to retrieve the rightest byte of
> that int, and I also use this method plus right-shift operation to get
> the leftest byte of an int.[/color]
Yes, for unsigned types. Be warned that negative integers
do not right-shift the same way on all systems.
[color=blue]
> I should be wrong on it, please correct me with your expertise.
>
> Thank you
>
> lovecreatesbeauty
>
> */
>
> #include <stdio.h>
>
> int main(void)
> {
> unsigned int data = 'chum';[/color]
This construct isn't portable, and the value assigned
to data is entirely compiler-defined. Either the 'c' or
the 'm' -- or even neither! -- might wind up in the low-
order byte of data. A portable (assuming four-byte int)
way of ensuring the order you expect is to assemble it
from the individual pieces:
unsigned int data = ('c' << 24) + ('h' << 16)
+ ('u' << 8) + 'm';
[color=blue]
> unsigned char left = '\0';
> unsigned char right = '\0';
>
> printf("data: %#X\n", data);
>
> /* get the leftest byte of an int */
> left = data >> (sizeof(int) - 1) * 8;[/color]
This is fine, assuming eight-bit char. Machines
with other char sizes are rare, but definitely do exist
(they are commoner than machines that don't use two's
complement). To gain more portability, you could #include
the <limits.h> header and use CHAR_BIT instead of 8 (and
you'd make similar adjustments in the initialization of
data, above).
[color=blue]
> /* get the rightest byte of an int */
> right = data;
>
> printf("left: %#X, %c\n", left, left);
> printf("right: %#X, %c\n", right, right);
>
> return 0;
> }
>
> /* result: (Win2k, mingw32)
> data: 0X6368756D
> left: 0X63, c
> right: 0X6D, m
> */[/color]
A little thought will show that shifting by other
amounts can retrieve the 'h' and 'u' characters, too.
In fact, you can retrieve groups of bits that straddle
the char boundaries, if you want. See also "masking."
--
Eric Sosman
esosman@acm-dot-org.invalid