关于C语言中 char 型负数赋值给int

如果一个char 负数如-1在计算机中代码为1111 1111,那么把他赋值给int 型的数,int 是不是就变成了0000 0000 1111 1111 ,这就变成255了,对不对?如果不对,那负数不同类型之间是如何转换的?

错的,这个程序我亲自敲了代码,结果打印int型的数,结果也为-1,我想,原因可能如下:
都知道负数在计算机内部的存储形式为:取其绝对值的“反码”再加1,即:源码的反码加1
一、-1的源码:1
二、反码的情况(用二进制表示)
(1)若为1字节则为:1111 1110
(2)若为4字节的int型,则为:1111 1111 1111 1111 1111 1111 1111 1110
三、反码加1,即为:
(1)若为1字节则为:1111 1111
(2)若为4字节的int型,则为:1111 1111 1111 1111 1111 1111 1111 1111
所以,还是为-1

所以我的分析为:计算机存储负数都采用上面的规则,不管其占用几个字节。

还有关于 “蓝人poke”兄台所说的东西,我觉得需要更正一下:
这并不是“基本的运算都不能保证”,一个系统有自己的一套的法则。
我可以有办法让他显示为正数,代码如下:
char c=-1;
int b;
memset(&b,'\0',4);//将b的4字节存储单元清零,因为b没有初始化,其内存的值是随机的。
memcpy(&b,&c,1);//将c的内存的内容拷贝到b的内存当中去。
printf("%d\n",b);
这个时候肯定为正的了,这里将c的内存的值直接拷贝到b的内存当中。
要明白,计算机存储数据,并不是如上所示的简单的内存拷贝,他有自己的规则的

果然,输入上面的代码,得到的结果是:255,我敲代码亲自验证了的。追问

我看了上面的说法,感觉结果对的但原因可能不太多,昨天我问我一同学,他告诉我汇编处理这种数的时候会跟据最高位判断,比如,unsigned char 1111 1111 ,这是255,但是赋值给int的时候,因为int是有符号数,所以计算机会验证unsigned char的最高位,会赋值为1111 1111 1111 1111,但是如果是char 1111 1111 ,赋值给unsigned int,因为unsigned int为无符号,所以不验证符号位,得结果为255,说是强制转换引起的错误,不知对否

追答

int main()
{
unsigned char a = -1;
printf("%d\n", a);
}
上面的运行结果为:255,你自己可以试
所有说前面的声明“unsigned char a”无效,系统只会看“=”后的是不是实际的负数,如果是,则按照负数的存储规则(即:补码)来进行存储。又如:
int main()
{
unsigned char a = -1;
unsigned int b=(int)a;
printf("%d\n", b);
}
运行结果也是255,因为第二个等号后的“a”,在前面声明为(unsigned char),则按照正数的规则去存储,不把a的最高位当作符号位,而当作数据位。又如下面的:
int main()
{
unsigned char a =(unsigned char) -1;
unsigned int b=(char)a;
printf("%d\n", b);
}
运行结果为:-1

因此你同学说的,可以说对,但不确切。汇编我了解的不深,但是从上面的三个例子,可以看出,系统先判断等号右边的数,当为“-”开头,或者声明为:有符号时,按补码规则存储。
一切“听说”,我想都不可靠,还是自己敲代码验证吧!
还有,各个系统的编译规则也不尽相同,如:
struct a{ //空的结构体
}
sizeof(struct a)=?
在linux中得到的结果为:0,但是在VC中得到的结果为:1
所以还是那句话:还是自己敲代码验证吧!

追问

呵呵,真是麻烦你了,我电脑上没有VC,不好用这个验证,我搞控制算法,想用负数的,又担心算负数会出错,我上次因为追问限字数,没有说!

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-03-14
在正数前加1,为有符号型
第2个回答  2012-03-14
还是-1啊,怎么能这样转换呢,基本的运算都不能保证还能叫C语言吗?
相似回答