目录

文章目录

  • 目录
  • 数组类型强制类型转换为结构体
  • 结构体之间的强制类型转换

数组类型强制类型转换为结构体

先看一个例子:

#include <stdio.h>int main(void) {unsigned char arr[] = "0123456789abcdefghijk";struct A {int     a;char    b;char    c;char    d;int     e;} p, *pp;struct B {int     a;char    b;int     c;};p.a = 1;p.b = '2';p.c = '3';p.d = '4';p.e = 5;pp = &p;printf("pp->a: %d\npp->b: %c\npp->c: %c\npp->d: %c\npp->e: %d\n", pp->a, pp->b, pp->c, pp->d, pp->e);printf("**********\n");pp = (struct A *)arr;printf("pp->a: %d\npp->b: %c\npp->c: %c\npp->d: %c\npp->e: %d\n", pp->a, pp->b, pp->c, pp->d, pp->e);return 0;
}

运行结果:

pp->a: 1
pp->b: 2
pp->c: 3
pp->d: 4
pp->e: 5
**********
pp->a: 858927408
pp->b: 4
pp->c: 5
pp->d: 6
pp->e: 1650538808

上述是一个将数组类型变量强制类型转换为 struct A 的例子,结合结构体内存分布的内容我们可以看出:结构体数据类型转换的本质就是对结构体内存空间的填充。通过这种方式,可以把某一起始地址的数据类型与结构体成员相对应。

结构体之间的强制类型转换

要理解结构体之间的强制类型转换,需要明白以下几点原理:

  1. 结构体变量是如何分布内存的。
  2. 结构体变量的内存首地址。
  3. 结构体成员在结构体内存中的偏移地址。

实际上在上述的内容中,我们已经提到了这 3 点内容。

先看一个例子:

#include <stdio.h>struct A {int     x;char    y;
} a, *pa;struct B {char    x;int     y;
} b, *pb;int main(void) {a.x = 1;a.y = 'A';pa = &a;printf("pa->x: %d, pa->y: %c\n", pa->x, pa->y);b.x = 'A';b.y = 1;pb = &b;printf("pb->x: %c, pb->y: %d\n", pb->x, pb->y);struct B z;z.x = ((struct B *)pa)->x;printf("z.x: %c, z.y: %d\n", z.x, z.y);
}

输出结果:

pa->x: 1, pa->y: A
pb->x: A, pb->y: 1
z.x: , z.y: 32766

上述例子为结构体之间的强制类型转换,根据结构体内存分布的内容,并且我们暂不考虑内存对齐的话,我们知道:

  • a 的内存分布为:前 4B,后 1B
  • b 的内存分配为:前 1B,后 4B

当我们执行强制类型转换时,本质是就是 C 语言会对结构体变量 a 的空间,按照 struct B 的布局进行解释:也就是说,将 a 的第一个字节看成 struct B 的第一个成员,且按 ASCII 码处理数据,而将后面的 4B 看成 struct B 的第二个成员,并按补码格式解释数据。

需要注意的是,C 语言中的结构体强制类型转换本质是对指针进行转换,所以转换的对象必须为一个指针类型:

struct str1 a;struct str2 b;
a = (struct str1)b;     // this is wrong
a = ((struct str1)&b);  // this is correct

通过数组强制类型转换为结构体以及结构体之间互相转换的内容,我们可以总结到:C 语言中结构体变量之间直接的赋值和转换本质是将右值的内存数据直接覆盖到左值所占用内存空间中,然后再根据 C 语言对这块内存的理解(类型定义)表达出来

struct in_addr {unsigned long a_addr;
}struct sockaddr_in {unsigned short     sin_family;     // 地址类型(2B)unsigned short int  sin_port;      // 端口号(2B)struct in_addr      sin_addr;       // IP 地址(4B)unsigned char       sin_zero[8];  // 填充空间(8B)
}struct sockaddr {unsigned short  sa_family;    // 地址类型(2B)char            sa_data[14];   // 协议地址(14B)}

在实际的网络编程中,通常会先初始化 sockaddr_in,再将它强制转化成 sockaddr 来使用。这两个结构体,长度都为 16 字节,sockaddr_in.sin_family 的数据存入 sockaddr.sa_family,剩下的 14 个字节存入 sockaddr.sa_data,这样在各种操作中可以方便的处理端口号和 IP 地址。

C 语言编程 — 结构体的数据类型转换相关推荐

  1. c 语言结构体类型转换,C 语言编程 — 结构体的数据类型转换

    目录 数组类型强制类型转换为结构体 先看一个例子: #include int main(void) { unsigned char arr[] = "0123456789abcdefghij ...

  2. C语言中结构体的强制类型转换

    最近在学习C语言中的Socket,遇到了结构体强制类型转换的问题,在这里记录一下. 我们看一个例子 struct sockaddr_in seraddr;memset(&seraddr, 0, ...

  3. c 语言 结构体 编程,C语言:结构体的编程问题(很简单)

    C语言:结构体的编程问题(很简单) 答案:2  信息版本:手机版 解决时间 2020-07-25 02:18 已解决 2020-07-24 02:27 先定义一个结构体Student,它包含四个成员: ...

  4. c++ 结构体初始化_单片机C语言 - 基于结构体的面向对象编程技巧

    单片机C语言 - 基于结构体的面向对象编程技巧 一.面向对象 面向对象是软件开发方法,是相对于面向过程来讲的.通过把数据与方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式 ...

  5. 【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态

    介绍 这个是在B站上看边看视频边做的笔记,这一章是Glang面向对象编程 这一章内容较多,内容有Go语言的结构体是什么,怎么声明:Golang方法的调用和声明:go语言面向对象实例,go语言工厂模式: ...

  6. c语言强制转换为结构体,C语言结构体的强制类型转换

    陈浩师兄03年的一篇博客<用C写有面向对象特色的程序>描述了用C语言来实现相似C++类继承的方法,这样方法的核心要点就是结构体的强制类型转换,让我来简单分析分析C语言中的结构体强制类型转换 ...

  7. c语言咋样编程学号,C语言 用结构体类型数组编程实现输入5个学生的学号姓名平时成绩期中成绩和期末成绩然后输出每位...

    满意答案 zhyx520325 推荐于 2020.12.09 采纳率:41%    等级:10 已帮助:1973人 #include #include //C语言 用结构体类型数组编程实现输入5个学生 ...

  8. c语言中申请内存并初始化,c语言中结构体的定义、初始化及内存分配

    #include struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数外 //相当于全局变量与局部变量 ...

  9. c语言 结构体 ppt,第8章C语言的结构体和共同体.ppt

    <第8章C语言的结构体和共同体.ppt>由会员分享,可在线阅读,更多相关<第8章C语言的结构体和共同体.ppt(41页珍藏版)>请在皮匠网上搜索. 1.1第八章结构体.共用体和 ...

最新文章

  1. kafka配置参数详解
  2. linux下 tar解压 gz解压 bz2等各种解压文件使用方法
  3. 用C++面向对象的方式动态加载so
  4. 学习使用Bing Maps Silverlight Control(一):准备和新建
  5. 在DataFrame中新建列赋值后全部为NaN(转)
  6. 基于JavaScript 数组的经典程序应用源码(强烈建议收藏)
  7. linux中updatedb命令详解,updatedb命令
  8. PostgreSQL 中如何delete重复数据
  9. 扫雷win10_厉害了,一个自动扫雷游戏项目!
  10. 经验分享:如何快速上手公司的项目代码
  11. iphone屏幕自定义排版_如何使用小部件和图标自定义iPhone主屏幕
  12. C++“打鱼晒网”问题
  13. ensp中ap获取不到ip_[网络求助]华为ap无法获取到ip
  14. 谈谈对springioc的理解
  15. 【图像识别】基于模板匹配算法求解车牌识别问题matlab代码
  16. csgo如何增加人机数量及平衡_csgo怎么单机跟电脑打只有每队5人,怎么增大BOT
  17. java热敏打印机_用java在POS热敏打印机上打印PDF或PNG
  18. android view交替动画,Android View原理(View树遍历,View重绘,View动画)
  19. 归并排序(递归+非递归)
  20. 什么是综合布线系统?

热门文章

  1. 查询添加条件_035 JAVA-MySQL 约束、DML操作(增改删)、事务处理、查询数据
  2. excel字段自动java类,Java 接口自动化系列--工具类之Excel测试数据解析封装
  3. 转让app后AppStore应用名称下面所有者显示问题
  4. Deepmind“好奇心”强化学习新突破!改变奖励机制,让智能体不再“兜圈子”
  5. Oracle的ONS创建,Oracle 10gR2 RAC Clusterware ONS服务的管理
  6. HTC开放Vive Tracker代码啦!
  7. python中torch模块下载,Python qtorch包_程序模块 - PyPI - Python中文网
  8. 杨强入选加拿大皇家科学院院士!此外还有3名华人学者入选
  9. 都在说GPT-3和AlphaFold,2020没点别的AI技术突破了?
  10. 一片哗然!ICLR 2020被曝47%的审稿人没发过相关论文