以下是示例:
#include <stdio.h>
int main()
{
int x=35;
int y=-35;
unsigned int z=35;
unsigned int p=-35;
signed int q=-35;
printf("Int(35d)=%d\n\
Int(-35d)=%d\n\
UInt(35u)=%u\n\
UInt(-35u)=%u\n\
UInt(-35d)=%d\n\
SInt(-35u)=%u\n",x,y,z,p,p,q);
return 0;
}
输出:
Int(35d)=35
Int(-35d)=-35
UInt(35u)=35
UInt(-35u)=4294967261
UInt(-35d)=-35
SInt(-35u)=4294967261
如果我将值声明为signed或unsigned int,这真的很重要吗?因为,C实际上只关心我如何从内存中读取值。请帮助我理解这一点,我希望你证明我错了。
答案 0 :(得分:4)
unsigned int
和signed int
在内存中占用相同的字节数。它们可以存储相同的字节值。但是,数据的处理方式会有所不同,具体取决于是签名还是未签名。
有关表示整数值的最常用方法的说明,请参阅http://en.wikipedia.org/wiki/Two%27s_complement。
由于您可以在C中进行类型转换,因此可以有效地强制编译器将unsigned int视为signed int,反之亦然,但要注意它并不意味着它会按照您的想法执行或表示将是正确的。 (溢出有符号整数会调用C中的未定义行为。)
(正如评论中所指出的,除了两个补码之外,还有其他方式来表示整数,但是在桌面计算机上最常用的是两个补码。)
答案 1 :(得分:3)
如果我将值声明为signed或unsigned int,那真的很重要吗?
是
例如,看看
#include <stdio.h>
int main()
{
int a = -4;
int b = -3;
unsigned int c = -4;
unsigned int d = -3;
printf("%f\n%f\n%f\n%f\n", 1.0 * a/b, 1.0 * c/d, 1.0*a/d, 1.*c/b);
}
及其输出
1.333333
1.000000
-0.000000
-1431655764.000000
这清楚地表明,如果我将相同的字节表示解释为有符号或无符号,则会产生巨大的差异。
答案 2 :(得分:3)
Representation of signed integers取决于底层平台,而不是C语言本身。对于有符号整数表示,语言定义主要是不可知的。 Two's complement可能是最常见的,但还有其他表示形式,例如one's complement和signed magnitude。
在双补码系统中,您通过反转位并添加1来否定一个值。要从5
转到-5
,您可以执行以下操作:
5 == 0101 => 1010 + 1 == 1011 == -5
要从-5
返回5
,请按照相同的步骤操作:
-5 == 1011 => 0100 + 1 == 0101 == 5
如果我将值声明为signed或unsigned int,那真的很重要吗?
是的,原因如下:
它会影响您可以表示的值:无符号整数可以表示从0
到2N-1
的值,而有符号整数可以表示-2N-1
和2N-1-1
之间的值(两个补充)。
对于无符号整数,溢出是明确定义的; UINT_MAX + 1
将&#34;包裹&#34;回到0
。对于有符号整数,溢出不定义良好,INT_MAX + 1
可以&#34;换行&#34;到INT_MIN
,或者可能不是。
由于1和2,它会影响算术结果,特别是如果在同一个表达式中混合有符号和无符号变量(在这种情况下,如果出现溢出,结果可能无法很好地定义)。
答案 3 :(得分:1)
#include <stdio.h>
int main(){
int x = 35, y = -35;
unsigned int z = 35, p = -35;
signed int q = -35;
printf("x=%d\tx=%u\ty=%d\ty=%u\tz=%d\tz=%u\tp=%d\tp=%u\tq=%d\tq=%u\t",x,x,y,y,z,z,p,p,q,q);
}
结果是: x = 35 x = 35 y = -35 y = 4294967261 z = 35 z = 35 p = -35 p = 4294967261 q = -35 q = 4294967261
int数字存储没有区别,它与补充样式存储在内存中,
我可以使用0X ... 0X00000023中的35和0Xffffffd中的-35,使用sigend或unsigend没有区别。它只输出不同的风格。 %d和%u关于正数没有差异,但是负数第一个位置是符号,如果输出%u是0Xffffffdd等于4294967261,但%d 0Xffffffdd可以是 - 0X00000023等于-35。
答案 4 :(得分:-1)
变量类型定义的最基本的东西是它在内存中的存储方式(即 - 读取和写入)以及如何解释这些位,因此您的语句可被视为“有效”。
您还可以使用转化来查看问题。在无符号变量中存储有符号和负值时,它将转换为无符号。碰巧这种转换是可逆的,因此签名-35转换为无符号4294967261,当你请求时,它可以转换为有符号-35。这就是2的补码编码(见其他答案中的链接)的作用。