结构体类型强制转换

本文通过具体示例探讨了C/C++中不同结构体之间的强制类型转换原理及结果预测方法,展示了如何通过理解内存布局来预测转换后的行为。

看code的过程中,经常看到将一个结构(a)体强制转换为另一结构体类型(b)后,赋给结构体(b)的变量。不明白其中奥秘,忍了好久终于忍不住编了一小段程序测试一下。如下:
#include<iostream.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct chann_s
{
int num1;
int num2;
}chann_t;


typedef struct mpoaChann_s
{
chann_t chan;
int num3;
int num4;
}mpoaChann_t;

void main()
{
chann_t p;
chann_t *p1;
mpoaChann_t q;
mpoaChann_t *q1;

p.num1=1;
p.num2=2;
q.num3=3;
q.num4=4;
p1=&p;
q1=&q;
q1=(mpoaChann_t *)p1;//注意这条语句
cout<<q1->chan.num1<<endl;
cout<<q1->chan.num2<<endl;
cout<<q1->num3<<endl;
cout<<q1->num4<<endl;

}

输出结果
1
2
1310656
4208553
将q1=(mpoaChann_t *)p1;改为:q1->chan =p;
输出结果:
1
2
3
4

若将结构体mpoaChann_t定义为:
typedef struct mpoaChann_s
{
int num3;
chann_t chan;
int num4;
}mpoaChann_t;
结构体chann_t不变,main()如下:
void main()
{
chann_t p;
chann_t *p1;
mpoaChann_t q;
mpoaChann_t *q1;

p.num1=1;
p.num2=2;
q.num3=3;
q.num4=4;
p1=&p;
q1=&q;
q1=(mpoaChann_t *)p1;//注意这条语句
cout<<q1->chan.num1<<endl;
cout<<q1->chan.num2<<endl;
cout<<q1->num3<<endl;
cout<<q1->num4<<endl;

}
输出结果:
2
1310656
1
4208553
分析结果:结构体类型强制转换,用mopaChann_t的结构,去套chann_t的地址空间。
对于第一次输出结果
p1(chann_t)       q1(mpoaChann_t)
--------                 ---------------
num1
--------                  chann_t变量
num2
--------                 ---------------
未知                      num3
--------                ---------------
未知                      num4
--------                ---------------
用q1的类型去套p1指向的地址空间,由于前两个变量类型对应上,而对于q1的后两个变量p1没定义,直接读紧

接其后的空间(不是p1管理的空间,出来的值是不可确定的)
第二次输出结果就不做说明了,平时都那么写。
第三次输出结果,同样使用以上的分析方法
p1(chann_t)           q1(mpoaChann_t)
-----------                 ---------------
num1                      num3
-----------                 ---------------
num2
-----------                 chann_t
未知
-----------                 ---------------
未知                        num4
-----------                ---------------
注意输出顺序 q1->chan.num1、q1->chan.num2、num3、num4
如上图所示,q1->chan.num1对应num2(值为2),q1->chan.num2对应第一个"未知"(值为1310656),num3

对应num1(值为1),num4对应第二个"未知"(值为4208553)。因此有输出结果
2
1310656
1
4208553
结论:对于结构体类型强制转换,用类型套空间,可分析出转换后结果。

 

在贴一下我自己的测试代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct _AAA{
unsigned char a1;
unsigned char a2;
char *a3;
char *a4;
}AAA;

typedef struct _BBB{
unsigned int b1;
char *b2;
char *b3;
}BBB;


int main()
{
AAA a;
a.a1 = 'A';
a.a2 = 'B';
a.a3 = "CBD";
a.a4 = "EFGH";

BBB *b;
b = (BBB*)(&a);

printf("b1 is %d/n",b->b1);
printf("b2 is %s/n",b->b2);
printf("b3 is %s/n",b->b3);
AAA *c;
c = (AAA*)b;
printf("c1 is %c/n",c->a1);
printf("c1 is %c/n",c->a2);
printf("c3 is %s/n",c->a3);
printf("c4 is %s/n",c->a4);

return 0;
}

 

输出结果:

 

在C语言中,结构体强制类型转换是将一个结构体类型的数据转换为另一个结构体类型的操作。可以通过强制类型转换运算符来实现,即将要转换的数据类型放在要转换的值或表达式前面,用括号括起来[^1]。 ### 结构体指针类型强制转换示例 ```c #include <stdio.h> // 定义一个结构体 typedef struct { short start; char value1; short value2; int value3; char stop; } value_def; int main() { char buff[100]; value_def *pvalue; // 强制转换地址类型再给地址到指针 pvalue = (value_def *)buff; printf("%d", pvalue->value1); printf("%d", pvalue->value2); printf("%d", pvalue->value3); return 0; } ``` 此示例中,将`buff`数组的地址强制转换为`value_def`类型的指针,然后通过该指针访问结构体成员[^2]。 ### 基于内存布局连续性的父结构体与子结构体间的强制类型转换示例 ```c #include <stdio.h> // 父结构体(基类) typedef struct Shape { int x, y; void (*draw)(void*); } Shape; // 子结构体(派生类) typedef struct Circle { Shape base; // 必须为首成员 int radius; } Circle; // 假设的绘制函数 void circle_draw(void* self) { Circle* circle = (Circle*)self; printf("Drawing a circle with radius %d at (%d, %d)\n", circle->radius, circle->base.x, circle->base.y); } // 多态调用 void render(Shape* shape) { shape->draw(shape); } int main() { Circle circle; circle.base.x = 10; circle.base.y = 20; circle.radius = 5; Shape* shape = (Shape*)&circle; // 强制类型转换 shape->draw = circle_draw; // 绑定子类方法 render(shape); // 多态调用 return 0; } ``` 该示例将`Circle`结构体类型的指针强制转换为`Shape`结构体类型的指针,利用内存布局的连续性,通过强制类型转换直接访问父类成员,实现了多态调用[^3]。 ### 相关问题 1. C语言结构体强制类型转换会带来哪些潜在风险? 2. 结构体强制类型转换在不同编译器下的表现是否一致? 3. 除了上述示例,结构体强制类型转换还有哪些常见的应用场景? 4. 当结构体成员包含指针时,进行强制类型转换需要注意什么?
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值