我最近在学习C,有些事我无法理解。
以下是示例
int a = -1;
unsigned int b = a;
在这个例子中,这本书说,
"a is auto-casted to 'unsigned int' and then assigned to 'unsigned int b'."
但是......为什么?我的意思是
' int a'是-1,所以它的位串应该是
1111 1111 1111 1111 1111 1111 1111 1111
在计算机的观点中,它所要做的就是只是将这些位复制到unsigned int b
没有必要转换' signed int' to' unsigned int' !
我无法理解,为什么他们会自动投票'签署' to' unsigned int'在复制这些位之前?
答案 0 :(得分:4)
嗯...当您初始化unsigned int
值为signed int
的对象时,肯定需要将unsigned int
转换为signed int
。这正是您通过在初始化中混合这两种不同类型而要求语言执行的操作。当您使用不同类型T
的值初始化类型为U
的对象时,类型U
必须隐式转换以键入T
。 (或者如果没有适当的转换,则必须报告错误。)没有办法绕过它。除了转换之外,没有办法“交配”两种不同的类型。
此外,没有“比特复制”这样的事情。我不知道为什么你的书决定在这种情况下发明这样的概念。当singed int
值转换为unsigned int
类型时,符号值将根据模运算的规则进行转换。这就是你的情况。在二进制补码平台上,转换是概念性的,这意味着值的位表示不会改变(这就是“位复制”的意思)。
答案 1 :(得分:3)
C按值分配变量值,而不是表示。 -1
显然无法在无符号类型中表示,因此必须进行转换。这里的规则(从有符号类型到无符号类型)是转换“模数”,因此-1
最终成为无符号类型的最大值。
如果要通过表示“分配”,则必须使用复制函数,例如memcpy
,但请注意,如果原始位模式不受支持,则可能导致未定义的行为目标类型。
另外,对于词汇,在C中我们说的是“转换”。你在这里有一个隐含的转换。显式转换也称为“强制转换”。
你的书似乎并没有意识到这一切,并且应用了奇怪的词汇。如果你能让自己成为一个新的更好的人,那可能会更好。
答案 2 :(得分:1)
太多的程序员受过这样的教育,他们编写程序假设所有负数都表示为2的补码,并假设有符号/无符号转换是按位复制。
然而,语言无意强迫每个计算机/编译器以这种方式表示负数,尽管它很受欢迎。
C放宽了负数表示的要求,以提供更多的实现灵活性,但同时使“常规”2的补码式按位复制类型转换成为标准的一部分,因此大部分时间那些错误的假设不会引起问题。