解析C语言结构体,位段。

来源:互联网 发布:数组java99乘法表 编辑:程序博客网 时间:2024/05/18 17:43


1.结构的定义

聚合数据类型能够同时存储超过一个的单独数据。c语言提供了两种类型的聚合数据类型,数组与结构。数组是相同类型元素的集合,它的每个元素是通过下标引用或指针间接访问来选择的。结构也是一些值的集合,这些值成为它的成员,但一个结构的各个成员可能具有不同的类型。每个结构成员都有自己的名字,它们是通过名字访问的。结构并不是一个它自身成员的数组。和数组名不同,当一个结构变量在表达式中使用时,它并不被替换成一个指针。结构变量也无法使用下标来选择特定的成员。

结构的声明:

struct {

int a;

char b;

float c;

}x;      我们可以看出这个声明创建了一个名叫x的变量,它包含三个成员:一个整数,一个字符,一个浮点数。
2.结构的初始化

如下例子:

struct Student

{  int  num;

   char name[20];

   char sex;

   int  age;

   float  score;

   char addr[30];

}student1{10000,“李炯”,“M”,19,80,“北京”}

这就是对结构的初始化。
3.结构体的typedef

关于结构体的typedef,

typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。
具体区别在于:
若struct node {}这样来定义结构体的话。在申请node 的变量时,需要这样写,struct node n;
若用typedef,可以这样写,typedef struct node{}NODE; 。在申请变量时就可以这样写,NODE n;
区别就在于使用时,是否可以省去struct这个关键字。
1 首先:
在C中定义一个结构体类型要用typedef:
typedef struct Student
{
int a;
}Stu;
于是在声明变量的时候就可:Stu stu1;
如果没有typedef就必须用struct Student stu1;来声明
这里的Stu实际上就是struct Student的别名。
另外这里也可以不写Student(于是也不能struct Student stu1;了)
typedef struct
{
int a;
}Stu;

结构名是结构的标识符不是变量名.

另一种常用格式为:

typedef struct 结构名

{

类型 变量名;

类型 变量名;

...

} 结构别名;

另外注意: 在C中,struct不能包含函数。在C++中,对struct进行了扩展,可以包含函数。
4.结构体的内存存储(内存对齐规则,为什么存在内存对齐?)

 typedef struct fun
{
 int a;
 char b;
 double c;
 short d;
}fun;
int main()
{
 int ret = sizeof(fun);
 printf("%d\n", ret);
 system("pause");
 return 0;
}

其值为24.

对齐过程分析(对齐参数为其他的同理):

1、结构的第一个成员永远放在结构的0偏移处。

2、从第二个成员开始,都要对齐到某个对齐数的整数倍处(对齐数为结构成员自身大小和默认对齐数的较小值    默认对齐数:vs--8,linux---4).

3、结构自身的总大小必须为最大对齐数的整数倍。

union Fun
{
    int a;
    char b;
    double c;
    short d;
};
int main()
{
    int ret = sizeof(Fun);
    cout << "ret= " << ret <<"\n"<< endl;
    system("pause");
    return 0;

}

union Fun
{
 int a[7];
 char b[9];
 double c;
 short d[4];
}fun;
int main()
{
 int ret = sizeof(fun);
 printf("%d\n", ret);
 system("pause");
 return 0;
}

其值为32.

当联合体中无数组时,联合体的大小为联合体中变量类型最大的字节长度;
当联合体中有数组时,联合体的大小最小为字节数最大的数组,同时也要是字节数最大的变量类型的最小整数倍。

5.结构实现位段,位段大小的计算。位段的数据存储。

  位段的声明和普通的 成员声明相同,但 是位段成员必须声明为int 、signed  int、unsigned int类型。其次在成员名的后面是一个冒号和一个整数,这个整数表示该位段所占用的位的数目。

structbits{
unsigneda:2;

unsignedb:3;

unisngedc:4;

int  i;};
这个位段定义中除了定义了各成员的位长以外,还有int型

在上例中,其中a、b、c共占9位,占用了1个字节还要多,不到2个字节。而它后面为int型,占用2个字节。则a、b、c之后的7个位的空间闲置不用,i从另一个字节开头存放。如下图所示:
3)存储单元中位段的空间分配方向为由低位到高位分配。
上例中的字段分配图只是一个示意图,在内在的实际表示其实是这样的:
先定义的a(2个位),被分配到高16位的低位上,紧接着是b(3个位),后面的成员分配依此类推。最后的int型,因为是16位,高16位剩余的7个位不能容纳它,则i被分配到低16位。

6.位段的跨平台问题。 


原创粉丝点击