当前位置: 首页 > news >正文

做内容网站好累/微信公众号运营推广方案

做内容网站好累,微信公众号运营推广方案,浙江沉船事故最新消息,企业门户网站的主要技术指标看linux内核代码很多地方都用到了container_of,乍一看它的定义,感觉有点懵,不过实际了解了却发现实现的非常简单,由这个宏引发了我几点感慨: ①一行代码的威力竟有如此之大 ②开发内核的大佬,恐怖如斯 ③…

看linux内核代码很多地方都用到了container_of,乍一看它的定义,感觉有点懵,不过实际了解了却发现实现的非常简单,由这个宏引发了我几点感慨:

①一行代码的威力竟有如此之大

②开发内核的大佬,恐怖如斯

③没事要多看看内核代码

为何会有这些感慨,且听我细细道来...

一行代码的威力

说到一行代码的威力,且看container_of(ptr, type, member)宏的作用,定义如下:

/*** container_of - cast a member of a structure out to the containing structure** @ptr:        the pointer to the member.* @type:       the type of the container struct this is embedded in.* @member:     the name of the member within the struct.**/
#define container_of(ptr, type, member) ({                      \const typeof( ((type *)0)->member ) *__mptr = (ptr);    \(type *)( (char *)__mptr - offsetof(type,member) );})

该宏的作用就是通过结构体中一个成员的地址(ptr),以及该成员的类型(type)与名字(member)获得该结构体的地址,从而访问该结构体中其它成员,对,就这么简单,这个类似面向对象中通过父类指针访问子类对象成员,也就是说通过container_of从c语言的面向过程编程直接过渡到了面向对象编程,也就是因为这个宏,linux内核发生了天翻地覆的变化...

container_of(ptr, type, member)的简化

看了container_of的定义,第一行就是一个指针赋值,功能上面没有起什么作用,我们可以简化一下变为:

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

简化之后的功能完全是一样的,等会我们再讲去掉的那行的含义,了解container_of这个宏就是了解 (type *)( (char *)ptr - offsetof(type,member) )这行代码了,而了解这行代码我们需要先来了解一下offsetof这个宏

offsetof宏

前面的(char *)ptr我们知道是将ptr指针强制转换为char*型指针,就是转换为字节型的好计算,后面的offsetof这个宏定义如下:

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

这个宏的意思就是将0地址强制转换为(TYPE *)结构体指针类型,然后->MEMBER是指向MEMBER成员,然后&是将该成员的地址取出来,实际就是相对结构体0地址的偏移位置,最后转换为size_t类型,size_t一般为长整型,整个过程如下:

					 0			    //0地址((TYPE *)0)			    //强制转换为(TYPE *)结构体指针(((TYPE *)0)->MEMBER)	//指向结构体成员&(((TYPE *)0)->MEMBER)	//取成员地址,就是相对0地址的偏移位置
((size_t) &(((TYPE *)0)->MEMBER)    //转换为size_t类型

总之,这个宏就是返回一个成员相对基地址的偏移位置。

然后整体看(type *)( (char *)ptr - offsetof(type,member) ),就是将结构体成员地址强制转换为字符型指针减去其相对结构体首地址的偏移量,最后在转换为(type *)类型指针,实际得到的就是结构体首地址.

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

最后我们来看一下去掉的那行代码的意义,const typeof( ((type *)0)->member ) *__mptr = (ptr); 

typeof在标准C中是不支持的,在gnu扩展语法中才可以支持;它的作用就是:比如定义 int a;

通过typeof(a)就可以返回int这个类型,typeof( ((type *)0)->member )这里就是获得成员member的类型,const typeof( ((type *)0)->member ) *__mptr = (ptr);就是定义了一个新的跟成员member类型一致的常指针__mptr,并且赋值指向ptr,这么做有何意义呢?直接使用ptr不就好了吗,多此一举?这么做是很有意义的,是为了防止开发人员使用container_of时,如果误传指针就会报错,从而减小开发出错的可能,这里不得不佩服开发内核的大佬实在是厉害,考虑问题的全面与细致,真是恐怖如斯~

移植与测试

这么好的宏怎么可能不把它移植到mcu上去呢,因为mcu编译器并不支持typeof,所以我就把中间那行直接去掉了,使用的时候就需注意别传错指针了,因为传错了也不会报错,注意就不会影响使用,代码如下:


#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) ( \(type *)( (char *)(ptr) - offsetof(type,member) ))struct test {int 	i;char 	c;float 	f;
};void test_container(void)
{struct test temp= {8, 'b', 22.6};struct test *tp = container_of(&temp.c, struct test, c);printf("&temp 	= %p\n",&temp);printf("&tp 	= %p\n\n",tp);printf("tp.i 	= %d\n",tp->i);printf("tp.c 	= %c\n",tp->c);printf("tp.f 	= %0.1f\n\n",tp->f);	printf("sizeof-c:%d\n", offsetof(struct test, c));
}

运行结果:

 移植成功,能得到预期的结果,,,

http://www.lbrq.cn/news/746695.html

相关文章:

  • 张家口网站建设张家口/网站加速器
  • 驻马店建设网站/网站推广平台搭建
  • 北京装饰网站建设/网站营销方案
  • 好人一生平安网站哪个好/站长素材官网免费
  • wordpress wizhi cms/seodao cn
  • 文化推广网站建设心得/seo属于运营还是技术
  • 吉安手机网站建设/注册推广
  • 织梦网站模板视频/html友情链接代码
  • 谷歌做英文网站/上海关键词排名软件
  • 张掖专业做网站的公司/温州网站建设
  • 做调查赚钱网站/职业培训机构
  • 青岛 两学一做 网站/网络广告营销典型案例
  • 设计公司网站什么重要/全案网络推广公司
  • 桂林网站seo/百度账号购买1元40个
  • 网站建设流程有哪七步/怎样利用互联网进行网络推广
  • 做赌博的网站违不违法/大连seo按天付费
  • wordpress批量删掉文章内的文字/抖音seo是什么意思
  • 网站建设属于移动互联网/南宁百度首页优化
  • 揭阳网站制作专业/网站排名系统
  • 无锡网站建设 网站制作/出词
  • 想让客户公司做网站的话语/广西seo公司
  • wordpress 下载站/小程序开发公司十大排名
  • 快速做彩平图得网站/外链推广软件
  • html5可不可以建设手机网站/制作电商网站
  • 北京公司请做网站工资/南宁关键词优化软件
  • 专业企业网站开发/网络推广赚钱平台有哪些
  • 做新闻微网站有哪些方面/web前端培训费用大概多少
  • 南昌建设企业网站公司/网络营销外包推广价格
  • 女人和男人做爰网站/营销方案网站
  • 网站建设加微信/守游网络推广平台
  • 可以一键生成PPT的AI PPT工具(最新整理)
  • 106、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(下)
  • 玳瑁的嵌入式日记D20-08019(数据结构)
  • 小程序插件使用
  • mq存量消息如何处理
  • 【LeetCode 热题 100】198. 打家劫舍——(解法二)自底向上