Home > Mobile >  Print operators
Print operators

Time:01-29

I need help solving this problem in my mind so if anyone had a similar problem it would help me a lot.

The task is: What the next code prints:

union uni { char s[2], c; } u={"A"};
printf("01:%d\n", sizeof(u));
printf("02:%d\n", sizeof(u.s));
printf("03:%d\n", sizeof(u.c));
printf("04:%x\n", u.c);
printf(u.s[1] ? "05:%c":"05:%d", u.c);

I don't understand why the print looks like this:

01:2
02:2
03:1
04:41
05:65 

In the first print function, my opinion on why it prints 2 is because we have two data of type char in the union.

In the second function it prints 2 because we have two elements of the array of type char.

In the third function it prints 1 because we have one data of type char.

In the fourth function, it prints 41, because 'A' is entered in the char data in the union, and 41 is the hexadecimal value of A.

I do not understand the fifth function for printing at all, because the condition of the ternary operator is unclear to me.

Can anyone explain to me why the printout is like this?

CodePudding user response:

Here

union uni { char s[2], c; } u={"A"};

A variable named u is defined, of a union type declared in the same line. The variable is also initialised with the value "A", which is a null-terminated sequence of 2 chars. The initialisation targets the first of the union options, an array of char with two elements. The array receives the 'A' in index 0 and the '\0' in index 1.

Here

u.s[1] ? "05:%c":"05:%d"

The ternary operator is used to check the index 1 of the array (which contains the null terminator; boolean false). The option selected by the ternary is hence "05:%d", i.e. a format specifier for an integer interpretation. Which is used to output the second union option. The output is hence the integer value, 65, by default in decimal.

CodePudding user response:

printf("01:%d\n", sizeof(u));
01:2

u is a union type containing two members: a 2-element char[] array named s, and a single char named c. All members of a union overlap in memory, so the size of the union is the size of its largest member, which in this case is s. And since sizeof(char) is 1, the size of s is sizeof(char) * 2 = 2, thus the size of the union is 2.

printf("02:%d\n", sizeof(u.s));
02:2

s is a char[2] array, so its size is sizeof(char) * 2 = 2.

printf("03:%d\n", sizeof(u.c));
03:1

c is a single char, so its size is sizeof(char) = 1.

printf("04:%x\n", u.c);
04:41

You are initializing u with the string literal "A". Initializing a union initializes its 1st member (unless a designated initializer is used, which you are not doing). Thus, u.s is initialized with {'A', '\0'}. And because u is a union, u.c overlaps the 1st array element of u.s in memory, so u.c now contains the character 'A', which has an ASCII decimal value of 65. You are telling printf() to print the value of u.c as a hexadecimal integer, and the hexadecimal value of 65 is 0x41.

printf(u.s[1] ? "05:%c":"05:%d", u.c);
05:65

The ?: conditional operator evaluates its 2nd operand only if its 1st operand is non-zero, otherwise it evaluates its 3rd operand. In this case, you are essentially doing the equivalent of this:

const char* fmt;
if (u.s[1] != 0)
    fmt = "05:%c";
else
    fmt = "05:%d";
printf(fmt, u.c);

As stated further above, u.s[1] is initialized with the character '\0', which has a numeric ASCII value of 0. Since the 1st operand of ?: is 0, the 3rd operand is evaluated, which is "05:%d". Thus, you are telling printf() to print the value of u.c as a decimal integer, not as a character. And as stated further above, u.c contains the character 'A', which has a decimal value of 65.

CodePudding user response:

This:

printf(u.s[1] ? "05:%c":"05:%d", u.c);

has the same behaviour as this:

if (u.s[1])  // shorthand for `if (u.s[1] != 0)`
  printf("05:%c", u.c);
else
  printf("05:%d", u.c);

Now it should be clear. Read about the ternary operator in your learning material.

CodePudding user response:

Remember that a union can store only one of its members at a time, so only enough space is set aside for the largest member - in this case, that's the member s which is a 2-element array of char.

So the object u must be at least as large as u.s, which is a 2-element array of char; hence, sizeof u == sizeof u.s == 2.

The member u.c has type char, so sizeof u.c == 1.

  •  Tags:  
  • Related