zoukankan      html  css  js  c++  java
  • 听翁恺老师mooc笔记(13)--类型定义和联合

    typedef

      虽然我们知道使用struct这个关键字定义一个结构类型,然后可以使用该结构类型定义变量。但是每次要使用的时候都需要带着struct这个关键字,那么如何摆脱这个关键字哪?C语言提供了一个叫做typedef的功能来声明一个已有的数据类型的新名字,typedef也是个关键字,比如:

    typedef int Length;
    

      意思是Length是int类型的别名,可以代表int。在程序的变量定义或者参数声明时,如果出现Lenght就是表示int:

    Length a,b,len;
    Length numbers[10]; //相当于int numbers[10]
    

      再比如:

    typedef long int64_t;  //typedef后面跟着两个东西,一个是原来的实际的数据类型,第二个东西是你给起的新名字
    typedef struct ADate{
        int month;
        int day;
        int year;
    }Date;                    //所以这个Date是新名字,typedef和Date之间的所有的东西是原来的数据类型,这块原来的类型是struct
    
    int64_t i=10000000000;    //相当于 long i=100000000000;
    Date d = {3,29,2017};     //相当于struct ADate d = {3,29,2017};
    

      所以typedef的作用是声明一个数据类型的新名字,新名字相当于该数据类型的别名,改善了程序的可读性。
      再看下面的代码,是怎么回事哪:

    typedef struct{    
        int month;
        int day;
        int year;
    }Date;
    

      如果没有typedef,那么是使用一个没用名字的结构定义了一个变量Date,那么加上typedef,实际意思是将没用名字的结构定义为Date,它有了一个新的名字,至于这个结构叫什么名字就无所谓了。
      typedef有的时候你会看到很复杂,但是只要知道最后一个单词是新名字。比如:

    typedef *char[10] Strings;//Strings是10个字符串的数组的类型
    typedef struct node{
        int date;
        struct node *next;
    }aNode;             //aNode是新的名字
    

    联合

      和struct非常相似的一个东西是union,union的用法和struct是非常相似的:

    union AnElt{
        int i;
        char c;
    }elt1,elt2;
    
    elt1.i=4;
    elt2.a='a';
    elt2.i=0xDEADBEEF;  //将elt2.a中的值给冲刷掉
    

      和struct不同的是,struct中的两个成员是分开的,是可以随意使用的。但是对于union来说,这两个成员占据了同一个空间,即使有3,4个成员,每个成员占据的空间都是一份,所以称为联合,大家联合起来使用同一个空间,怎么使用?如果第一个成员使用了,第二个就会把第一个给覆盖掉,但是第一个成员的值还在,呃呃呃呃这是什么东西?实际上联合在存储的时候,所有成员共享一个空间,同一时间只有一个成员是有效的,union的空间是其最大成员的大小。对联合进行初始化的时候,只需对第一个成员做初始化。
      下面看union的常用应用场合:

    #include <stdio.h>
    typedef union{
    	int i;
    	char ch[sizeof(int)];
    }CHI;
    
    int main(int argc,char const argv[]){
    	CHI chi;
    	int i;
    	chi.i=1234;
    	for (i=0;i<sizeof(int);i++)
    		printf("%02hhX",chi.ch[i]); //%02hhX是格式符,这部分在文件章节详细讲解,大概的意思是输出16进制,并且这是一个字节,不要给我们做扩展,显示两个16进制数字的方式,如果前面不到10就补充0,
    		
    	printf("
    ");
    	return 0;
    } 
    

      使用typedef将一个联合重命名为CHI,在主函数中定义CHI类型的变量chi,然后chi.i赋值1234,那么1234这个10进制数据化为16进制为:0x04D2,因为union中每个成员共用一个空间,所以chi.ch这个数组中的内容也是0x04D2,该数组共有sizeof(int)个,也就是4个,那么chi.ch[0]=00,chi.ch[1]=00,chi.ch[2]=04,chi.ch[3]=D2。为了验证我们的想法,编译运行程序结果是:

    FFD2040000
    
    --------------------------------
    Process exited after 0.008268 seconds with return value 0
    请按任意键继续. . .
    

      和我们想的有一点不一样,顺序是反过来的,chi.ch[0]=D2,chi.ch[1]=04,chi.ch[2]=00,chi.ch[3]=00,这主要因为在x86计算机中,数据的存储是小端存储方式,低位数据在高地址内存空间,高位数据在低地址内存空间。
      上述就是union常用场合,通过union得到一个整数内部的各个字节,同样通过这种方式可以得到double内部的各个字节等,这是一个有趣的工具,比如在做文件操作的时候,或者将一个数以2进制的形式写入到一个文件中的时候就需要用到。

  • 相关阅读:
    MySQL中TIMESTAMP和DATETIME区别
    图片标签的alt与title区别
    DEDE自带的采集功能,标题太短的解决方法
    Modernizr——为HTML5和CSS3而生!
    InnoDB,MyISAM,Memory区别
    Innodb,MyIsam,聚集索引和非聚集索引
    聚集索引与非聚集索引的总结
    程序kill -9与kill -15的区别,以及回调函数的作用
    linux 信号 SIGINT SIGTERM SIGKILL区别
    oracle mysql sqlserver 查看当前所有数据库及数据库基本操作命令
  • 原文地址:https://www.cnblogs.com/c-programing-language/p/6637601.html
Copyright © 2011-2022 走看看