Home > Enterprise >  What is happening step by step in this C code
What is happening step by step in this C code

Time:10-22

I dont understand what is happening in the code below. Please explain to me step by step

In the output Console, for the 1st printf, I get a smiley face. WHY? If i'm not mistaken, it is supposed to print the 257th ASCII, but there is no ASCII value after 255. So where is it getting the smiley face from?

Similarly for the 2nd printf i got a smiley face. WHY?

3rd printf: value is 323 as it is printing the integer value of variable d

lastly, the 4th printf: WHY does the output show 0?

int main()
{
    char b;
    int i = 257;
    double d = 323.142;

    b = i;
    printf("%c\n", b);

    b = (char) i;
    printf("%c\n", b);

    i = (int) d;
    printf("%d\n", i);

    b = (char) d;
    printf("%c\n", b);
}

OUTPUT:

console output

CodePudding user response:

b = i;
printf("%c\n", b);

This will truncate the value of i (257 as 4 bytes) into a one byte value (char), which effectively writes the result of 257 modulo 256, ie 1. Then it prints the character with the ASCII code 1, which your console of choice prints as a smiley face, so it sounds like you're using the Windows console.

b = (char) i;
printf("%c\n", b);

Same as above, the cast was implied above, here it's written explicitly.

i = (int) d;
printf("%d\n", i);

Casting a floating point value (d) to an integer stores the integer part only, as long as it fits, otherwise it truncates it as described above. In this case it fits and you get the integer part of 323.142, which is 323.

b = (char) d;
printf("%c\n");

Here you didn't pass b to your printf statement, so the result is undefined. If you had, it would have printed character 323 modulo 256 which is 67, which is a C.

As an aside, I find hilarious the amount of people "answering" you in comments that they're confused. If this confused me, I wouldn't be so quick to announce it to the world.

CodePudding user response:

b = i;
printf("%c\n", b);

When an int is assigned to a char:

  • If char is unsigned, the value is wrapped modulo CHAR_MAX 1, commonly 256. This maps 257 to 1.
  • If char is signed, the conversion produces a value or signal defined by the C implementation. Wrapping modulo 256 is common.

Printing the value 1 with %c prints the character with code 1, which is apparently a smiley face in the C implementation you are using. (This is not ASCII; ASCII does not have smiley faces, although other characters in the character set may be ASCII.)

(The C standard allows the char type to be signed or unsigned. It is up to each implementation to define which.)

b = (char) i;
printf("%c\n", b);

This performs the same conversion and printing above. Using (char) just makes the conversion explicit.

i = (int) d;
printf("%d\n", i);

When a double is converted to int, the fractional part is discarded. If the integer part can fit in an int, that is the result. Otherwise, the behavior is undefined. For converting 323.142, 323 fits in an int, so that is the result, and that is what is printed for i.

b = (char) d;
printf("%c\n", b);

Converting a double to a char is similar; if the integer part cannot fit, the behavior of the program is not defined by the C standard. Since 323 will not fit into a char, the behavior is not defined by the C standard. Below are some examples of behavior observed in this case.

Using this code:

#include <stdio.h>

int main()
{
    char b;
    double d = 323.142;

    b = (char) d;
    printf("%d\n", b);
}

Compiler Explorer shows, for GCC 12.2 with -O0 output of “67”.

Changing -O0 to -O3 produces output of “127”.

Clang 15.0.0 with -O0 also produces “67”.

Clang 15.0.0 with -O3 produces “1360786488”. Observe it is not possible for a char to have a value of 1,360,786,488 in this C implementation, so the conversion has not merely produced a value for the char; it has “broken” the behavior of the program more drastically.

CodePudding user response:

If you are taking a class in the C language and this is a problem given to you in that class, I would suggest that you read the sections in the text about variable types and type casting. What is going on here is an exercise in understanding these two things. If this is part of your education, you will need to understand these concepts otherwise others will have to do the work for you.

For example, your code that says b = i is trying to stuff a variable of type char with a value of type int. The int value is 257 but the char type only holds a byte whose value ranges from 0 to 255. So, when C does the implicit type coercion it is setting 'b' to the value of 1 (the last 8 bits of the int). Then when you go to the next line and print b using the character formatting in printf, since the value of 1 is an unprintable ASCII control character, you get that symbol you're getting on the console. That symbol represents an undefined ASCII character.

The next part, b = (char) i is doing that same thing as b = i except you are explicitly asking the compiler to cast the integer as a char type. And, you get the same result on the console.

The next part of i = (int) d is casing your floating point value of d to an integer. The integer part of d is 323. You then print this out to the console as a number (your %d) and thus you get 323 on the console.

The last line tries to cast the double floating point into an 8 bit char. I'd have to do more research for you to see why you're getting a '0' on the console for this conversion.

  •  Tags:  
  • c
  • Related