陈浩师兄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的话是不安全的!)。

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

最新文章

  1. springmvc&lt;一&gt;一种资源返回多种形式【ContentNegotiatingViewResolver】
  2. javascript--Function
  3. Python3基础 ,= 一个等式给多个变量赋值
  4. Android selector选择器的使用
  5. nova分析(2)—— nova-all
  6. 【转】Android中View的绘制过程 onMeasure方法简述 附有自定义View例子
  7. thinkphp 文件上传
  8. MVC4新功能...压缩和合并js文件和样式文件
  9. experss框架—基础认识
  10. 【三十】php之PDO抽象层
  11. Legal or Not(拓扑排序判环)
  12. MYSQL之库操作
  13. Linux - RAID和LVM
  14. JAVA对mysql的基本操作
  15. Linux下MySQL编码的修改
  16. Web前端性能优化策略
  17. flask部署
  18. 一款基于 Android 开发的离线版的 MM 图片浏览 App
  19. 《Python程序设计(第3版)》[美] 约翰&#183;策勒(John Zelle) 第 1 章 答案
  20. 关于Oracle中的字符的比较

热门文章

  1. MAC虚拟机NAT方式共享上网设置
  2. 玩一个:可以显示任何xml树结构的xaml定义
  3. 自己安装的几个Eclipse插件
  4. Mysql engine
  5. 创建本地CM 离线服务器
  6. HDU4862-Jump(最大流量最大费用流)
  7. 宿舍局域网与Internet连接
  8. mybatis代码生成器配置文件详解
  9. JavaScript要点(十) HTML DOM - 改变 HTML
  10. ASP.NET 学习的总结