浅析C语言结构体及位段
2017-07-08 23:10
274 查看
数据经常以组的形式存在。例如,学校需要了解每位学生的姓名,学号和成绩等。如果这些值储存在一起,访问起来会更加简单。但如果类型不同,就无法存储于同一个数组中。所以在C语言中可以使用结构把不同类型的值存储在一起。
先来看看百度百科对结构体的定义:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构。数组是相同类型的元素的集合,结构也是一些值的集合,这些值称为它的成员。
声明一个结构体类型的形式:
在声明结构时,必须离出它包含的所有成员。这个列表包括每个成员的类型和名字。
接下来看看如何定义一个结构体变量:
也可以在声明类型的时候直接定义变量,如下:
关于结构体的类型要注意的几点:
(1)类型与变量是不同的概念,不要混淆。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。
(2)对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于同类型的普通变量。
(3)结构体的成员也可以是一个结构体变量。
那么结构体该如何初始化呢?直接上例子:
1.在定义结构体时直接初始化
2.在定义变量时进行初始化
有的同学可能会觉得每次定义变量的时候都需要写上很长的类型名,为了方便我们可以用typedef关键字,对类型进行重命名,如下:
那么,结构在内存中是如何存储的呢?先来看看我们之前定义好的结构体的大小:
发现是36个字节,这是因为结构体内部存在对齐规则。
1、第一个成员对齐到整个结构的0偏移处
2、从第二个成员开始,每个成员都要对齐到对齐数的整数倍处去
3、整个结构的最终大小必须是所有对齐数中最大对齐数的整数倍
对齐数----成员自身大小和默认对齐数中的较小值
默认对齐数:VS----8字节 Linux----4字节
默认对齐数是可以修改的,利用 #pragma pack(修改后的字节数),就可以对当前平台的对齐数进行修改。
那么,为什么要存在对齐规则呢?我们可以从以下两个方面去解释:
1.平台原因:不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则将抛出硬件异常。
2.性能原因:数据结构应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。
关于结构,就要说说它实现位段的能力。位段的声明和结构类似,但是它的成员是一个或多个位的字段。这些不同长度的字段实际上存储于一个或多个整型变量中。
位段的声明和任何普通的结构成员声明相同,但是有两个例外。首先,位段成员必须声明为int、signed int或unsigned int类型。其次,在成员名后面是一个冒号和一个整数,这个整数指定该位段所占用的位的数目。
struct node
{
unsigned int a:4; //位段a,占4位
unsigned int :0; //无名位段,占0位
unsigned int b:4; //位段b,占4位
int c:32; //位段c,占32位
int :6; //无名位段,占6位
};
位段在内存中的存储方式:对于位段结构,编译器会自动进行存储空间的优化,主要有这几条原则:
1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节).
2)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;
先来看看百度百科对结构体的定义:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构。数组是相同类型的元素的集合,结构也是一些值的集合,这些值称为它的成员。
声明一个结构体类型的形式:
struct Student //声明一个结构体类型Studet { char name[20];//声明一个字符型数组name char sex[5]; //声明一个字符型数组sex int age; //声明一个整形变量age float score; //声明一个单精度型变量score };
在声明结构时,必须离出它包含的所有成员。这个列表包括每个成员的类型和名字。
接下来看看如何定义一个结构体变量:
struct Student //声明一个结构体类型Studet { char name[20];//声明一个字符型数组name char sex[5]; //声明一个字符型数组sex int age; //声明一个整形变量age float score; //声明一个单精度型变量score };int main()
{
struct Student stu1;//这样就定义了一个结构体类型变量stu1
system("pause");
return 0;
}
也可以在声明类型的时候直接定义变量,如下:
struct Student //声明一个结构体类型Studet { char name[20];//声明一个字符型数组name char sex[5]; //声明一个字符型数组sex int age; //声明一个整形变量age float score; //声明一个单精度型变量score }stu2; int main() { stu2.age;//直接在声明类型的时候定义的变量访问成员 system("pause"); return 0; }
关于结构体的类型要注意的几点:
(1)类型与变量是不同的概念,不要混淆。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。
(2)对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于同类型的普通变量。
(3)结构体的成员也可以是一个结构体变量。
那么结构体该如何初始化呢?直接上例子:
1.在定义结构体时直接初始化
struct Student{ //声明一个结构体类型Student char name[20]; //声明一个字符型数组name char sex[5]; //声明一个字符型数组sex int age; //声明一个整形变量age float score; //声明一个单精度型变量 } stu1 = { "zhangsan", 'm', 20, 90, };
2.在定义变量时进行初始化
struct Student //声明一个结构体类型Studet { char name[20];//声明一个字符型数组name char sex[5]; //声明一个字符型数组sex int age; //声明一个整形变量age float score; //声明一个单精度型变量score }; int main() { struct Student stu1 = { "lisi", "男", 19, 100 }; system("pause"); return 0; }
有的同学可能会觉得每次定义变量的时候都需要写上很长的类型名,为了方便我们可以用typedef关键字,对类型进行重命名,如下:
那么,结构在内存中是如何存储的呢?先来看看我们之前定义好的结构体的大小:
发现是36个字节,这是因为结构体内部存在对齐规则。
1、第一个成员对齐到整个结构的0偏移处
2、从第二个成员开始,每个成员都要对齐到对齐数的整数倍处去
3、整个结构的最终大小必须是所有对齐数中最大对齐数的整数倍
对齐数----成员自身大小和默认对齐数中的较小值
默认对齐数:VS----8字节 Linux----4字节
默认对齐数是可以修改的,利用 #pragma pack(修改后的字节数),就可以对当前平台的对齐数进行修改。
那么,为什么要存在对齐规则呢?我们可以从以下两个方面去解释:
1.平台原因:不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则将抛出硬件异常。
2.性能原因:数据结构应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。
关于结构,就要说说它实现位段的能力。位段的声明和结构类似,但是它的成员是一个或多个位的字段。这些不同长度的字段实际上存储于一个或多个整型变量中。
位段的声明和任何普通的结构成员声明相同,但是有两个例外。首先,位段成员必须声明为int、signed int或unsigned int类型。其次,在成员名后面是一个冒号和一个整数,这个整数指定该位段所占用的位的数目。
struct node
{
unsigned int a:4; //位段a,占4位
unsigned int :0; //无名位段,占0位
unsigned int b:4; //位段b,占4位
int c:32; //位段c,占32位
int :6; //无名位段,占6位
};
位段在内存中的存储方式:对于位段结构,编译器会自动进行存储空间的优化,主要有这几条原则:
1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节).
2)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;
相关文章推荐
- 解析C语言结构体、位段
- 解析c语言结构体和位段
- C语言用结构体实现位段
- 浅析C语言位域和位段
- 在C语言中各种数据类型各占多少位 C语言 中结构体的位域(位段)
- 解析C语言结构体,位段
- C语言中的位运算&结构体浅析 — <编程之美>1.2学习笔记
- C语言中的位运算&结构体浅析 — <编程之美>1.2学习笔记
- 解析C语言结构体,位段
- C语言结构体中位域(位段)的使用
- C语言 中结构体的位域(位段)
- 解析C语言结构体,位段。
- 第09天C语言(18):结构体和函数
- C语言字符串和结构体
- C语言内存中结构体对齐分析
- C语言-结构体学习
- 有关c语言结构体能否直接赋值的问题
- 结构体之位域(位段)
- C语言结构体,位段
- C语言,内存对齐,内存分配,地址操作,结构体(一)