美文网首页
2019-08-18数据类型

2019-08-18数据类型

作者: 嵌入式Linux小白 | 来源:发表于2019-08-19 08:23 被阅读0次

    1基本数据类型

    数据类型分为2类:基本数据类型、复合类型
    基本类型:char、short、int、long、float、double
    复合类型:数组、结构体、共用体、类(C无类,C++有)

    1.1内存占用与sizeof运算符

    数据类型就好像一个一个的模子,这个模子实例化出C语言的变量。变量存储在内存中,需要占用一定的内存空间。一个变量占用多少空间是由变量的数据类型决定的。
    每种数据类型,在不同的机器平台上占用内存是不同的,我们一般讲的时候都是以32位CPU为默认硬件平台来描述:

    数据类型 占用字节
    char 1字节
    short 2字节
    int 4字节
    long 4字节
    float 4字节
    double 8字节

    1.2有符号数与无符号数

    对于char、short、int、long等整型类型的数,都分有符号数和无符号数。而对于float与double这种浮点型数来说,只有有符号数,没有无符号数。
    对于C语言来说,数(也就是变量)是存储在内存中一个一个的格子中的,存储的时候是以二进制方式存储的。对于有符号数和无符号数来说,存储方式是不同的。
    如对于int来说,unsigned int无符号数32位(4字节)全部用来存储数的内容,范围是0~4294967295(2^32-1);signed int有符号数,32位中最高位用来存储符号(0表示正数,1表示负数),剩余31位用来存储数据,所以可以表示的数范围
    -2147483648~2147483647(2^31-1)
    总结:
    从绝对数值来说,无符号数所表示的范围要大一些,因为有符号数使用1个二进制来表示正负号。

    1.3整型数和浮点数型数存储方式上的不同

    对于float和double这种浮点类型的数,它在内存中的存储方式和整型数不一样。所以float和int相比,虽然都是4字节,但是在内存中存储的方式不同,所以同一个4字节的内存,如果存储时是按照int存放的,取得时候一定要按照int型方式去取。如果存的时候和取的时候理解的方式不同,那数据就完全错了。(好比你把人家当恋人,人家却把你当朋友。)
    总结:
    存储方式主要有两种:一种是整型,一种是浮点型。
    这两种存取方式完全不同,没有任何关联,所以绝对不能随意改变一个变量的存取方式,在整型与浮点型之间,如说4中整型char、short、int、long只是范围大小不同而已,存储方式是一摸一样的。float和double存储原理是相同的,方式上有差异,导致了能表示的浮点型的范围和精度不同。

    2空类型(关键字void)

    (1)C语言中的void类型,代表任意类型,而不是空的意思。任意类型的意思不是说想变成谁就变成谁,而是说它的类型是未知的,是还没指定的。
    (2)在函数参数列表和返回值中,void代表的含义是:一个函数形参列表为void,表示这个函数调用时不需要给它传参。返回值类型是void,表示这个函数不会返回一个有意义的返回值,所以调用者也不要想着去使用该返回值。(其实C语言都是有返回值,只不过因void不管了)
    (3)void *是void类型的指针。void类型的指针的含义是:这是一个指针变量,该指针指向一个void类型的数。void类型的数就是说这个数有可能是int,也有可能是float,也有可能是个结构体,哪种类型都有可能,只是我当前无法确定。
    void类型指针的作用就是,程序不知道那个变量的类型,但是程序员自己心里知道。程序员如何知道?当时这个变量赋值的时候是什么类型,现在取的时候就是什么类型。这些类型对不对,能否兼容,完全由程序员自己负责。编译器看到void就没办法帮你做类型检查了。
    代码参考

    int  main(void)
    {
        int  a  =  444;
        void  *pVoid;
        pVoid  =  &a;
        //printf("*pVoid  =  %d.\n", *pVoid);
        printf("*pVoid  =  %d.\n", *(int  *)pVoid);
        return  0;
    }
    

    注释句:直接这样写不太好,因为没有告诉printf是以char、short、int、long的哪种类型去取值,虽然内存中存的都是0和1,但是取的方式不同,结构就不同。
    执行句:所以最好先将指针变量强制类型转换成int类型,然后再去取数据,这时候就会根据int型4字节4字节的方式读取内存中的0和1的值,从而正确解析。
    (4)C语言设计的基本理念:
    C语言相信程序员永远是对的;C语言相信程序员都是高手;C语言赋予程序员最大的权力。所以C语言的程序员必须自己对程序的对错负责,必须随时闹到清楚自己在干嘛。这也是黑客最喜欢的语言。

    3数据类型转换

    C语言中有各种数据类型,写程序时需要定义各种类型的变量。这些类型需要参与运算。C语言有一个基本要求就是:不同类型的变量不能直接运算。也就是说,int和float类型的变量不能直接加减等运算,必须先把两种类型转换成相同的类型才可以。比如简单的6+6.5。

    隐式转换

    隐式转换就是自动转换,是C语言默认会进行的,不用程序员干涉。C语言的转换理念:隐式转换默认朝精度更高、范围更大的方向转换。所以隐式转换不会出现错误,只会出现精度问题。
    代码分析1:

    int  main(void)
    {
        int  a  =  3;
        float  b  =  3.5;
        printf("a+b=%f.\n",  a+b);    //6.500000
        printf("a+b=%d.\n",  a+b);    //0
        printf("a+b=%d.\n",  (int)(a+b));    //6
        printf("a=%d.\n",  a);    //3
        return  0;
    }
    

    逐步分析:
    (1)编译器发现a+b中a和b的类型不同。这时候两个要加,编译器会进行隐式转换把两个转成类型相同。根据隐式类型转换的规则,编译器构造了一个临时变量(如叫float f1),然后把f1赋值为a转换成float类型的值,但是本身的a还是int类型,不可能经历一次相加操作就把本质都变了。
    (2)之后参与运算时用f1和b相加,加完后得到一个临时变量(如叫float f2),f2=f1+b,这个临时变量再参与之后的运算。
    (3)题目中printf("a+b=%f.\n", a+b); printf中是%f,所以需要一个float类型的变量来打印。于是,f2直接拿去打印显示,得到结果6.500000
    代码分析2:

    //接着分析1的a、b
    int  c;
    c  =  a  +  b;
    printf("c=%d.\n",  c);
    结果等于:6
    

    逐步分析:
    (1)编译器发现a和b类型不同,于是隐式类型转换,将a转成float类型的临时变量f1;
    (2)f1+b,得到一个临时变量f2,值为float类型的6.500000;
    (3)c = f2,编译器发现c和f2的类型不相同,但是赋值时必须以等号=左边的类型为准,于是编译器隐式类型转换,将f2转成临时变量i,值为6,然后再将i赋值给c;
    (4)printf打印时发现%d,右边的变量c类型为int,编译器检查发现类型匹配,直接打印。

    强制类型转换

    C语言默认不会这么做,但是程序员我想这么做,所以我强制这么做了。

    4C语言与bool类型

    C语言中原生类型没有bool类型,C++中有。在C语言中如果需要使用bool类型,可以用int来代替。很多代码体系中,用以下宏定义来定义真与假。

    #define  TRUE  1
    #define  FALSE  0
    //除了0为假,其余(正负数)都为真。
    

    相关文章

      网友评论

          本文标题:2019-08-18数据类型

          本文链接:https://www.haomeiwen.com/subject/spzlsctx.html