关于字节对齐、结构体偏移地址、字位段问题的例子程序说明

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
    struct a
    {
        int a1;
        char a2[3];
        int a3;
    }*p;//占12字节

    p = (struct a *)0X1000;

    //几种数据类型所占的字节个数
    printf("%d\n", sizeof(char));
    printf("%d\n", sizeof(short));
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof(long));
    printf("%d\n", sizeof(float));
    printf("%d\n", sizeof(double));
    printf("%d\n", sizeof(long double));
    printf("%d\n", sizeof p);//可以写成sizeof(p)或者sizeof p

    //每个结构体数据成员在内存中的起始地址
    printf("%0X\n", &(p->a1));
    printf("%0X\n", &(p->a2[0]));
    printf("%0X\n", &(p->a2[1]));
    printf("%0X\n", &(p->a2[2]));
    printf("%0X\n", &(p->a3));


    printf("%0X\n", p + 0X1);//p是指向结构体的指针变量,加1偏移一个结构体变量的大小
    //printf("%0X\n", (unsigned char)p + 0X1);//强制转换到普通char类型,p变为一个具体的数,
                                    //并且只截取了一个字节,截取低8位,一个字节长度:0X00 + 0X1 = 1
    //printf("%0X\n", (unsigned short)p + 0X1);
    printf("%0X\n", (unsigned int)p + 0X1);
    printf("%0X\n", (unsigned long)p + 0X1);
    printf("%0X\n", (unsigned long *)p + 0X1);//偏移一个long类型大小:4个字节大小
    printf("%0X\n", (char *)p + 0X1);//偏移一个char类型大小:1个字节大小
    printf("%0X\n", (double *)p + 0X1);


    struct b
    {
        unsigned char b1;
        unsigned char b2:5;
        unsigned char b3:2;
        unsigned char b4:3;
    }*x;//占3个字节,b1占一个,b2、b3总共占一个、b4占一个
    char c[4];
    x = (struct b *)c;

    memset(c, 0, 4);
    printf("0x%0x--0x%0x--0x%0x--0x%0x\n",c[0],c[1],c[2],c[3]);
    x->b1 = 1;
    x->b2 = 2;
    x->b3 = 3;
    x->b4 = 4;
    printf("0x%0x--0x%0x--0x%0x--0x%0x\n",c[0],c[1],c[2],c[3]);


    /*************************************************************************
    位字段是C语言中一种存储结构,不同于一般结构体的是它在定义成员的时候需要指定成员所占的位数。

    看如下位字段的定义:

    typedef struct bit_field {
    unsigned int a : 5;
    unsigned int b : 3;
    unsigned int c : 20;
    unsigned int d : 4;
    } bit_field_s;

    在如上定义中,bit_field_s结构体只占用一个DWORD的空间,即4个字节。
    其中成员a占用5位,成员b占用3位,成员c占用20位,成员d占用4位。
    我们可以对bit_field_s结构体的成员进行如下赋值:

    bit_field_s x;
    x.a = 4;
    x.b = 7;
    x.c = 1024;
    x.d = 13;

    在定义位字段时还可以不指定成员的名称,看如下定义:

    typedef struct bit_field {
    unsigned int a : 5;
    unsigned int b : 3;
    unsigned int c : 20;
    unsigned int : 4;
    } bit_field_s;

    在如上定义中,最后一个成员只是用于占位,使结构体按word对齐。
    而如下定义就和上面的定义是一样的效果:

    typedef struct bit_field {
    unsigned int a : 5;return 0;
    unsigned int b : 3;
    unsigned int c : 20;
    unsigned int : 0;
    } bit_field_s;
    最后一个成员的0位宽度用于强制结构体按DWORD对齐。
    ************************************************************************************/


    int m[5];
    memset(m,1,20);//如果这里改成memset(a,1,5*sizeof(int))也不可以,因为memset按字节赋值,将每个字节赋为1。
    for(int i = 0;i < 5;i++)
        cout<<m[i]<<" ";//这里a[i] = 00000001 00000001 00000001 00000001 =16843009
    cout << pow(2, 0) + pow(2, 8) + pow(2, 16) + pow(2, 24);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值