站长做什么网站赚钱,传承网页设计公司,有了域名怎样做淘客网站,网站浏览器兼容性问题吗结构体
结构#xff1a;一些值的集合#xff0c;这些值称为成员变量。结构体的每个成员可以是不同类型的变量#xff1b;
结构体声明#xff1a;struct是结构体关键字#xff0c;结构体声明不能省略struct#xff1b;
匿名结构体#xff1a;只能在声明结构体的时候声…结构体
结构一些值的集合这些值称为成员变量。结构体的每个成员可以是不同类型的变量
结构体声明struct是结构体关键字结构体声明不能省略struct
匿名结构体只能在声明结构体的时候声明结构体成员之后再想用这个结构体声明结构体成员时就不行了因为匿名结构体只能用一次没有结构体名字没有办法声明结构体成员只打算用一次的结构体 结构体变量的声明与初始化
结构体变量的初始化需要使用大括号进行初始化
// 结构体成员的声明与初始化
struct student
{ // 声明的是一个描写学生的结构体char name[20];int age;char sex[5];
} s1 { 张三, 18, 男 }; // 声明的是结构体成员并初始化
int main()
{struct student s2 { 李四, 19, 女 }; // 声明的是结构体成员并初始化struct student s3 { .age 20, .name 王五, .sex 男 }; // 指定初始化结构体成员变量通过 . 指定// 如果不指定初始化结构体成员变量就顺序初始化printf(%s %d %s\n, s1.name, s1.age, s1.sex);printf(%s %d %s\n, s2.name, s2.age, s2.sex);printf(%s %d %s\n, s3.name, s3.age, s3.sex);return 0;
} 结构的自引用
可以包含同类型的结构体指针但是不能包含同类型结构体
#include stdio.h
struct Node
{int data; // 存储数据 - 数据域struct Node* n; // 存放下一个节点的地址 - 指针域// 可以包含同类型结构体指针但是不能包含同类型结构体
}; 结构体内存对齐
怎么对齐
1、第一个成员在结构体偏移量为0的地址处存放
2、其他成员变量要对齐到对齐数的整数倍的地址处
3、对齐数VS默认对齐数、结构体成员自身大小就是对齐数取较小的对齐数
4、结构体总大小为最大对齐数的整数倍每个成员都有一个对齐数所有成员中的最大对齐数
5、嵌套结构体的对齐嵌套的结构体要对齐到自身最大对齐数的整数位结构体的大小就是所有成员中的最大对齐数的整数倍
为什么对齐
1、不是所有硬件平台都能访问任意地址上的数据的有些只能在特定位置处取某些特定数据
2、结构体尤其是栈应该尽可能在自然边界上对齐未对齐的内存处理器需要访问两次而对齐的只需访问一次
3、结构体的内存对齐就是拿空间换取时间的
如何节省空间让占用空间小的成员集中在一起 代码验证
#include stdio.h
int main()
{struct S{char c1;int a;double b;char c2;}s;struct S1{int a;char c1;char c2;double b;}s1;printf(%d\n, sizeof(s));printf(%d\n, sizeof(s1));return 0;
} 百度笔试题 写一个宏计算结构体中某变量相对于首地址的偏移offsetof宏 offsetof宏的使用
#include stdio.h
#include stddef.h
int main()
{struct S{char c1;int a;double b;char c2;}s;struct S1{int a;char c1;char c2;double b;}s1;// offsetof宏结构体成员变量相对于首地址的偏移量printf(%d %d %d %d\n, offsetof(struct S, c1), offsetof(struct S, a), offsetof(struct S, b), offsetof(struct S, c2));printf(%d %d %d %d\n, offsetof(struct S1, a), offsetof(struct S1, c1), offsetof(struct S1, c2), offsetof(struct S1, b));printf(%d\n, sizeof(s));printf(%d\n, sizeof(s1));return 0;
} 结构体传参
1、传值调用形参相当于一份临时拷贝修改形参不会改变实参
2、传址调用如果不加上const修改新参就会改变实参
3、传址调用比传值调用更节省空间结构体传参尽量传址 位段
1、设计位段的目的就是为了节省空间
2、位段的成员必须是int、unsigned int、signed intc99之后其他类型也可以但是基本都是int、char类型
3、位段的成员名后边有一个冒号和一个数字数字表示几个比特位
4、位段为表示二进制位
#include stdio.h
int main()
{struct S1 // 结构体{int a;int b;char c;};struct S2 // 位段{int a : 2;int b : 4;char c : 1;};printf(%d\n, sizeof(struct S1));printf(%d\n, sizeof(struct S2));return 0;
} 位段的内存分配
1、不知道是从低位开始分配还是从高位才是分配这是不确定的 位段的跨平台问题
1、int位段被当成有符号数还是无符号数是不确定的
2、位段中最大位的值是不确定的
3、位段中的成员在内存中从右到左还是从左到右分配标准未定义
4、一个结构包含两个位段第二个位段无法容纳于第一个位段剩余的位时是舍弃位还是利用是不确定的 枚举
枚举类型的定义
1、把可能的取值一一列举月份、星期
2、必须包含关键字enum
3、枚举的值是默认从0一次递增的
4、枚举常量的默认值是可以修改的
#include stdio.h
enum Color
{RED, // 注意这是逗号不是分号GREEN,BLUE // 最后这里什么符号都没有
};
enum Sex
{MALE 2, // 枚举常量的默认值是可以修改的FEMALE 4,CECRECY 1
};
int main()
{printf(%d\n, RED);printf(%d\n, GREEN);printf(%d\n, BLUE); // 打印枚举常量printf(%d\n, FEMALE);return 0;
}枚举的优点
1、枚举可以增加代码的可读性和可维护性
2、#define是用于替换的没有类型的但枚举有类型检查
3、可以一次定义多个常量 联合共用体
1、联合定义的变量包含一系列的成员
2、这些成员共用同一块空间所以也叫做共用体
3、在同一时间段内联合体内的成员不能同时使用只能使用其中一个
4、如果修改联合体内其中一个成员的值则另一个的值也会改变
5、联合体的关键字union
#include stdio.h
union Un
{int a;char b;
};
int main()
{union Un un;un.a 10;un.b a; printf(%d\n, sizeof(un)); // 大小是成员中较大的那个大小printf(%p\n, un);printf(%p\n, (un.a));printf(%p\n, (un.b)); // 说明联合体共用一块空间return 0;
} 联合体大小的计算
1、联合体的大小是最大成员的大小这句话是错的
2、联合体的大小至少是最大成员的大小
3、当最大成员大小没有对齐到最大对齐数的整数倍时就要对齐到最大对齐数的整数倍处
#include stdio.h
union Un
{short a[7]; // 对齐数 2int b; // 对齐数 4// a占14个字节// 但是不是最大对齐数的整数倍// 所以联合体的大小是16
}un;
int main()
{printf(%d\n, sizeof(un));return 0;
}