2010-10-07 118 views
1
#include<stdio.h> 
int main(void) 
{ 
    signed int a=-1; 
    unsigned int b=1; 
    int c= a+b; 
    printf("%d\n",c); 

    return 0; 
    } 

根据隐式类型转换的规则,如果一个操作数是unsigned int,其他将被转换为unsigned int和结果将是一个二进制运算unsigned int。 所以这里为bunsigned inta应类型强制转换为unsigned int。作为unsigned int类型总是+ VE,所以a值将是1.so c=1+1=2。但输出0。如何?隐式类型转换

+0

我相信这是您遇到的实现定义(或未定义?)行为。 – strager 2010-10-07 18:24:52

+0

@strager:是的,赋值给'c'的行为是实现定义的。 6.3.1.3/3:“新类型被签名并且值不能在其中表示;结果是实现定义的或者实现定义的信号被引发。” – 2010-10-07 18:55:20

+4

你们都错了。相关的转换是从有符号到无符号的,而不是无符号到有符号的,并且行为是明确的。 '-1'以模数'UINT_MAX + 1'减少,产生'UINT_MAX',并且再次加1就导致以'UINT_MAX + 1'模为模的减少,因此0.然后将0转换回有符号类型,然后明确定义。 – 2010-10-07 18:59:24

回答

16

-1,当转换为无符号时将成为该类型的最大可能值 - 例如,用32位无符号数表示,它将是4,294,967,295。当你加1时,数值“回绕”为0.

+0

@Jerry棺材,所以如果我已经采取了有符号整数a = -2和无符号b = 1,那么输出将是4,294,967,295?但输出是-1。 – Parikshita 2010-10-07 18:14:17

+0

%d输出一个带符号整数。尝试%u。 – 2010-10-07 18:31:40

+0

@Parixit:是的,因为'c'是有符号的。 – JoshD 2010-10-07 18:31:58

-1

现代机器大多使用two's complement表示负数。当添加两个数字时,如果其中任何一个是负数,它将首先转换为二的补码表示。那么这两个数字将被添加。所以电脑通常执行1 - 1作为1 + two's complement of (-1)。结果为0.

对于1 - 2,它是1 + two's complement(-2)。查看该程序,相同的号码,不同的表示:

int main() 
{ 
    signed int a = 1; 
    unsigned int b = -2; 

    int c = a+b; 

    printf("%d\n%u\n", c, c); 

    return 0; 
} 

请阅读有关二进制补码表示。你需要这个成为一名程序员。

+0

加法的行为与二进制补码表示无关。在一个补码机器上,直到结果赋给'c'(这是执行定义的,正如strager所说的)。 – 2010-10-07 18:57:57

+0

-1二进制补码与OP的问题无关,它在**任何** C实现上具有相同的行为。您的新示例依赖于两个补充实现共同的特定于实现的行为。 – 2010-10-07 19:01:28

+0

我的意图是让OP意识到最常见的实现。对不起,我应该在原始答案中注明它。 – Donotalo 2010-10-07 19:56:12

2

“a应该被转换为unsigned int类型,因为unsigned int总是+ ve,所以a的值将为1”。

校正多达“将”,但此后不;-)

带符号的整数转换成无符号的结果在标准中指定,6.3.1.3/2:

如果新的类型是无符号的,则该值 通过反复增加或减去 一个以上可在 新类型来表示,直到该值是在 范围的新类型的最大 值转换

换句话说,负值通过将其值取2的某个幂而不是通过翻转符号而转换为无符号。

+0

so -1%UINT_MAX将再次为-1 .. – Parikshita 2010-10-07 19:39:35

+0

不,因为-1不能表示为无符号整数,所以它不能是将任何内容转换为无符号整型的结果。标准中有一个脚注说“加法”或“减法”是指涉及的实际数学数字,而不是任何特定C类型的“+”或“-'运算符。这同样适用于我使用“模数” - 我的意思是数学运算,产生一个范围为[[0,UINT_MAX]'的值。我不是指签署的'%'运算符。 – 2010-10-07 19:44:11

+0

也就是说,作为一名受数学家教育的人,我个人有时会认为无符号值是环UUN_MAX模的抽象成员。在这种情况下,是的,减少-1模“UINT_MAX + 1”的结果仍然是-1,但是在-1等于“UINT_MAX”的模型中。尽管如此,将这个无符号整数的心智模型做成可能并不明智,因为该模型没有描述某些C操作,例如分割。 – 2010-10-07 19:47:50