首页 新闻 会员 周边 捐助

结构体的强制转换

0
悬赏园豆:15 [已解决问题] 解决于 2012-12-04 16:22

struct SC
{
 int a;
 int b;
 int c;
};

struct SD
{
 int a;
 int b;
 int c;
 int d;
};

int main()
{
 struct SC c1[]={{3},{4},{5},{6}};
 struct SD *c2=(struct SD *)c1+1;
 printf("%d %d %d %d\n",c2->a,c2->b,c2->c,c2->d);

}

lzjnhs的主页 lzjnhs | 初学一级 | 园豆:60
提问于:2011-10-11 15:32
< >
分享
最佳答案
1

结构体和int等类型一样,都是数据类型。其他类型怎么转换,结构体就怎么转换,没有什么特殊的地方。
楼主可能想知道的不是结构体怎样强制转换这个问题吧,猜测,楼主想知道如下几个问题:
如果将一个结构体强制类型转换为另一个结构体(或者类型),那这个结构体的成员会怎样了?
如果将一个结构体强制类型转换为另一个结构体(或者类型),那么这个结构体成员的数值又会是什么了?
解答:
1、结构体的本质是:我们和C语言约定了一段内存空间的长短,及其内容的安排。假设下面两个结构体:
struct A1
{
    int a;
    char b;
};

struct A2
{
    char a;
    int b;
};
接着,用struct A1和struct A2定义变量,并赋初值:
struct A1 x = {10, 'A'};
struct A2 y = {'A', 10};
现在最重要的是,要知道x和y的内存情况:
x的内存安排是:前4B,后1B;
y的内存安排是:前1B,后4B。
如果有struct A2 z;
z.a = ((struct A2)x).a;
那么,C语言会对x的空间,按照struct A2的格局进行解释:
也就是说,将x的第一个字节看成第一个成员,且按ASCII码处理数据,而将后面的4B看成第二个成员,并按补码格式解释数据。

收获园豆:15
疾风中的劲草 | 初学一级 |园豆:186 | 2011-10-12 14:55
其他回答(4)
0

这涉及到内存布局,直接强转是不安全的.

egmkang | 园豆:-734 (初学一级) | 2011-10-24 15:36
0

1楼正解。但1楼给的例子有点问题,一般情况下编译器都会对结构体进行对齐,故两种结构体默认都是8字节大小。

希望睿智 | 园豆:215 (菜鸟二级) | 2012-02-24 20:28
1

简单的说,至于结构体对其之类的东西不做考虑,这部分内容可以看我的一片博文:

[c&cpp][memory] 内存对齐分配策略(含位域模式)


struct SC c1[]={{3},{4},{5},{6}}; 
struct SD *c2=(struct SD *)c1+1;

上面两句之后,C1占据48字节存储,在栈上,按照栈生长空间,存储内容可以看做:

3,0,0,4,0,0,5,0,0,6,0,0

(struct SD *)c1+1;首先将C1强制类型转换为SD指针,在+1的时候做指针偏移,是按照c1指向的数据类型的大小偏移的,也就是偏移4个字节,c1指向紧跟4之后的0。

struct SD *c2=(struct SD *)c1+1;操作使得c2指向c1的位置,也就是紧跟4的0,对于指针来说,他不关心自己指向的是什么,它会按照自己指向的类型信息来解释其指向的内存区域。所以说出的内容是0050。

 

这种强制类型转换是非常错误的,这里你的代码可以运行通过,是因为你的c1数组申请的足够大,在栈上申请了足够的空间供c2使用,否则,出错时必然的。

 


zsounder | 园豆:2819 (老鸟四级) | 2012-03-10 03:19
0

每个c1占3个int,c1指向的地址是 3,0,0,4,0,0,5,0,0,6,0,0

 

 struct SC c1[]={{3},{4},{5},{6}};
 struct SD *c2=(struct SD *)c1+1;

c1 + 1 相当于跨越了4个int(因为c1被转成SD的指针,1个SD是4个int),所以c2指向的数据是:

0,0,5,0,0,6,0,0

所以打印出来应该是0,0,5,0.

hoodlum1980 | 园豆:573 (小虾三级) | 2012-06-07 17:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册