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

来源:互联网 发布:saas数据库设计 编辑:程序博客网 时间:2024/05/20 04:10
#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;}

0 0