前言

本文讲解typeof( ((type *)0)->member )的含义,并在此基础上学习offset_of()的用法。
typeof( ((type *)0)->member )

ANSI C标准允许值为0的常量被强制转换成任何一种类型的指针,并且转换的结果是个NULL,因此((type *)0)的结果就是一个类型为type *的NULL指针.

如果利用这个NULL指针来访问type的成员当然是非法的,但typeof( ((type *)0)->member )是想取该成员的类型(有关typeof()的用法可参考这里),所有编译器不会生成访问type成员的代码,类似的代码&( ((type *)0)->member )在最前面有个取地址符&,它的意图是想取member的地址,所以编译器同样会优化为直接取地址。

struct apple{
    int weight;
    int color;
};

int main(int argc, char *argv[])
{
    int weight = 5;

typeof(((struct apple *)0)->weight) *ap1 = &weight;//定义一个指针变量ap1, ap1的类型为apple成员weight的类型。
    printf("ap1's value:%d\n", *ap1);
}

printf("%d\n", offset_of(struct apple, color));

[root@xxx c_base]# ./a.out
ap1's value:5

offset_of()

理解了以上内容后再看offset_of(),它的作用是获取结构体中某个成员相对于该结构体首元素地址的偏移量。

#define offset_of(type, memb) \
        ((unsigned long)(&((type *)0)->memb))

比如想知道sruct apple中的color是在结构体中的哪个位置,可以这么做:

printf("colore offset addr:%d\n", offset_of(struct apple, color));

[root@xxx c_base]# ./a.out
colore offset addr:4

如上结果表示colore成员在结构体apple中的偏移地址是4.
参考文章

int( (LONG)(LONG_PTR)&(((type *)0)->field))的最好解释
    C 中&(((TYPE *)0)->member) 中指针为0 为什么不会报错?
————————————————
版权声明:本文为CSDN博主「sweird」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rosetta/article/details/90746936

C语言高级用法---typeof( ((type *)0)->member )和offset_of()的更多相关文章

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

    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的运行机理:1. ( (TYPE *)0 ) 将零转型为TY ...

  2. #define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

    #include <iostream> #define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) usi ...

  3. Jmeter 中JSON Path Extractor高级用法

    好久没玩jemter了,由于项目原因又重新拾起.在使用JSON Path Extractor(jmeter 4.0已经默认支持了,4.0以下要自行安装插件)时,可以进行条件过滤,不用再自行写shell ...

  4. Flask - 模板语言jinja2 和render_template高级用法

    目录 Flask - 模板语言jinja2 和render_template高级用法 一. 字典传递至前端 二. 列表传入前端Jinja2 模板的操作: 三. 大字典传入前端 Jinja2 模板 四. ...

  5. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  6. C# 语言规范_版本5.0 (第1章 介绍)

    1. 介绍 C#(读作“See Sharp”)是一种简洁.现代.面向对象且类型安全的编程语言.C# 起源于 C 语言家族,因此,对于 C.C++ 和 Java 程序员,可以很快熟悉这种新的语言.C# ...

  7. Newtonsoft.Json高级用法之枚举中文转义

    最近看博客园中 焰尾迭的两篇关于"Newtonsoft.Json高级用法"的文章受到了很多人的评论,一度登入到头条推荐. 今天我就不再重复焰尾迭博文中的一些提过的Newtonsof ...

  8. TypeScript高级用法详解

    引言 作为一门强大的静态类型检查工具,如今在许多中大型应用程序以及流行的JS库中均能看到TypeScript的身影.JS作为一门弱类型语言,在我们写代码的过程中稍不留神便会修改掉变量的类型,从而导致一 ...

  9. 再谈Newtonsoft.Json高级用法

    上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...

随机推荐

  1. 【MM系列】SAP技巧之更改布局

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP技巧之更改布局   前言部分 ...

  2. KVM虚拟化原理

    CPU虚拟化 KVM虚拟化是需要硬件支持的.我们可以用 egrep -o '(vmx|svm)' /proc/cpuinfo 来查看是否支持CPU虚拟化. 虚拟机中每一个vCPU对应qemu-kvm中 ...

  3. sqlalchemy orm 层面删除数据注意

    #encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text ...

  4. docker 使用阿里云免费仓库

    阿里云为开发人员提供了免费的仓库~~ 登录阿里云 ,选择容器镜像服务,当前是2019/08/13 ,之后不知道阿里云控制台菜单会不会调整哈 进入容器镜像服务菜单,创建仓库,需要绑定git仓库 怎么上传 ...

  5. [转帖]JVM总结--JVM体系结构

    JVM总结--JVM体系结构 https://blog.csdn.net/samjustin1/article/details/52215274 需要不断的学习才可以. 2016年08月15日 22: ...

  6. 统计sql server 2012表的行数

    --功能:统计sql server 2012表的行数 SELECT a.name, a.object_id, b.rows, b.index_id FROM sys.tables AS a INNER ...

  7. Python学习【day05】- Python文件处理

    一.打开文件 对文件的操作主要为三步:1.打开文件,得到文件句柄.2.通过句柄对文件进行操作.3.关闭文件 # 默认打开模式为r,encoding默认为系统文件编码 f=open('F:/Go.txt ...

  8. 面向服务架构之RPC原理与实例

    1.RPC概述 RPC(Remote Procedure Call)即远程过程调用,允许一台计算机调用另一台计算机上的程序得到结果,而代码中不需要做额外的编程,就像在本地调用一样.主要是为了应对当前互 ...

  9. 什么是云数据库RDS PPAS 版

    云数据库PPAS版,是阿里云与EnterpriseDB公司合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL.数据类型.高级函数 ...

  10. 【转】.NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现

    作者:Zhang_Xiang 原文地址:.NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现 先决条件 关于 Ocelot 针对使用 .NET 开发 ...