B.Linux

灵魂构造师

导航

嵌入式开发知识点总结

offsetof和container_of宏

offsetof宏的作用:计算结构体中某个元素相对结构体首地址的偏移量

container_of宏的作用:知道结构体变量中某个成员的指针,反推这个结构体变量的指针

#include <stdio.h>
#define offsetof(type,member) ((int) &((type *)0)->member)
#define container_of(ptr,type,member) ({\
    const typeof(((type *)0)->member) *mptr = (ptr);\
    (type *)((char *)mptr - offsetof(type,member));})
//typeof关键字的作用:typeof(a)由变量a获得变量a的类型
typedef struct node{
    int a;
    double b;
    float c;
} n1;
int main()
{
    n1 s;
    float *p = &(s.c);
    printf("offsetof(c) = %d\n",offsetof(n1,c));
    printf("addr of s is %p\n",&s);
    printf("container_of(p,n1,c) = %p\n",container_of(p,n1,c));
    return 0;
    
}

 

offsetof(c) = 16
addr of s is 000000000023FE20
container_of(p,n1,c) = 000000000023FE20
结果

 

结构体和共用体:

相同点:共用体union和结构体struct类型声明、变量定义和使用方法很相似

不同点:结构体是多个独立元素(内存空间)打包在一起;union是一个元素(内存空间)的不同解析方式;

    union的sizeof测得的大小实际上是union各个元素中占用内存最大的那个元素大小,不涉及字节对齐的概念

#include <stdio.h>
union myun{
    int a;
    char b;
    float c;
    double d;
};
int main()
{
    union myun a1;
    a1.a = 97;
    printf("a1.a =%d\n",a1.a);
    printf("a1.b =%c\n",a1.b);
    printf("a1.d =%d\n",a1.d);
    printf("sizeof(a1) = %d\n",sizeof(a1));
    return 0;
}
a1.a =97
a1.b =a
a1.d =97
sizeof(a1) = 8

--------------------------------
Process exited after 0.7912 seconds with return value 0
请按任意键继续. . .
运行结果

 大小端:

小端模式:低地址存低字节的数据               大端模式:高地址存储低字节数据

通信系统的大小端:

通信双方的默契,先发/先接是高位还是地位?先发低字节叫小端,先发高字节叫大端。

网络字节序是大端模式

 C enum(枚举)

递归函数:函数直接或间接调用其函数本身

使用递归的原则:收敛性和栈溢出

递归与循环的区别:

递归清晰,易于理解。递归就是方便自己,难为机器。递归需时刻考虑收敛性和栈溢出的问题;

循环避免了函数的调用和传参和返回值的开销,效率高于递归。

 

posted on 2019-10-01 23:06  B.Linux  阅读(582)  评论(0编辑  收藏  举报