c语言 unsigned int

在c语言中如果我事先声明此变量为unsigned int a;这时我再让 a=-67;为什么还成立呀,不是事先声明了无符号的吗??再赋值为负数为什么没问题呀??那有符号跟无符号除了范围不一样其他的不都一样了,,都可以表示负值??

数值在内存当中存放,就是以二进制形式存在。注意这里这是一种状态。
十进制对于人而言有正负之分,而对于计算机来说却没有,十六进制没有负号,二进制也没有,但同一个数表示的状态必然是一样的。十进制的-67对于十六进制来说是多少?对于unsigned int型来说,是FFBD(这个自己可以用电脑上自带的计算器转换)。不要觉得奇怪,它们是同一个数,在内存当中存放的状态是一样的,只是对于人而言不一样而已(对人来说有正负之分)。而C语言中的十进制也人性化,但终究会是对计算机“机性化”(比喻一下,呵呵),它就是一个规则,一个数值在它指定的范围内兜圈子。比如你上述所说的,unsigned int 的a,它的范围是多少?当然是0到65535,那对于int的这个-67呢?当然是-32768到32767,既然前面是unsigned int的,而-67本身是int型的,那就兜圈子呗,过了就溢出,溢出就从最小那个开始,对号入座嘛。

另外,负数在内存当中以补码形式存在,至于补码怎么求,我不想详细讲,告诉你简单的步骤:
1、取绝对值,2、取反,3、加1。
然而正数却是以源码存放在内存,所以你用一个unsigned int 的变量去读取一块int 的内存,当然结果超乎想象。自己对-67求一下补码,是不是FFBD?呵呵。追问

"既然前面是unsigned int的,而-67本身是int型的,那就兜圈子呗,过了就溢出,溢出就从最小那个开始,对号入座嘛。”这句话不是太懂,,是咋个兜圈子呀,,我声明是unsigned 型,,输入为-67,关键计算的结果还是对的,,好像超出一定范围的负值它才会兜圈子???

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-02-13

编译器会把-67转化为无符号整型存储到a所在的地址里。

你可以试着使用

printf("%u\n", a);

来试探编译器的行为。

理论上来说,既然你定义了一个无符号整型变量,你就对这个变量负责。对其赋值负数,属于人为的bug,应该尽量避免,编译器可能会发出警告,但是不会把它当作一个错误。

追问

你的意思就是我用unsigned int 与int的意义是一样的,,起码对计算机来说是这样的,,那也就是我都用unsigned int 范围还更大,,不容易出现数据溢出??

追答

意义是不一样的。既然你定义了unsigned int,那么你应该对这个定义负责。你用int赋值给unsigned int变量,编译器没有把这个操作当作错误而已,但是编译器一般会显示警告,告诉你这个操作带来的风险,作为一个程序员,应该尽量规避这样的操作,养成良好的代码习惯。

第2个回答  2014-02-13
很多人都说C语言是弱类型语言,这是一个例子。
你可以把一个 int 类型的数赋值给 unsigned int 类型的变量。不过预先说明,产生的结果一定比 int 能表示的最大的数还大追问

那也就是说我都用unsigned int 会更好,,还不容易出现数据溢出??

追答

C语言的无符号数没有溢出之说

当然如果你觉得 “负一比任何正数都大” 是 “好” 情况的话,随意

追问

关键我现在输入负值结果是对的,,比如—69,,之后输出的值正确,,但是如果负值较小,,才有问题??

关键我现在输入负值结果是对的,,比如—69,,之后输出的值正确,,但是如果负值较小,,才有问题??

追答

你就是给 printf 一个字符,它也能当有符号数输出了,另外 scanf 也不会(实际上是无法)检查参数的类型。不过在任何其他情况下,把任何负数赋给unsigned int 类型的变量都有问题。

如果你的变量不用大于或小于号比较大小,不取相反数,不做任何其他数学运算,不使用API,大概有可能永远不会看到问题……

追问

非常感谢,,我是个新手,,感谢赐教了

本回答被提问者和网友采纳
第3个回答  2014-02-13
虽然你将a的值赋为-67后没有报错,但是在计算机运算的时候是按照补码运算,将-67的补码作为了正数来计算,所以结果跟你预期的不一样
第4个回答  2015-10-29
  unsigned int类型相加的情况。
没有强制转换。
UINT+UINT INT+INT UINT+INT 对于加法器(CPU内部)
是完全相同的。Computer的设计者非常巧妙的统一了他们:
使用反码代替负数。

(32位INT情况下)
-1 和 0xFFFFFFF 是物理等价的。
-2 和 0xFFFFFFE 是物理等价的。
(-1)+(-2) 加法器回答是 0xFFFFFFF + 0xFFFFFFE =
0xFFFFFFFD 和(-3)是物理等价的。

所以关键是结果是什么类型,而不是2个输入是什么类型。
加法减法都没有问题。但是比较大小必须注意要同类。要看编译器了。
相似回答