几个有关于结构体的宏
检测系统错误的宏。
#include <stdio.h>
#include <stdlib.h>
#define handle_error(msg) \
do{perror(msg); exit(EXIT_FAILURE);}while(0)
//perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字
//符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno(这里的说法不
//准确,errno是一个宏,该宏返回左值) 的值来决定要输出的字符串。
//在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某
//些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和
//现在的errno所对应的错误一起输出。
//C 标准定义了两个值 EXIT_SUCCESS 和 EXIT_FAILURE,可以作为 exit()
// 的参数,来分别指示是否为成功退出。
//exit(参数)传递给的是父进程,或者shell终端
#define FUNC printf("所在文件%s所在行数%d.\n", __FILE__, __LINE__)
int main(void)
{
int fd = -1;
int ret = close(fd);
if(ret == -1)
{
handle_error("file error.\n");
}
return 0;
}
两个有关于内核的结构体的宏
/*
linux内核里的两个宏:在驱动应用中很广泛。
off_set_of(type, member)计算结构体内元素的偏移量
containe_of(ptr, type, member),ptr是结构体里成员的指针,通过调用这个宏计算出结构体的首地址.包含两句代码(表达式),必须要加{}.
这两个宏:内核双链表。
*/
//分析: 1、(type *)0指向结构体零地址
2、((type *)0)->member得到了结构体某个成元变量名 \
3、给这成员变量名,取地址(相对于零地址),此时&(((type *)0)->member)表示是指针类型 \
4、强制类型转换成(long)。
5.最后得到结构体的首地址
#define off_set_of(type, member) ((long)&(((type *)0)->member))
//分析:1、得到结构体成员变量的类型 2、指针赋值(得到真实成员变量的地址值)
// 3、减去偏移量得到一个数字,该数字和结构体本身首地址在数值上一样
//4、最后强制类型转换为结构体指针类型
#define container_of(ptr, type, member) \
({typeof(((type *)0)->member) *_mptr = ptr; \
(type *)((char *)_mptr-off_set_of(type, member));})
#include <stdio.h>
struct da
{
int a;
short b;
int c;
double e;
};
struct data
{
char a;
short b;
int c; // 8
// float d; // 8
double e; // 8
struct da s; // 16
char ch;
}s = {1, 3, 10, 3.14, 1.41};
int main(void)
{
printf("sizeof(s) = %d.\n", sizeof(s));
//结构体自身的首地址
printf("&s = %p.\n", &s);
struct da *p = container_of(&s.s.b, struct da, b);
printf("p = %p.\n", p);
printf("&s.s = %p.\n", &s.s);
//计算结构体的某个元素的偏移量。
int off = off_set_of(struct data, c);
printf("off = %d.\n", off); // off 4
off = off_set_of(struct data, d);
printf("off = %d.\n", off); // off 8
off = off_set_of(struct data, e);
printf("off = %d.\n", off); // off 16
double *p_e = (double *)((char *)&s+off);
printf("*p_e = %.2f.\n", *p_e);
printf("&s = %p.\n", &s);
//计算结构体的首地址。
return 0;
}