Can somebody explain to me what happens with br agument in union, after assigning str.a and str.b? We need to set that value before calling the function above? I tried to run the code in simulator https://pythontutor.com/render.html#mode=display which says that the value of br is 516 before calling the function. How is that possible?
#include <stdio.h>
void f(short num, short* res){
if (num){
*res = *res * 10 num;
f(num / 10, res);
}}
typedef union {
short br;
struct {
char a, b;
} str;
} un;
void main() {
short res = 0; un x;
x.str.a = 4; x.str.b = 2;
f(x.br, &res); x.br = res;
printf("%d %d %d\n", x.br, x.str.a, x.str.b);}
CodePudding user response:
The value of the short
will depend on the computer's endianess. On a little endian machine, a
will correspond to the least significant byte and b
to the most significant. Thus when those two bytes are converted to a short, you get the number 0x0204 = 516 decimal.
As a side note, it is a bad idea to use short
and char
since those may be signed and negative. Use uint16_t
and uint8_t
instead, whenever dealing with binary arithmetic.
CodePudding user response:
Assuming that char
is one byte and short
is two bytes (the most common), then it's really simple.
Begin by drawing out the members of the union on a piece of paper, one member next to the other. Something like this:
br str --- --- | | | | a --- --- | | | | b --- ---
Now we do the assignments:
x.str.a = 4;
x.str.b = 2;
And write the results in the drawing:
br str --- --- | 4 | | 4 | a --- --- | 2 | | 2 | b --- ---
Assuming little endianness like on a normal x86 or x86-64 system, then the value of br
will be 0x0204
which is 516
in decimal.
So that's where the value 516
is coming from.
CodePudding user response:
If you put some effort into your debugging you would see what is going on:
void f(short num, short* res)
{
if (num)
{
*res = *res * 10 num;
f(num / 10, res);
}
}
typedef union
{
short br;
struct
{
char a, b;
};
} un;
int main(void)
{
short res = 0; un x;
x.a = 4; x.b = 2;
printf("Before br=0xx (%d) a=0xx b=0xx res = %d 0x%x\n", x.br, x.br, x.a, x.b, res, res);
f(x.br, &res); x.br = res;
printf("After br=0xx a=0xx b=0xx res = %d 0x%x\n", x.br, x.a, x.b, res, res);
}
result:
efore br=0x0204 (516) a=0x04 b=0x02 res = 0 0x0
After br=0x0267 a=0x67 b=0x02 res = 615 0x267
Do your br
was 516 and it was reversed by the f
function becoming 615 which is 0x0276. It contains of two bytes 0x02 and 0x67.
Your computer is little-endian so the first byte is 0x67 and the second one is 0x02 because this system stores the least significant byte first.