首页 > 其他分享 >结构体的强制类型转换

结构体的强制类型转换

时间:2022-12-03 22:23:01浏览次数:55  
标签:类型转换 内存 结构 强制 hEnt hLinks 指针

陈浩师兄03年的一篇博客《用C写有面向对象特点的程序》描述了用C语言来实现类似C++类继承的方法,这样方法的核心要点就是结构体的强制类型转换,让我来简单分析分析C语言中的结构体强制类型转换,还是用陈浩师兄原博的结构体来举例吧。两个结构体如下:

复制代码
/* 双向链表 (类似于父类)*/
typedef struct hLinks{
   struct hLinks *bwLink;
   struct hLinks *fwLink;
} hLinks;

/*
 * 一个使用双向链表的结构
 *     (类似于子类)
 */
typedef struct hEnt{
   hLinks links;
   int hData;
   char key[10];
} hEnt;
复制代码

首先,我们要搞清楚的一点是:C语言中的结构体并不能直接进行强制类型转换,只有结构体的指针可以进行强制类型转换。因此你可以在原博中看到在函数调用的时候有一些比较别扭的参数形式,我们来看看。

复制代码
/*
 *  打印 (类似于子类重载父类的成员函数)
 */
PrintLink( hLinks *h )
{
    hEnt *p ;

    for( p = ( hEnt* ) h->fwLink;     /*  <-----------把hLink再转回来  */
         p != ( hEnt* ) h;
         p = ( hEnt* )( (hLinks*)p )->fwLink )
    {
       printf("hData=[%d], key=[%s]/n", p->hData, p->key);
    }
}
复制代码

PrintLink函数的参数是一个hLinks类型的指针,因此在调用PrintLink时传入参数也应该是hLinks类型的指针,如果我们定义的时候用下面这样的形式。

hLinks head;

那么在调用函数的时候就必须把它转换成hLinks指针,于是先取地址在强制类型转换。

PrintLink( (hLinks *) &head );

这样看起来确实是很别扭,如果我们在声明结构体的时候这样做的话就可以避免这么难看的传递形式。

typedef hLinks *PtrhLinks;

 

话说回来,结构体指针的强制类型转换问题在这里面始终存在。PrintLink中就出现了这样的情况,那么在将hLinks指针转换为hEnt类型指针时有两个问题:

  1. 结构体中的成员情况是怎么的?
  2. 结构体中的成员的值的情况是怎么样的?

首先,结构体是储存在一块连续内存中的,计算机只关心的是结构体的大小和操作方式,结构体大小是定义的时候决定的(要进行对齐),而结构体的操作确实和结构体中的成员类型有关的。指针表示的是内存地址,那么在强制类型转换之后,计算机便以转换后的结构体来看待这个地址内存中的内容。比如两个结构体的内存结构如下:

                  hLinks                         hEnt

*bwLink *bwLink
*fwLink *fwLink
——(未定义) hData
——(未定义) key[10]

 

可以看出,在前两个内存单元中两个结构体存储的内容是相同的,当然不管相不相同计算机是不管的,当hLinks类型转换成hEnt类型时,计算机就将原结构体看做是hEnt类型的。转换后的hEnt类型结构体的前面两个内存单元的内容就是hLinks中的前两个单元内容,而hEnt的后两个内存单元中的内容取得是hLinks后的两个单元(这两个单元不是hLinks类型的成员,而是别的内容,所有如果转换后的hEnt要访问hData和key的话是不安全的!)。

总之一句话,在转换之后,计算机就按照转换后的结构体的组成结构来解释那么一段内存中存储的数据!!

标签:类型转换,内存,结构,强制,hEnt,hLinks,指针
From: https://www.cnblogs.com/amxiang/p/16948916.html

相关文章

  • Flutter 陈航 05-工程结构 示例项目 声明式
    本文地址目录目录目录05|Flutter是如何运行在原生系统上的计数器示例工程工程结构工程代码应用的整体结构MyAppMyHomePage页面布局及交互逻辑ScaffoldsetState代码流......
  • c语言怎么进行强制类型转换
    在c语言中,可以通过“(新类型名称)数据或表达式”语句来进行强制类型转换;例如“(float)100”就是将数值100(默认为int类型)转换为float类型,“(int)(x+y)”就是将表达式“x+......
  • 数据结构与算法__01--单链表无顺序添加时,节点对象形成封闭环问题,无法添加同一个对象导
    1进行对象是否相同的判断创建辅助节点temp遍历链表,找到最后未到最后,将temp后移当退出while循环时,temp就指向了链表的最后判断add的节点对象是否存在,若存在则不添......
  • n202_python数据类型和数据结构
    3.数据类型和数据结构python的数据类型大致可以分为两种:python自带的内置数据类型和第三方扩展包中的数据类型。其中,python自带的内置数据类型可以分为两种:可变数据类......
  • Linux 系统目录结构
    登录系统后,在当前命令窗口下输入命令:ls/你会看到如下图所示:树状目录结构:以下是对这些目录的解释:/bin:bin是Binaries(二进制文件)的缩写,这个目录存放着最经常使用的命......
  • 12.数结构
     ......
  • JS数据类型转换,转数值,转字符串,转布尔
    ​1.转数值number        parseInt(‘内容‘/变量名)可以强制把字符串转整数数值,隐式转换        Parsefloat(‘内容‘/变量名)可以强制把有小数的字符串......
  • 每日算法之树的子结构
    JZ26树的子结构描述输入两棵二叉树A,B,判断B是不是A的子结构。(我们约定空树不是任意一个树的子结构)假如给定A为{8,8,7,9,2,#,#,#,#,4,7},B为{8,9,2},2个树的结构如下,可以看......
  • 数据结构 玩转数据结构 6-13 更多二分搜索树相关话题
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13478 1重点关注1.1待解决的问题(持续深进)求某个节点的floor和ceil求某个节点的......
  • 强制解决Java参数乱码问题
    在我们日常开发中,常常复制的url路径都是这样的原路径:https://xxxx.oss-cn-hangzhou.xxxxxx.com/2022/xx/文件名.pdf复制出来的路径:https://xxxx.oss-cn-hangzhou.xxxxxx.com......