C 语言 struct 第一个成员变量的妙用
一、双重身份
如下定义了一个 School 结构体:
typedef struct School
{
int a;
int b;
}SCHOOL_S;
SCHOOL_S stSch;
下面我们来输出一下 stSch 以及成员变量 a 和 b 的地址:
int main()
{
printf("stSch 的地址[%p]\n", &stSch);
printf(" a 的地址[%p]\n", &stSch.a);
printf(" b 的地址[%p]\n", &stSch.b);
return 0;
}
输出结果如下:
有没有发现什么不得了的事情——结构体 school 的地址与第一个成员变量 a 的地址相同,也就是说变量 a 的地址既是 school * 类型,又是 int * 类型。脑海中突然冒出一个大胆的想法,如果我将 a 的地址强制类型转化为 SCHOOL_S * 类型呢:
int main()
{
stSch.a = 10;
stSch.b = 20;
SCHOOL_S *pstSch = (SCHOOL_S *)&stSch.a;
printf("a = %d\n", pstSch->a);
printf("b = %d\n", pstSch->b);
return 0;
}
输出结果如下:
Amazing~
二、妙用
通过上边的小测试,我们发现了 struct 的第一个成员变量的地址有双重身份,那么该如何使用呢?
对于两个不同的结构体:
typedef struct Teacher
{
char name[10]; /* 姓名 */
int id; /* 职工编号 */
}TEACHER_S;
typedef struct School
{
char name[10]; /* 校名 */
int cnt; /* 教职工个数 */
}SCHOOL_S;
SCHOOL_S school;
TEACHER_S teacher;
void Init()
{
strncpy(stSchool.name, "School", sizeof(stSchool.name) - 1);
stSchool.cnt = 1;
strncpy(stTeacher.name, "Teacher", sizeof(stTeacher.name));
stTeacher.id = 1;
}
如何在得知 school 的情况下得到 teacher 的信息呢?你或许可以这么做:在 School 中新增 Teacher 的指针变量,使其指向 teacher。
typedef struct School
{
char name[10]; /* 校名 */
int cnt; /* 教职工个数 */
struct Teacher *pstTeacher; /* 【Add】指向 Teacher 的指针变量 */
}SCHOOL_S;
int main()
{
Init();
stSchool.pstTeacher = &stTeacher;
}
这也不失为一种方法,但怎么样才能用到第一个成员变量的「双重身份」这个信息呢?
下面让我们对结构体 School 和 Teacher 做个简单修改:
typedef struct List
{
struct List *next;
}LIST_S;
typedef struct Teacher
{
LIST_S head; /* 【Add】单链表头结点 */
char name[10]; /* 姓名 */
int id; /* 职工编号 */
}TEACHER_S;
typedef struct School
{
LIST_S head; /* 【Add】单链表头结点 */
char name[10]; /* 校名 */
int cnt; /* 教职工个数 */
}SCHOOL_S;
int main()
{
Init();
stSchool.head.next = &stTeacher.head;
TEACHER_S *pstTeacher = (TEACHER_S *)stSchool.head.next;
printf(" stTeacher 的地址为[%p]\n", &stTeacher);
printf("pstTeacher 的地址为[%p]\n", pstTeacher);
return 0;
}
输出结果如下:
是不是很神奇~
C 语言 struct 第一个成员变量的妙用的更多相关文章
- C语言根据结构体成员变量的地址,得到结构体的地址
看nginx代码时发现双链表使用的是这种方法,记录一下 给出一个实例来说明 struct father_t { int a; char *b; double c;}f;char *p ...
- R语言学习 第一篇:变量和向量
R是向量化的语言,最突出的特点是对向量的运算不需要显式编写循环语句,它会自动地应用于向量的每一个元素.对象是R中存储数据的数据结构,存储在内存中,通过名称或符号访问.对象的名称由大小写字母.数字0-9 ...
- Objective-C类成员变量深度剖析
目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...
- Objective-C类成员变量深度剖析--oc对象内存模型
目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...
- 【IOS 开发】Object - C 面向对象 - 类 , 对象 , 成员变量 , 成员方法
. 一. 类定义 类定义需要实现两部分 : -- 接口部分 : 定义类的成员变量和方法, 方法是抽象的, 在头文件中定义; -- 实现部分 : 引入接口部分的头文件, 实现抽象方法; 1. 接口部分定 ...
- Java语言基础(六)char成员变量默认初始值 最简单的Java源文件 Java的main()方法
①char成员变量的初始值是:'\u0000' ②package用来指定该文件所处的包的名称,必须位于源文件的顶端. import java.util.*; package com.hyy.test; ...
- C语言中 struct成员变量顺序对内存的占用
在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...
- 【C语言探索之旅】 第一部分第四课第一章:变量的世界之内存那档事
内容简介 1.课程大纲 2.第一部分第四课第一章:变量的世界之内存那档事 3.第一部分第四课第二章预告:变量的世界之声明变量 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答 ...
- java类中,成员变量赋值第一个进行,其次是静态构造函数,再次是构造函数
如题是结论,如果有人问你Java类的成员初始化顺序和初始化块知识就这样回答他.下面是代码: package com.test; public class TestClass{ // 成员变量赋值第一个 ...
随机推荐
- Python递归函数的定义和几个小例子
递归函数 (1)什么是递归函数? 我们都知道,一个函数可以调用其他函数.如果这个函数在内部调用它自己,那么这个函数就叫递归函数. (2)递归函数的作用 举个例子,我们来计算阶乘 n! = 1 * 2 ...
- svn提交报错Unexpected HTTP status 413 'Request Entity Too Large' on
问题原因:nginx的client_max_body_size设置过小,默认 1M,如果请求的正文数据大于client_max_body_size,HTTP协议会报错 413 Request Enti ...
- 11.4 Android Studio如何设置代理
有些网络环境下,Android Studio下载无法下载依赖,这个时候就要配置代理,至于代理的问题,大家要自己解决. 获取代理信息 一般要获取如下信息: 地址:可以是域名和IP 端口: 代理类型:常用 ...
- NC14583 糖糖别胡说,我真的不是签到题目
NC14583 糖糖别胡说,我真的不是签到题目 题目 题目描述 从前,有 \(n\) 只萌萌的糖糖,他们分成了两组一起玩游戏.他们会排成一排,第 \(i\) 只糖糖会随机得到一个能力值 \(b_i\) ...
- Servlet-2获取请求,响应结果
获取请求参数值1)HttpServletRequest ① 该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息,由Servlet容器创建其实现类对象并传入serv ...
- java-Stream的总结
JAVA中的Stream 01.什么是Stream Stream是JDK8中引入,Stream是一个来自数据源的元素序列并支持聚合操作.可以让你以一种声明的方式处理数据,Stream 使用一种类似用 ...
- python+tkinter 简单的登录窗口demo
一个简单的登录窗口布局,可以用于日常快速搭建一个简单的窗口类. from tkinter import * import tkinter.messagebox class LoginUi: def _ ...
- 论文阅读 TEMPORAL GRAPH NETWORKS FOR DEEP LEARNING ON DYNAMIC GRAPHS
14 TEMPORAL GRAPH NETWORKS FOR DEEP LEARNING ON DYNAMIC GRAPHS link:https://scholar.google.com.hk/sc ...
- Hbase学习(三)过滤器 java API
Hbase学习(三)过滤器 HBase 的基本 API,包括增.删.改.查等. 增.删都是相对简单的操作,与传统的 RDBMS 相比,这里的查询操作略显苍白,只能根据特性的行键进行查询(Get)或者根 ...
- Nginx第三方模块Ngx-dyups安装过程
Ngx-dyups是什么,能干什么 它是一个Nginx第三方动态Upstream配置模块,可以实现在不重启Nginx情况下动态更新反向代理Upstream表.该模块由淘宝开发团队维护,淘宝自家的Ten ...