zoukankan      html  css  js  c++  java
  • C语言中 有符号数、无符号数、整数溢出

    #include<stdio.h>
    void main()
    {
     int l=-1;
     unsigned int c=135;
    printf("%u
    ",l+c);
    }
    这个的结果134,而不是我之前认为的很大的正数,实际上需要注意的是-1(0xffffffff)被提升为unsigned int后是一个差1就溢出的unsigned int,所以相加后结果是134。但是如果l=-10000,那么结果就真是一个很大的正数了,因为不涉及溢出了。
    C语言中存在两种整数算术运算,有符号型和无符号型。无符号数运算:所有无符号数运算都是以2的n次方为模,(n是结果中的位数)。所以它不存在运算时的没有那种所谓的“溢出”,当它超过范围时,从零开始重新计数!当一个无符号数和有符号数计算的时候,有符号数会自动转化为无符号数参与运算!有符号数运算: 是可能发生“溢出”的,而且“溢出”的结果不固定。

         关于无符号数减去无符号数的用法错误:

    if ( i - j >=0) 假如i,j为无符号数,这样写可能会引发错误,即当i小于j的时候,这个式子仍然成立,因为无符号数始终是大于等于零的。例: if ( strlen( a ) >= 10) 与 if (strlen ( b ) -10 >= 0) 这两条语句是不相等的 ,因为strlen函数返回的是无符号数类型。

    2015年3月8日追加一点:今天看这个地方有些不明白在网上搜了一下资料发现,无符号数相减,如果被减数小于减数,那么结果会是一个非常大的无符号数,而不是一个想象中的有符号数。所以对于无符号数相减之前需要进行判断,最好做比较的时候使用 if ( strlen( a ) >= 10) 这种方式,而不要使用if (strlen ( b ) -10 >= 0) 这种方式。因为无符号数进行计算的结果还是无符号数;另外无符号数和有符号数计算时,有符号数会被强制转提升无符号数。

    例如以下这个例子很有意思:

    #include<stdio.h> 
    int main() 
    { 
    unsigned int a=6; 
    int b=-20; 
    printf("%d
    ",(a+b)>0); 
    
    } 

    这个小例子可以机器试一下。另外还有几道题不错我也附在最后。

    需要注意一点,我在进行程序编写的时候发现一个小问题:


    那么unsigned char与signed int相减呢?

    #include<stdio.h>
    void main()
    {
     unsigned char a;
     int b;
     a=0;
     b=2;
     printf("X=%d
    ",(a-b)>0);
    }

       ANSI C规定在无符号整数和有符号整数之间进行强制类型转换时,位模式不应该改变。类型转换并未改变对象的位模式,改变的是位模式的解释方式

        有符号数转换为无符号数时,负数转换为大的正数(可以理解为原值加上2的n次方),而正数保持不变。

        无符号数转换为有符号数时,对于小的数将保持原值,对于大的数则转换为负数(可以理解为原值减去2的n次方)。


    今晚在看C的时候突然想到如果把大于unsigned int的范围的数据赋予 该类型变量,printf出来会是什么样。

    void main()
    {
      unsigned int a;
      a=7000000000;
     printf("a=%d
    ",a);
     printf("a=%u
    ",a):
    }

    这两个结果是完全不一样的。


    几个小例子:

    题目一:

    int a = -1;

    unsigned int b = 1;

    printf("%d", a > b);

    结果输出:1

    因为无符号数与有符号数比较时,要将有符号数转化为无符号数,再来比较。a转化为无符号数后就是0xFFFFFFFF,肯定大于b

    题目二:

    char a = -1;

    unsigned char b = 1;

    printf("%d", a > b);

    结果输出:0

    奇怪了,怎么会这样?这是因为两者被提升为int了,a提升为int就表示-1,b提升为int 就是1,前者小于后者。注意了这里不是像题目一里一样简单的把char转化为unsigned char了

    题目三:

    int a = -1;

    unsigned char b = -1;

    printf("%d ", a < b);

    结果输出是:1

    原因在于要把b提升为int就是255当然大于-1了,unsigned char 先提升为int,送入int的低八位中,高位全部补零。

    题目四:

    char a = -1;

    unsigned int b = -1;

    printf("%d ", a == b);

    结果输出:1

    原因是char类型被扩展为unsigned int后与b相等,同为0xFFFFFFFF

    小于int的提升到int,int之后都是从signed -> unsigned

    对于浮点数来说,浮点数(float,double)实际上都是有符号数,unsigned 和signed前缀不能加在float和double之上,当然就不存在有符号数根无符号数之间转化的问题了。

    一定要记住如果需要使用有符号数时不要忘记强制转换

  • 相关阅读:
    一文搞定 Spring Boot & Shiro 实战
    CPU 到底是怎么认识代码的?涨姿势了!
    Java 可重入锁内存可见性分析
    大牛总结的 Git 使用技巧,写得太好了!
    厉害了,如何搭建一套自己的私有网盘?
    深入浅出 Java 中 JVM 内存管理
    SLA服务可用性4个9是什么意思?怎么达到?
    解决springboot配置@ControllerAdvice不能捕获NoHandlerFoundException问题
    mybatis多参数使用方法且其中有的参数是多个值使用in查询
    Optional导致的 java.util.NoSuchElementException: No value present
  • 原文地址:https://www.cnblogs.com/JSD1207ZX/p/9386280.html
Copyright © 2011-2022 走看看