zoukankan      html  css  js  c++  java
  • C语言学习笔记 _内存对齐大小端共用体等

    C语言学习笔记 _内存对齐大小端共用体等

    offsetof宏

    offset宏返回的是member元素相对于整个结构体变量的首地址的偏移量,类型是int:

    #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
    

    这个宏的原理是,在地址0处虚拟此结构体,然后用地址0的结构体指针获得member元素的地址,那么此地址的数值相当于是偏移量,因为从0出发的地址,偏移量就是其本身;

    container_of宏

    container_of宏返回指向整个结构体变量的指针,类型是(type *);

    ptr是指向结构体元素member的指针,type是结构体类型,member是结构体中一个元素;

    #define container_of(ptr, type, member) ({	
    	const typeof(((type *)0)->member) * __mptr = (ptr);	
    	(type *)((char *)__mptr - offsetof(type, member)); })
    

    此宏通过获取member的数据类型,和其地址ptr,定义与member相同类型的变量__mptr,注意代码中((type *)0)->member)只是为了定义一个结构体以获得member的变量类型,(之所以要这么复杂定义这个指针,是为了不改变ptr这个源指针)。最后利用此地址减去偏移量就可以得到结构体的地址了;

    通过此宏,可以从一个元素的指针的指针,得到整个结构体变量的指针,结合offset可以得到所有元素的指针;

    typeof关键字的作用是:得到变量的数据类型;

    共用体union

    共用体方式的使用方法和结构体基本一致;但是含义完全不同;

    共用体就是对同一块内存中存储的二进制不同的理解方式;也就是申明同一块内存的不同数据类型;

    sizeof共用体,得到的是各元素中占用内存最大的元素的大小;

    共用体方法可以用指针加强制类型转换来替代,如下所示:

    union student{
       int a;
       float b;
    };
    
    // 共用体方式
    union test t1;
    t1.a = 1123477881;
    printf("value = %f.
    ", t1.b);
    
    // 指针方式
    int a = 1123477881;
    printf("point mode: %f.
    ", *(float *)&a);
    

    大小端模式

    这是两种数据在内存种的存储方式:

    大端模式:数据高位存放于高地址,低位存放于低地址;

    小段模式:数据高位存放于低地址,低位存放于高地址;

    当不确定大小端模式的时候,通过union来判断大小端模式:

    union un {
      int a;
      char b;
    };
    
    // 判断函数
    int check(void) {
    	union un u1;
        u1.a = 1;
        return u1.b;
    }
    
    // 输出1则为小端模式,输出0则为大端模式
    printf("mode is %d.
    ", check());
    

    通过union方式判断大小端模式的依据是,int类型占用四字节,数据为00 00 00 01:

    大端模式下存放方式为:01 00 00 00;小端模式下存放的方式为:00 00 00 01;

    那么当把这段内存按照char读取的时候只会读取低地址的一个字节,于是大端模式下为0,小端模式为1;

    另外,位与运算、移位、强制类型转换不能用于检测大小端,因为编译器对其做了封装。

    枚举

    enum week {
    	SUM,	
        MON,
        TUE,
    };
    
    enum value {
    	TRUE = 12,	  
        FALSE = 13,
    };
    

    枚举相当于用符号代替数字,作用于全局,可直接使用。

    如果只声明符号,默认从0开始,也可以声明符号与数字。

  • 相关阅读:
    如何设置IIS实现无扩展名重写
    正则表达式基础知识
    Literal控件用法
    ajaxPro.dll基础教程
    PetShop的系统架构设计
    SQL点滴29—错误无处不在
    javascript中的正则表达式
    为什么开发环境如此之乱
    SQL点滴文章总结
    javascript读写cookie
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13261771.html
Copyright © 2011-2022 走看看