| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 532 人关注过本帖
标题:关于struct 和union的一些小问题求教
只看楼主 加入收藏
S_12s
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:110
专家分:670
注 册:2010-7-21
结帖率:100%
收藏
已结贴  问题点数:50 回复次数:7 
关于struct 和union的一些小问题求教
以下程序在VC6.0中的结果:
sizeof(tests)=20
sizeof(A)=16
sizeof(B)=24
Press any key to continue
在Win-TC中的结果:
sizeof(tests)=12
sizeof(A)=11
sizeof(B)=11

谁能解释一下??
程序代码:
#include <stdio.h>

struct test
{

    int m1;
    char m2;
    float m3;
    union uu
    {
        char u[5];
        int u2[2];
    }ua;
}tests;

struct A

{

    char a;

    int b;

    double c;

}A;
                                        /*A和B只是变量的位置顺序不一样*/
struct B
{

    int b;

    double c;

    char a;

}B;



int main()
{
    printf("sizeof(tests)=%d\n",sizeof(tests));
    printf("sizeof(A)=%d\n",sizeof(A));
    printf("sizeof(B)=%d\n",sizeof(B));
    return 0;

}

搜索更多相关主题的帖子: struct union 
2010-08-28 19:30
kingsroot
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:284
专家分:1159
注 册:2010-3-28
收藏
得分:0 
字节对齐的问题  VC为了提高程序效率  把字节对齐了的 便于CPU读取  而TC没有采用对齐  直接挨个存储  这样不利于CPU读取  就怎么简单
2010-08-28 19:53
S_12s
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:110
专家分:670
注 册:2010-7-21
收藏
得分:0 
那它是怎样对齐的呢??为什么sizeof(A)和sizeof(B)不一样呢??
2010-08-28 19:55
kingsroot
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:284
专家分:1159
注 册:2010-3-28
收藏
得分:16 
struct A

{

    char a;

    int b;

    double c;

}A;
我就拿这个做例子  char a  通常情况是占一个字节 所以他对地址没有多大的要求,但是int b 对地址就有要求了 现代编译器要求分配b的地址必须是能被sizeof(int)整除的  这样方便CPU读取  如果分配的地址不能被sizeof(int)整除 CPU就要花费2个周期来读取改数 效率有所降低  所以a和b之间就空了3个字节没有使用  所以你用VC编译出来的就是16,TC是16位的编译器  所以才会出现11的情况 VC是32位编译器  你可以试着打印各个字段的地址  看地址就一切明白了
2010-08-28 20:17
makebest
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:3
帖 子:658
专家分:962
注 册:2005-3-17
收藏
得分:16 
VC6 中对变量空间的分配, 是按变量的长度对齐的
struct A{
    char a; // 1字节, +3字节填充
    int b;  // 4字节
    double c; // 8字节
}A; // 16字节

struct B
{
    int b; // 4字节+4字节填充
    double c; // 8字节
    char a;   // 1字节
}B; // 17字节, 扩充到8X, 所以是 24

使用下面的语句可以取消所有填充空间:
#pragma pack(1)

[ 本帖最后由 makebest 于 2010-8-28 20:38 编辑 ]
2010-08-28 20:36
S_12s
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:110
专家分:670
注 册:2010-7-21
收藏
得分:0 
5楼的大侠可以说明一下为什么在struct B中对a分配完之后是扩充到8X,而不是4X?这有什么规则吗?
还有#pragma pack(1)的作用又是什么呢??
2010-08-28 21:18
hahayezhe
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖南张家界
等 级:贵宾
威 望:24
帖 子:1386
专家分:6999
注 册:2010-3-8
收藏
得分:18 
struct B
{
    int b; // 4字节+4字节填充
    double c; // 8字节
    char a;   // 1字节
}B; // 17字节, 扩充到8X, 所以是 24
 
struct B 中 int b是4字节 ;double c是8字节,这时 int b 和char a要保持字节对齐
当是int b周围又没有其它的成员,所以只能单独+4 而char a加7字节 那么是3*8=24字节

而 struct A中 int b和char a可以组合在一起与double c对齐,注意结构体中成员是按顺序存放的
#pragma pack(1)是指示struct成员按1字节对齐 也就是说不分配额外的空间,之间空余用nop 90填充

#pragma pack(n)为其原型 意思使结构体成员按照n字节对齐
仅当成员的字节<n时成立
比如#pragma pack(2)
那么char c为 1字节<2分配2字节
int b为4>2 分配4字节

2010-08-28 21:41
S_12s
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:110
专家分:670
注 册:2010-7-21
收藏
得分:0 
7楼的大侠令我思路开朗了不少,。虽然对nop 90这一东西不明白,但下面的内容还是可以理解的。谢谢了!
2010-08-28 22:18
快速回复:关于struct 和union的一些小问题求教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021926 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved