277955973 发表于 2012-11-7 13:14:43

C语言中为什么-1与0xFF不相等,求高手解释解释

之前没有注意过这个问题
今天在试的时候除了问题

看程序#include "reg51.h"

volatile signed char x;

void main()
{
    x = -1;//-1在内存中就是按着0xff储存的
    if( x == 0xff)//该等式不成立
    {
      x = -1;
    }
    if( x == -1 )//该等式成立
    {
      x = 0;
    }
   
    while(1);
}负数在单片机中采用补码存储
-1的补码就是0xff
但是为什么 x == 0xff不成立

277955973 发表于 2012-11-7 13:16:48

#include "reg51.h"

volatile signed char x;

void main()
{
    x = 128;//128在内存中就是按着0x80储存的
    if( x == 128)//该等式不成立
    {
      x = 128;
    }
    if( x == -128 )//该等式成立
    {
      x = 0;
    }
   
    while(1);
}还有这个代码也不行,顺带一起解释解释

liwei_jlu 发表于 2012-11-7 13:19:07

标准c语言里常量默认是32位 int类型
0xff貌似默认等同于 int 0x000000FF
if( x == 0xff) 要先把x转化成int也就是 0xFFFFFFFF吧。
c51里面,常量是32还是16位,忘记了。

试一试if( x == (signed char)0xff)

weixinal 发表于 2012-11-7 13:21:02

体现在RAM的是相同的,到c是在判断的时候肯定有考虑的。如果真相等的话就是编译器的bug了。看看汇编文件吧

mitchell 发表于 2012-11-7 13:21:42

搞不懂你这个程序是要干嘛,如果非要这样写的话。
    if( x == 0xff)//该等式不成立
    {
      x = -1;
    }

    if( x == 128)//该等式不成立
    {
      x = 128;
    }
会直接被优化掉的。

dr2001 发表于 2012-11-7 13:37:39

C很多运算需要进行整数类型提升,目标类型是signed int or unsigned int. -1和0xFF的提升结果不同。

xiaoqingy 发表于 2012-11-7 13:38:24

最高位是符号位

albert_w 发表于 2012-11-7 14:17:48

立即数提升了, 前面说的没错

277955973 发表于 2012-11-7 14:27:56

liwei_jlu 发表于 2012-11-7 13:19 static/image/common/back.gif
标准c语言里常量默认是32位 int类型
0xff貌似默认等同于 int 0x000000FF
if( x == 0xff) 要先把x转化成int ...

将0xff强制转换成(signed char),再去比较的确是可以的,我在单纯在看C的时候觉得这个理所当然是一个错误,如果结合汇编去看,C51编译器会根据我定的常量编译出不同的结果。比如二楼的程序,如果在#include "reg51.h"

volatile signed char x;

void main()
{
    x = 128;//128在内存中就是按着0x80储存的
    if( x == 128)//该等式不成立
    {
      x = 128;
    }
    if( x == -128 )//该等式成立
    {
      x = 0;
    }
   
    while(1);
}编译的结果是
    24: void main()
    25: {
    26:   x = 128;//128在内存中就是按着0x80储存的
C:0x0003    750880   MOV      x(0x08),#P0(0x80)
    27:   if( x == 128)//该等式不成立
C:0x0006    AF08   MOV      R7,x(0x08)
C:0x0008    EF       MOV      A,R7
C:0x0009    33       RLC      A
C:0x000A    95E0   SUBB   A,ACC(0xE0)
C:0x000C    FE       MOV      R6,A
C:0x000D    EF       MOV      A,R7
C:0x000E    6480   XRL      A,#P0(0x80)
C:0x0010    4E       ORL      A,R6
C:0x0011    7003   JNZ      C:0016#include "reg51.h"

volatile signed char x;

void main()
{
    x = 128;//128在内存中就是按着0x80储存的
    if( x == 127)//该等式不成立
    {
      x = 128;
    }
    if( x == -128 )//该等式成立
    {
      x = 0;
    }
   
    while(1);
}编译的结果是
    24: void main()
    25: {
    26:   x = 128;//128在内存中就是按着0x80储存的
C:0x0003    750880   MOV      x(0x08),#P0(0x80)
    27:   if( x == 127)//该等式不成立
C:0x0006    E508   MOV      A,x(0x08)
C:0x0008    B47F03   CJNE   A,#0x7F,C:000E
    28:   {

这个我似懂非懂..琢磨不透

277955973 发表于 2012-11-7 14:30:21

dr2001 发表于 2012-11-7 13:37 static/image/common/back.gif
C很多运算需要进行整数类型提升,目标类型是signed int or unsigned int. -1和0xFF的提升结果不同。 ...

应该就是这个立即数提升的问题
C51中这个立即数提升成16位的还是32位的呢

277955973 发表于 2012-11-7 14:31:03

albert_w 发表于 2012-11-7 14:17 static/image/common/back.gif
立即数提升了, 前面说的没错

关于这个立即数提升能不能麻烦您详细的讲一讲呢

ibichao 发表于 2012-11-7 14:42:06

本帖最后由 ibichao 于 2012-11-7 14:43 编辑

volatile signed char x 改成03.volatile usigned char x,或if( x == (signed char)0xff)就等了,这个属于参数类型不匹配的范畴。





ztrx 发表于 2012-11-7 15:01:38

if( x == (signed char)0xff)

    {
      x = -1;
    }
这样就没问题了

devcang 发表于 2012-11-7 15:09:47

if( x == -1 )//该等式成立


都用变量,就会成立了。默认的一个数,和编译器有关,一般默认应该是int类型的。

dr2001 发表于 2012-11-7 22:46:04

什么操作需要整数类型提升以及如何进行整数类型提升,请参考C语言标准。

提升默认结果是int类型。
x == -1,-1是signed int,所以x的signed char提升成signed int。相等。
x == 0xff,0xff也是signed int,是值255,所以x提升成signed int,-1 != 255。

对右侧的常数进行强制类型转换会完成int -> Type -> signed/unsigned int的隐含转换过程。结果就没问题了。

barryliu 发表于 2012-11-13 02:50:25

编译器很笨的,看到源代码里有-1和0xff,直接认为不相等给优化掉了吧

millwood0 发表于 2012-11-13 06:58:43

    if( x == 0xff)//该等式不成立You do not understand integer promotion: google it or read K&R.

Essentially, all arithmatic calculations are done in integer. So 0xff is promoted to integer (->0x00ff, a positive number) before it is compared with x.

If you want, recompile your code this way:    if( x == (signed char) 0xff)//该等式不成立
页: [1]
查看完整版本: C语言中为什么-1与0xFF不相等,求高手解释解释