user2467545
user2467545

Reputation:

Confusion about the output of this program

I am new to C programming and I am currently learning Data types revised chapter. In the below program, my o/p is 36 but compiler is showing the o/p 35.

main( )
{
char ch = 291 ;
printf ( "\n%d %c", ch, ch ) ;
}

Can anyone explain me why the o/p is coming 35? I am currently using GCC 32-bit compiler.

Upvotes: 3

Views: 1632

Answers (3)

Jerska
Jerska

Reputation: 12002

You're actually making an overflow. A signed character can only go from values -128 to 127 (256 values = 28) in 8-bit character systems (which are pretty much everywhere). So we go with an actual character which value equals 291 % 256 = 35.

Don't forget that the first character is 0, not 1.

Here is actually how a char is represented with the 2's complement system:

unsigned
0 ------- 127 128 ------- 255

signed
0 ------- 127 -128 ------- -1

So actually a signed char c1 = -128 equals an unsigned char c2 = 128

But here this problem is just irrelevant. We're talking about modulo because only the last eight bits are taken into account (where would the other be stored when there are only eight bits available for it in the memory ?).

291 = % 1 0010 0011

(% means binary representation)

It keeps only the % 0010 0011 which equals 35 and which will be considered exactly the same either you take it signed or not.

Upvotes: 3

Carl Norum
Carl Norum

Reputation: 224844

Your system apparently has an 8-bit char type. That means 291 is too big to fit - the compiler reduces it modulo 256 (28) and you end up with 35.

In this case, Clang provides a great warning:

example.c:3:11: warning: implicit conversion from 'int' to 'char' changes value
      from 291 to 35 [-Wconstant-conversion]
char ch = 291 ;
     ~~   ^~~

You should probably avoid relying on this behaviour, since it may vary from implementation to implementation. The C99 and C11 specs (Section 6.3.1.3) say about signed integer conversions:

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

Since you're using GCC, you might be interested to read this excerpt from the documentation:

The result of, or the signal raised by, converting an integer to a signed integer type when the value cannot be represented in an object of that type (C90 6.2.1.2, C99 6.3.1.3).

For conversion to a type of width N, the value is reduced modulo 2N to be within range of the type; no signal is raised.

And there you have your full explanation of the reduction modulo 256.

Upvotes: 7

Havenard
Havenard

Reputation: 27854

Because a char can only contain 8 bits of information, and 291 require more than that to be stored. It will then discard the higher bits and keep only what fitted in the variable.

You can simulate that by both bitwise and module operation:

291 % 256 = 35

291 & 0xFF = 35

A 8-bit char can contain values of -128 to 127 or 0 to 255, depending if its signed or unsigned.

Upvotes: 3

Related Questions