简体   繁体   English

关于这个计划的输出的困惑

[英]Confusion about the output of this program

I am new to C programming and I am currently learning Data types revised chapter. 我是C编程新手,我目前正在学习数据类型修订章节。 In the below program, my o/p is 36 but compiler is showing the o/p 35. 在下面的程序中,我的o / p是36,但编译器显示o / p 35。

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

Can anyone explain me why the o/p is coming 35? 任何人都可以解释为什么o / p即将到来35? I am currently using GCC 32-bit compiler. 我目前正在使用GCC 32位编译器。

Your system apparently has an 8-bit char type. 您的系统显然具有8位char类型。 That means 291 is too big to fit - the compiler reduces it modulo 256 (2 8 ) and you end up with 35. 这意味着291太大而不适合 - 编译器将其模数减少256(2 8 )并最终得到35。

In this case, Clang provides a great warning: 在这种情况下, Clang提供了一个很好的警告:

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: C99和C11规范(第6.3.1.3节)说明有符号整数转换:

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 : 由于您正在使用GCC,您可能有兴趣阅读文档中的这段摘录:

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) . 当该值无法在该类型的对象中表示时,将整数转换为有符号整数类型的结果或信号(C90 6.2.1.2,C99 6.3.1.3)

For conversion to a type of width N, the value is reduced modulo 2 N to be within range of the type; 为了转换为宽度N的类型,该值以2 N为模减少到该类型的范围内; no signal is raised. 没有信号被提出。

And there you have your full explanation of the reduction modulo 256. 在那里你有对减少模256的完整解释。

Because a char can only contain 8 bits of information, and 291 require more than that to be stored. 因为char只能包含8位信息,而291需要的信息要多于要存储的信息。 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%256 = 35

291 & 0xFF = 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. 8位字符可以包含-128到127或0到255的值,具体取决于其是有符号还是无符号。

You're actually making an overflow. 你实际上是在溢出。 A signed character can only go from values -128 to 127 (256 values = 2 8 ) in 8-bit character systems (which are pretty much everywhere). 签名字符只能在8位字符系统(几乎无处不在)中从值-128到127(256值= 2 8 )。 So we go with an actual character which value equals 291 % 256 = 35. 所以我们选择一个实际的字符,其值等于291%256 = 35。

Don't forget that the first character is 0, not 1. 不要忘记第一个字符是0而不是1。

Here is actually how a char is represented with the 2's complement system : 这里实际上是如何使用2的补码系统表示char:

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

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

So actually a signed char c1 = -128 equals an unsigned char c2 = 128 所以实际上signed char c1 = -128等于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 ?). 我们讨论的是模数,因为只考虑了最后8位(如果内存中只有8位可用,那么另一位会被存储?)。

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. 它只保留% 0010 0011等于35 ,并且无论你是否接受它都将被视为完全相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM