结构体的定义和使用和位段的使用
2017-07-10 16:40
295 查看
结构体(struct),也叫结构,是由一系列具有相同类型或不同类型的数据构成的数据集合。
比如:描述一个学生,可能需要描述他的学号,姓名,成绩等。
一. 声明及定义结构体变量
有三种方法定义结构体变量
1. 先声明结构体类型,再定义该类型的变量,例如:
2 声明的同时定义,例如
3. 不指定类型名直接定义结构体类型变量,匿名定义,只能用一次
二.结构体变量的初始化
1直接初始化
2.用typedef定义后用改变后的类型名定义
用typedef将原来的类型名struct student 改为student 在定义
三. 结构体在内存中的储存
这个程序运行的结果是96
为什么那?
内存对齐的3条规则(要牢记):
1、结构的第一个成员永远都放在结构的0偏移处。
偏移就是往后挪,n偏移就是从系统默认开始分配内存的地方往后挪n个字节,0偏移就是挪0个,也就是相当于没有挪。
2、从第二个成员开始,都要对齐到某个某个对齐数的整数倍处。
对齐数:结构体成员自身大小和默认对齐数的较小值。
默认对齐数:VS-----8 linux-----4
3、结构体的总大小必须是最大对齐数的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。
例如:
内存对齐的原因吧。
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处去某些特定类型的数据,否则跑出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要访问。
五. 位段
1、位段成员必须声明为int,signed int,unsigned int类型,在成员名的后面是一个冒号的一个整数,这个整数该位段所占用的大小。
2、首先,位段的成员在内存里面存储是从左到右还是从右到左的是不确定的,其次,当一个声明指定两个位段,第二个位段无法存储在第一个的剩余位上时,第二个位段直接存储于下一个字节上还是将第一个位段剩余的空间占满后剩下的存储到下一个字节也是不确定的。
因此,位段不能跨平台使用。
在vs平台上这个位段的大小为2个字节
比如:描述一个学生,可能需要描述他的学号,姓名,成绩等。
一. 声明及定义结构体变量
有三种方法定义结构体变量
1. 先声明结构体类型,再定义该类型的变量,例如:
struct student { char name[20]; char sex[5]; char number[30]; double score[50]; }a1,a2;
2 声明的同时定义,例如
struct student { char name[20]; char sex[5]; char number[30]; double score[50]; }a1,a2;
3. 不指定类型名直接定义结构体类型变量,匿名定义,只能用一次
empty
二.结构体变量的初始化
1直接初始化
struct student { char name[20]; char sex[5]; char number[30]; double score[5]; }; int main() { struct student n = { "zhangsan", "nan", "201512030223", {100,100,100,100,100} }; return 0; }
2.用typedef定义后用改变后的类型名定义
用typedef将原来的类型名struct student 改为student 在定义
typedef struct student { char name[20]; char sex[5]; char number[30]; double score[5]; }student; int main() { student n = { "lisi ", "nan", "201512030224", { 60, 60, 60, 60, 60 } }; return 0; }
三. 结构体在内存中的储存
typedef struct student { char name[20]; char sex[5]; char number[30]; double score[5]; }student; int main() { printf("%d\n",sizeof(student)); system("pause"); return 0; }
这个程序运行的结果是96
为什么那?
内存对齐的3条规则(要牢记):
1、结构的第一个成员永远都放在结构的0偏移处。
偏移就是往后挪,n偏移就是从系统默认开始分配内存的地方往后挪n个字节,0偏移就是挪0个,也就是相当于没有挪。
2、从第二个成员开始,都要对齐到某个某个对齐数的整数倍处。
对齐数:结构体成员自身大小和默认对齐数的较小值。
默认对齐数:VS-----8 linux-----4
3、结构体的总大小必须是最大对齐数的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。
例如:
#define _CRT_SECURE_NO_WARNINGS 1 #include typedef struct student { char name[20];//0-19 char sex[5];//20-24 char number[30];//25-54 double score[5];//56-95 }student;//总大小为96 struct student1 { student a;//0-95 char b;//96 }; //总大小为97,但是必须为最大步数(double)的整数倍 //所以大小为104 int main() { printf("%d\n",sizeof(struct student1)); system("pause"); return 0; }
内存对齐的原因吧。
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处去某些特定类型的数据,否则跑出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要访问。
五. 位段
1、位段成员必须声明为int,signed int,unsigned int类型,在成员名的后面是一个冒号的一个整数,这个整数该位段所占用的大小。
2、首先,位段的成员在内存里面存储是从左到右还是从右到左的是不确定的,其次,当一个声明指定两个位段,第二个位段无法存储在第一个的剩余位上时,第二个位段直接存储于下一个字节上还是将第一个位段剩余的空间占满后剩下的存储到下一个字节也是不确定的。
因此,位段不能跨平台使用。
struct syudent { char a : 2; char b : 5; char c : 7; };
在vs平台上这个位段的大小为2个字节
相关文章推荐
- DELPHI结构体的定义和使用
- linux大量使用了static关键字用来修饰函数和结构体定义,为何?
- 汇编结构体的使用获取系统时间以及宏的定义和使用
- 结构体语法梳理1-基本定义及使用
- 位域结构体的定义示例及其与联合体的定义使用
- 结构体的定义以及使用
- 标准C++编程学习第一天之C++命名空间&结构体的定义和使用
- enum 使用技巧MFC可以定义在类中、结构体中
- iovec结构体定义及使用
- iovec结构体定义及使用
- C语言结构体中位域(位段)的使用
- 结构体的定义及使用
- c语言数据类型定义和总结构体的使用
- 结构体的定义以及使用
- 解析结构体的定义及使用详解
- C语言技巧--在结构体中使用函数例子(定义一个指向函数的指针)
- 关于结构体定义时初始化及结合数组使用问题 示例
- C#结构体指针的定义及使用详解
- typedef定义的struct类型与struct定义的结构体变量在使用上的区别
- c语言 结构体 、数组的使用,定义的同时必须初始化,否者它们成员的数值会错乱,不是想象的样子