700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C语言 结构体指针强制转换 c中结构体指针的强制类型转换

C语言 结构体指针强制转换 c中结构体指针的强制类型转换

时间:2024-06-18 06:20:50

相关推荐

C语言 结构体指针强制转换 c中结构体指针的强制类型转换

1、结构体到结构体指针之间的转换

a、结构体指针的强制类型转换即结构体的数据成员在内存段当中的重新分配,结构体的存储“内存对齐”请参看上篇博客,该论述实例如下:

#include

#include

struct A{

int num;

};

struct B{

int num;

char type;

int age;

};

int main()

{

struct A a;

a.num = 5;

char* tmp1 = (char *)(&(a.num));

tmp1 = tmp1 + 4;

*tmp1 = 'a';

int *tmp2 = (int *)(&(a.num));

tmp2 = tmp2 + 2;

*tmp2 = 32;

struct B *b = (struct B *)(&a);

std::cout << b->num << " " << b->age << " " << b->type << std::endl;

std::cout << sizeof(*b) << std::endl;

system("pause");

return 0;

}

输出结果: 5 32 a 12

结果分析:按照结构体B在内存当中的存储方式应该如下:11111xxx1111,也就是sizeof(*b)的值为12(详细计算看上篇)。

1、结构体定义了一个结构体Aa,它的存储方式是1111,共占用4个字节,存储的值为5;

2、tmp1指针所指向的位置为第8个字节的位置,保存的值为a;tmp2指向的位置为第6个字节位置;

3、将Aa强制转换成Bb,即需要按照结构体B对该a所对应的块内存进行重新取值并赋值给B所对应的字段,得到的会是如下结果:1~4字节存储的是5,5~8字节存储的是10,9~12字节存储的是a

理解如下图:

b、类型转换也可以根据如下理解:

例如:b->num:将structAa所指向的内存单元以structBb的分布方式(利用b)取得偏移为num的值。

结构体声明如何内存的分布,结构体指针声明结构体的首地址,结构体成员声明该成员在结构体中的偏移地址。

解释如下:

1、首先要明确structBb本身有一个值(在32位机上一般是32位),这个值代表着某个内存地址,比如这个首地址值是0x30000000,由于b被定义StructB类型,那么编译器在编译源文件时就会认为b指向的是一个structB的结构,这个结构的内容由一段连续的内存存储,(b->num)(b->type)(b->age)在structB的定义中肯定是存在num、type、age三个的,这几个变量对一个structB结构的地址偏移量是固定的,也就是说只要知道一个structB结构的起始地址,就能计算出这个结构所包含的num、type、age的地址,由于Bb的地址已知(由Aa强制转换而来,所以编译器知道这个地址即a的首地址),b所含的num离b的偏移量已知,那么就能通过b实现对num的取值,在编译器编译C文件的时候并不管b中的nun是否定义

2、b被定义为structB,而B中又包含b,那么编译器就认为b所指向的结构中存在num

3、b->num如果不发生保护错误,总是能取到一个值(这个值就是对b偏移一定距离的内存单元中的值),只是这个值不能确定是否是你期望的值

4、再次提醒,变量的值是存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,b的值就是一个32位值,并且存储在某个内存单元中,通过这个32位值就能找到b所指向的结构的起始地址,通过这个起始地址和各个结构所包含变量离起始地址的偏移对这些变量进行引用,b->num只是这种引用更易读的写法,只要b是指向num的指针,那么b的值就肯定存在,b存在,偏移量已知,那么b->num就肯定存在,只是要记住,b->num只是代表了对num一定偏移地址的值

5、假如b->num所对应的这段内存从未有进行过操作,那么其值就是系统上电启动之后的内存的默认值,如果有其他程序使用过,那么其值就是其他程序执行后在这段内存中留下的值,总之,每个正常工作的内存单元中都是有值的,无论这些值是否是我们所需要的,它们始终是存在的。你可以把内存想象成一个大数组,当你在程序中定义了一个数组,但是并没有初始化,但是你也可以引用数组元素,只是引用的值是未知的,道理是类似的

2、将int强制类型转换为结构体类型

typedefstructeg

{

intx;

inty;

}eg;

intpoint=0x30000000;

eg*peg=(eg*)point;

可以看到point本身只是个整型变量,但是这样的赋值是合法的,peg->x的值是0x30000000开始的四字节,peg->y是0x30000004开始的四字节。

解释如下:

不是说某个地址有那个结构体你才能引用,即使没有,你也能引用,因为你已经告诉了编译器param变量就是指向一个PAINT_PARAM结构体的变量并且指明了param的值,机器码的眼中是没有数据结构一说的,它只是机械的按照指令的要求从内存地址取值,那刚才的例子来说,peg->x,peg->y的引用无论0x30000000是否存在一个eg结构体都是合法的,如果0x30000000开始的8个字节存在eg结构体,那么引用的就是这个结构体的值,如果这个位置是未定义的值,那么引用的结果就是这8个字节中的未定义值,内存位置总是存在的,而对内存中值的引用就是从这些内存位置对应的内存单元取值。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。