c语言结构体成员变量访问方式的一点思考

2018-09-1410:57:29后端程序开发Comments3,254 views字数 1234阅读模式

本文主要探讨的是c语言中关于结构体成员变量的访问方式。访问结构体成员变量?如此简单的问题,有什么可以思考的呢?很纳闷也很奇怪。既然这样,那就带着这个奇怪的问题继续阅读吧。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

示例

我们的探讨还是从一个简单的示例开始:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

已知结构体类型定义如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

struct node_t {
    char a;
    int b;
    int c;
};

且结构体1Byte对齐:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

#pragma pack(1)

接下来我们探讨几种访问该结构体成员变量c的方式:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

情形1

如果程序中定义了一个struct node_t类型的变量node如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

struct node_t node;

那么我们就可以直接通过下面的方式来访问成员变量c:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

node.c

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

情形2

如果程序中定义了一个指向struct node_t类型的指针p_node如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

struct node_t node;
struct node_t *p_node = &node;

或者在堆上分配了一块类型为struct node_t的内存如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

struct node_t *p_node= (struct node_t *)malloc(sizeof(struct node_t));

那么我们就可以使用下面的方式来访问成员变量c:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

p_node -> c;

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

情形3

上述两种访问方式都是比较常见的,也是大家所熟悉的,下面我们来探讨一种大家不是特别熟悉也不是很常见的情形:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

如果程序中只给定了一个内存地址数值addr_node,且该地址addr_node起始的一段内存,指向一块类型为struct node_t的内存,addr_node声明如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

unsigned long addr_node;

此时,我们如何根据这块内存地址来访问成员变量c呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

由于我们知道了该结构体的起始地址addr_node,所以我们对其进行强制类型转换,从而得到一个指向该结构体的指针p_node:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

struct node_t *p_node = (struct node_t *)addr_node;

接下来我们就可以通过情形2的方式来访问成员变量c了;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

情形3要传达的意思是,我们可以通过一个具体的内存地址数值来访问我们的结构体成员变量;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

关于情形3的一点说明

为什么特地的指出情形3,因为我们上一篇博文关于c语言结构体偏移的一点思考中使用了类似的用法:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

((struct node_t *)0)->c

 文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

我们通过内存地址0来访问结构体struct node_t成员变量c,但这里面有几点需要说明一下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

1. 我们并未对内存地址0做过任何内存相关操作,如解引用、赋值等,即内存地址编号0开始的一段内存无任何变化;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

2. 我们只是利用了编译器的特性来帮助我们计算结构体的偏移,仅仅是利用了编译器的特性来计算而已;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

3. 善于利用编译器的一些特性来优化我们的程序或系统;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

结论

本文主要介绍了c语言中关于访问结构体成员变量的几种方式,并对通过内存地址数值直接访问结构体成员变量做了说明,解释了上篇博文中可能产生疑问的一个问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/4630.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/bc/4630.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定