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{ // 成员变量赋值第一个 ...
随机推荐
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- Excel表函数自动生成SQL
前言 在平常的工作中,多多掌握一点这样的小技巧,能够帮助我们省去很多时间: 1.数据库对应的表如下: 2.excel中需要导入的数据如下: 3.excel中sql的写法: ="insert ...
- idea控制台不能输入问题
idea控制台不能输入问题 在idea中,使用JUnit测试时,不能在控制台输入,进行下面的设置即可 第一步 :help---> Edit Custom VM Options... 第二步:添加 ...
- 自定义 systemd service
Red Hat Linux 自 7 版本后 采用systemd 形式取代原先 init ,用户可以参考 系统service 创建自己的service ,以便于日常统一管理,系统service 存储路径 ...
- Pytorch从0开始实现YOLO V3指南 part5——设计输入和输出的流程
本节翻译自:https://blog.paperspace.com/how-to-implement-a-yolo-v3-object-detector-from-scratch-in-pytorch ...
- resultMap自定义映射(多对一)
自定义resultMap,处理复杂的表关系,实现高级结果集映射 1) id :用于完成主键值的映射 2) result :用于完成普通列的映射 3) association :一个复杂的类型关联;许多 ...
- HashSet存储自定义类型元素和LinkedHashSet集合
HashSet集合存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: ~存储的元素(String,Integer,-Student,Person-)必须重写hashCode ...
- 发现Mapstruct的一个bug
前言 在一次需求的开发过程中,发现一个对象插入数据库时某个字段总是为空.简化后的代码如下: @Autowired private PersonService personService; public ...
- Solution -「构造」专练
记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...
- day03_3_流程控制练习题
# 流程控制练习题 # 一.编程题 1.实现一个课程名称和课程代号的转换器:输入下表中的课程代号,输出课程的名称.用户可以循环进行输入,如果输入0就退出系统.(**使用****switch +whil ...