嵌入式开发知识点总结
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 请按任意键继续. . .
大小端:
小端模式:低地址存低字节的数据 大端模式:高地址存储低字节数据
通信系统的大小端:
通信双方的默契,先发/先接是高位还是地位?先发低字节叫小端,先发高字节叫大端。
网络字节序是大端模式
递归函数:函数直接或间接调用其函数本身
使用递归的原则:收敛性和栈溢出
递归与循环的区别:
递归清晰,易于理解。递归就是方便自己,难为机器。递归需时刻考虑收敛性和栈溢出的问题;
循环避免了函数的调用和传参和返回值的开销,效率高于递归。