linux版本宏,Linux下的两个经典宏定义 转

http://www.linuxidc.com/Linux/2016-08/134481.htm

http://www.linuxidc.com/Linux/2013-01/78003.htm

http://blog.csdn.net/npy_lp/article/details/7010752

http://www.linuxdiyf.com/viewarticle.php?id=104768

本文首先介绍Linux下的经典宏定义,感受极客的智慧,然后根据该经典定义为下篇文章作铺垫。

offsetof宏定义:

// 获得结构体(TYPE)的变量成员(MEMBER)在此结构体中的偏移量。

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

说明:获得结构体(TYPE)的变量成员(MEMBER)在此结构体中的偏移量。

1.( (TYPE *)0 ) 将零转型为TYPE类型指针,即TYPE类型的指针的地址是0。

2.((TYPE *)0)->MEMBER    访问结构中的数据成员。

3.&( ( (TYPE *)0 )->MEMBER )  取出数据成员的地址。由于TYPE的地址是0,这里获取到的地址就是相对MEMBER在TYPE中的偏移。

4.(size_t)(&(((TYPE*)0)->MEMBER))  结果转换类型。对于32位系统而言,size_t是unsigned int类型;对于64位系统而言,size_t是unsigned long类型。

使用示例:

struct student

{

char gender;

int id;

int age;

char name[20];

};

int _tmain(int argc, _TCHAR* argv[])

{

int gender_offset, id_offset, age_offset, name_offset;

gender_offset = offsetof(struct student, gender);

id_offset = offsetof(struct student, id);

age_offset = offsetof(struct student, age);

name_offset = offsetof(struct student, name);

printf("gender_offset = %d\n", gender_offset);

printf("id_offset = %d\n", id_offset);

printf("age_offset = %d\n", age_offset);

printf("name_offset = %d\n", name_offset);

system("pause");

return 0;

}

//结果:

/*

gender_offset = 0

id_offset = 4 //字节对其

age_offset = 8

name_offset = 12

*/

offsetof图解

ec7521cfb6d8c543637cd829cb77fb44.png

TYPE是结构体,它代表"整体";而MEMBER是成员,它是整体中的某一部分。

container_of宏定义:

#define container_of(ptr, type, member) ({          \

const typeof( ((type *)0)->member ) *__mptr = (ptr);    \

(type *)( (char *)__mptr - offsetof(type,member) );})

说明:根据"结构体(type)变量"中的"域成员变量(member)的指针(ptr)"来获取指向整个结构体变量的指针。

1. typeof( ( (type *)0)->member )    取出member成员的变量类型。

2.const typeof( ((type *)0)->member ) *__mptr = (ptr)    定义变量__mptr指针,并将ptr赋值给__mptr。经过这一步,__mptr为member数据类型的常量指针,其指向ptr所指向的地址。

3. (char *)__mptr    将__mptr转换为字节型指针。

4. offsetof(type,member))    就是获取"member成员"在"结构体type"中的位置偏移。

5. (char *)__mptr - offsetof(type,member))    就是用来获取"结构体type"的指针的起始地址(为char *型指针)。

6.(type *)( (char *)__mptr - offsetof(type,member) )    就是将"char *类型的结构体type的指针"转换为"type *类型的结构体type的指针"。

7.反斜杠“/”表示行连接

Linux下的两个经典宏定义【转】

转自:http://www.linuxidc.com/Linux/2015-07/120014.htm 本文首先介绍Linux下的经典宏定义,感受极客的智慧,然后根据该经典定义为下篇文章作铺垫. of ...

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

Linux 下启动两个tomcat

Linux 下启动两个tomcat 闲来无事学习nginx,想要配置个load balance.可是先决条件是:得有两个web容器.两个电脑是不用想了.只能想办法在一个机器上启动两个tomcat.原以 ...

Linux下配置两个或多个Tomcat启动

Linux下配置两个或多个Tomcat启动 (2012-08-14 11:59:31) 转载▼ 标签: 杂谈 分类: linux_tomcat 步骤如下: (1)修改/etc/profile文件.添加 ...

Linux下的两种磁盘分区工具的使用

如何使用fdisk和parted分区工具来进行硬盘分区,下面我来说一下在Linux系统中这两种硬盘分区工具的使用方法:     ----------fdisk分区工具----------       ...

Linux下使用两个线程协作完成一个任务的简易实现

刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...

Linux 下的两种分层存储方案

背景介绍 随着固态存储技术 (SSD),SAS 技术的不断进步和普及,存储介质的种类更加多样,采用不同存储介质和接口的存储设备的性能出现了很大差异.SSD 相较于传统的机械硬盘,由于没有磁盘的机械转动 ...

Linux内核驱动基础(一)常用宏定义【转】

转自:http://blog.csdn.net/tommy_wxie/article/details/9427081 一: __init和__initdata  : __exit和__exitdata ...

Linux下对比两个文件夹的方法

最近拿到一份源代码,要命的是这份源代码是浅克隆模式的git包,所以无法完整显示里面的修改的内容. 今天花了一点点时间,找了一个在Linux对比两个文件夹的方法. 其实方法很简单,用meld 去对比两个 ...

随机推荐

有问题得就分享(此实现不是 Windows 平台 FIPS 验证的加密算法的一部分)

今天呢,我写完了MD5加密算法的代码,可是我正高兴的想运行时,按了F5.突然了个这样的窗体 我当时就纳闷了,怎么回事? 代码又没有错,这是乍回事! 于是呢上网查了看看:可以这样解决的 在window中 ...

Linux 路线 推荐

1.- 靠它来入门,然后装一个linux体系,练习shell(party)和linuxC,把基础打牢: 2. 和

关于有默认值的字段在用EF做插入操作时的思考

今天在用EF做插入操作的时候发现数据库中一个datetime类型的字段(CreateDate)的值居然全部为null.于是赶紧看表结构发现CreateDate字段居然是允许为空的. 虽然为空,但是设置 ...

Jmeter 中通过(_time函数)获取10位时间戳的方法

meter的__time函数作用是取当前时间的时间戳,默认取的时间精确到了毫秒级别,所以获取的时间戳默认是13位的.  下图为取10位的时间戳的函数表达式(时间精确到秒)

Activity启动方式

Activity启动方式有四种,分别是: standard singleTop singleTask singleInstance 可以根据实际的需求为Activity设置对应的启动模式,从而可以避免 ...

ABAP程序执行效率和优化 ABAP Performance Examples

一.             SQL Interface1.         Select ... Where vs. Select + Check用Select … Where语句效率比Select ...

基于jQuery的上下左右无缝滚动应用(单行或多行)

$(function(){     var _wrap=$('ul.line');//定义滚动区域     var _interval=2000;//定义滚动间隙时间     var _moving; ...

ZOJ 3818 Pretty Poem 模拟题

这题在比赛的时候WA到写不出来,也有判断ABC子串不一样不过写的很差一直WA 在整理清思路后重写一遍3Y 解题思路如下: 第一种情况:ABABA. 先判断开头的A与结尾的A,得到A的长度, 接着判断A ...

使用JDBC调用数据库的存储过程

本篇讲述如何使用JDBC来调用MySQL数据库中的存储过程.建议在学习如何使用JDBC调用存储过程前,请先了解如何在数据库中使用存储过程. 存储过程是指在数据库系统中,一组为了完成特定功能的SQL语句 ...

httpclient超时总结(转)

Httpclient超时 背景: 网站这边多次因为httpclient调用超时时间没设置好导致关掉,影响非常不好,而且问题重复出现,查看网络,没有比较明确介绍httpclient所有超时相关的设置(大 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值