C语言 - 结构体struct
结构体:struct,用户自己设计的 不同类型组合的 组合数据类型
格式
调用结构体
结构体的打印
指针与结构体的结合
引用与结构体结合
结构体的套接
结构体:内存对齐
共用体:union,共用内存,达到对不同的类型进行解析的目的
共用体的用法
//quesiton:如何实现CSDN博客间的跳转
格式:
[code] struct Student{ char name[20]; //姓名 int num[20]; //学号 int age; //年龄 char group; //所在学习小组 float score; //成绩 };
调用结构体:
[code]int main(){ Student student; //定义结构体变量 student.s_age=22;//给结构体内部赋值 student.s_name[20]="xiaoxuxu"; //× //结构体内若是一个数组或者字符串,不能直接赋值 //需要用拷贝函数 strcpy(s1.s_name,"string"); //可以整体打印? 答案:不可以 //除了整体初始化外,其余的都是分开操作,一个一个打印出来 }
访问并修改结构体内部数据:
1.逐个赋值: 使用 . (成员访问符)
2.整体赋值: Student s1 = {"LU","201901",18,"A",80}; // 利用花括号整体一一对应初始化
//注意:结构体内部为int num[20]; 赋值的时候是201901
//当结构体内部为char num[20]; 赋值的时候是"201901"
//注意:初始化时,不能跳着初始化(略过其中属性)
Student s2 = s1; //整体赋值 本质是调用内存拷贝函数 my_memmove(&s3,&s1,sizeof(Student));
结构体的打印:
[code]//值传递:直接开辟了一个Student类用来打印 void Print_Student(Student stu){printf: stu.s_name , stu.s_num....} main:Print_Student1(stu1); //指针:指针只开辟4个字节,相对节省空间, //缺点:为了防止不小心改变pstud的指向的内容 需要在前面加const 防止指向的内容被修改 //缺点:使用指针 一定要判空,防止空指针的存在 void Print_Student1(Student const *pstud) { if(NULL == pstud) return ; printf: pstud->s_name , pstud->s_num.... } main:Print_Student2(&stu1); //指针传递的是地址 //引用(起小名):避免开辟空间造成的空间浪费 void Print_Student1(Student const &stu){printf: stu.s_name , stu.s_num....} main:Print_Student1(stu1);
指针与结构体的结合:(指向作用 -> )
[code] ps ->s_age = 10; //ps指针指向s1 (*ps).s_age = 10; //等价 //.和*的优先级 => .的优先级first
引用与结构体结合:
[code]//引用与结构体的结合: Student &s = s2;//定义了一个Student类的变量s2,给s2起小名叫s
结构体的套接:
结构体可以套接结构体,但是函数不可以套接函数
(函数内部可以申明函数,不可以新定义一个函数)
[code]//定义函数 //× int Add(int x int y){ return x+y; } //申明函数 //√ int Add(int x int y); int fun(int ,int );
[code]//结构体套接结构体: struct Date { int year; int month; }; struct Student { char s_id[20]; struct Date birthday; //定义一个Date型的结构体变量 birthday }; //=========等价========= struct Student { char s_id[20]; struct Date { int year; int month; }; struct Date birthday; //struct 在.cpp文件中可以省略 };
结构体:内存对齐(存疑)
内存对齐遵循原则:
1.当前成员所在的地址 能够整除 成员本身的字节大小 (不包括数组)
2.结构体的整体大小能够能整除除成员最大基本类型 大小(不包括数组)
3.从零地址开始另一种理解:
偏移量:结构体中的偏移量就是结构体成员和结构体变量的地址之差
计算结构体大小的规则:
1.每一个成员的偏移量都必须是该成员的倍数。
2.结构体的大小必须是该结构体字节数最大成员的倍数。
[code]例如下面的结构体: struct A { char a; short b; int c; }; /*第一个成员的偏移量都是0;一般可以不看,a的大小为1,所以成员b的偏移量为1,b的大小 为2,1不是2的倍数,所以应该将1+1,成为2的倍数,成员c的偏移量就为1+1+2,是成员c的 倍数,现在就符合计算结构体大小的第一条:改成员的偏移量是该成员大小 的倍数,还有第二条规则:结构体大小是结构体最大成员的倍数,结构体的大小就是各个成员 之和,a;2,b:2,c:4加起来就是8,该结构最大成员为c大小为4,满足第二个条件,所以该结 构体的倍数就是8*/
参考博客:https://www.cnblogs.com/smile-812/p/7897187.html
[code]struct AA { char a; // 1 + 3 short b; // 4 int c; // 4 double d; // 8 }; //16 struct A { char a; // 1 + 3 [0,1,2,3] (1,2,3浪费) int b; // 4 [4,5,6,7] }; //[0-7] 大小为8,向前对齐 struct A1 { char a; //1 char c; //1 int b; //4 }s; // 大小为8 struct B { char a; //1 + 1 [0,1] short b; //2 [2,3] int c; // 4 [4,5,6,7] }; // [0-7]大小为8,向前对齐 struct C { char a; // 1 + 3 [0,1,2,3] int b; // 4 [4,5,6,7] short c; // 2 + 6 [8-15] double d; // 8 [16-23] }; // [0-23]大小为24,向前对齐 struct D { char a; // 1 [0] char b; // 1 [1] short c; // 2 [2,3] int d; // 4 [4,5,6,7] }; // [0-7]大小为8,向前对齐 struct E { char a; // 1 + 1 [0,1] short c; // 2 [2,3] char b; // 1 + 3 [4,5,6,7] int d; // 4 [8,9,10,11] }; // [0-11]大小为12,向前对齐 struct F { int a; // 4 [0,1,2,3] char c; // 1 + 3 [4,5,6,7] }; //[0-7]大小为8,向后对齐,一般只有两个数据成员 struct G { char ch[17]; //17 + 3 20能被4整除 int i; // 4 float f; //4 }su; // 大小为28 struct H { char a; //1 +1 short b; //2 char c; //1 +3 int d; //4 char e[3]; //3 +1 }; // 大小为16
干预内存对齐:
#pragma pack(n) // n = 1,2,4,8,16
//n = 1;强制要求内存按照1字节对齐;
共用体:
共用体:共用内存 ;; 最主要的用途 : 对不同的类型进行解析
结构体:自己独占内存,所占内存是各成员占用内存长度之和(存在内存对齐)
[code]union A{ char a; short b; int c; }; struct B{ char a; short b; int c; }; int main(){ A x1; //x1.a = 'a'; //这里内存互相侵占了 //x1.b = 12; B x2; x2.a = 'a'; //自己用自己的 不影响 x2.b = 12; }
共用体的用法:
共用体的用法:对同一个空间按不同类型去识别
//共用体可以套用结构体
//结构体可以套用联合体
[code]//直接使用共用体 union Node{ unsigned int addr; unsigned char s1,s2,s3,s4; //对于联合体而言s1,s2,s3,s4都用的是同一个字节 }; //共用体套用结构体 union Node{ unsigned int addr; sruct{ unsigned char s1,s2,s3,s4; //分布于四个字节了 }; } //结构体套用共用体 struct Node{ char ch; union{ //无名共用体:哑元结构 int a; //a和f共享同一个内存 float f; };//1+4 =6 凑/4 =>8个字节 }; //这里还需深一步理解,为何要这么做! 每种结构都有什么好处
- 点赞
- 收藏
- 分享
- 文章举报
- struct来处理C语言中的结构体
- C语言和C++中结构体struct区别
- C语言中结构体struct编写的一些要点解析
- [C语言 - 7] 结构体struct
- C语言第七讲(Struct结构体)
- c语言结构体 和 typedef struct与struct的区别
- 解析C语言中结构体struct的对齐问题
- 学习日记-C语言结构体(struct)
- C语言中结构体struct的对齐问题解析
- C语言中结构体struct类型使用
- C语言 结构体struct
- C语言新手想问一下可以改变struct结构体某一数据的字体颜色吗
- [struct]C语言编程结构体的学习
- C语言中结构体(struct)乱序初始化
- C语言中的结构体(struct)
- [C语言 - 7] 结构体struct
- 【C语言】21-struct结构体
- C语言中free()函数释放struct结构体中的规律
- IOS-C语言第8天,Struct (结构体)
- 《黑马程序员》 结构体struct (C语言)