• C语言学习笔记(4)—— 数据类型的使用


     在程序设计语言里,我们会把数据分为各种各样的类型,为什么会有数据类型之分呢?计算机中,所有的数据都会表示成二进制数的形式,对于同样的一个二进制数,数据类型不同,它表示的数据就是不同的。也就是说,同样的一个二进制数。我们可以把它”翻译“成不同的数。

      使用一个数据类型的数据的时候,需要注意的问题大概有以下几种:(1)数据溢出

                                    (2)精度问题

                                    (3)强制转换

     (1)数据溢出     

      

    #include <stdio.h>
    int main()
    {
      char d = 255;
      printf("%d",d+1);    
      return 0;  
    }

      这段代码的输出为0,其实原理很简单。char类型的数据相当于1个字节的无符号整形,即char型数据的范围是00000000~11111111,相当于十进制里的0~255。

      程序中的d是char型数据的最大值,给d加1后,d = 100000000(二进制),由于d是char型数据,所以最高位的1会被计算机丢掉。

      因此,d = 00000000(二进制),即 d = 0;转化为int型数据后,值依旧是0。

     (2)精度问题

    #include <stdio.h>
    int main()
    {
      float a = 0.1;
      for(int i = 0;i < 100;i++){
        a += 0.1;
      }
      printf("%f",a);       
      return 0;      
    }

      运行这段代码,结果可能会有点出人意料。printf函数打印的结果是

      

      我们的代码是没有问题的,它将100个0.1相加,结果是10。计算机内部的数据是用二进制表示的,十进制永远无法精确的表示1/3(三分之一),正如二进制

      永远无法精确的表示0.1,只能是一个无限循环小数。

      谈到无限,在计算机内部,资源总是有限的,我们只能用有限的内存来表示数据,所以,不管是什么类型的数据,它都是有范围的,所以,计算机内部不能准

      确的表示一些小数,只能将它控制在一定的精度内。所以我们就看到了这样的运行结果。

      那么,如何避免这种精度缺失的问题呢,我们可以把小数,当作整数来算,将一个小数适当的放大,把它变成整数。举个例子,0.1*10 = 1,这样,我们就把一

      个难以表示的0.1进行了转化,然后对计算结果适当的缩小,就可以得到我们想要的结果。我们可以修改上面程序,像这样:

    #include <stdio.h>
    int main()
    {
       float a = 0.1;
       a *= 10;
       for(int i = 0;i < 100;i++){
            a += 1;
       }  
       printf("%f",a/10);  
       return 0;  
    }

      (3)强制类型转换

        简单的概括一下强制类型转换,相对来说,由存储空间小的类型转向存储空间大的类型时,不会发生一些数据溢出,丢失之类的问题,一般来说,危险的转换发

        生在存储空间大的类型转换为存储空间小的类型。如double->int,float->int,int->char;

          这些时候,程序的结果,往往是出人意料的。 

    #include <stdio.h>
    int main()
    {
       printf("%u
    ",unsigned(-1));  
       return 0;  
    }
    
    

      运行结果为,是不是有一些出乎意料。我们来分析一下这段代码,int型的-1在计算机内部的表示形式为11111111111111111111111111111111(32个1),在将它转换为unsignefd型数据时,它就会被表示为11111111111111111111111111111111(32个1),

      这样的话,结果就成了2^32-1,即4294967295,这也是int型数据的最大值。


      
    
    
    
    
    
    

      

      

  • 相关阅读:
    rocketmq 命令示例
    原 荐 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控
    业务系统中最核心的状态设计,异常 case. (系统设计)
    大数据架构分析
    开源 java 电商系统
    数据一致性对账平台架构
    管理中遇到的问题--人,组织上的问题
    腾讯后台开发面试题
    理解inode
    TCP序列号和确认号
  • 原文地址:https://www.cnblogs.com/zhuxingtian/p/9788885.html
Copyright © 2020-2023  润新知