三、修改默认对齐数
对齐数也是可以被修改的,利用到#pragma 这个预处理指令;
未修改前的结构体大小:
#include <stdio.h> struct S1 { char c1; int i; char c2; }; int main() { printf("%d\n", sizeof(struct S1)); return 0; }
修改后的:
#include <stdio.h> #pragma pack(1)//设置默认对齐数为1 struct S1 { char c1; int i; char c2; }; int main() { printf("S1所占字节数:%d\n", sizeof(struct S1)); return 0; } #pragma pack()//取消设置的默认对齐数,还原为默认
四、结构体的传参
#include <stdio.h> struct S { int data[1000]; int num; }; struct S s = { {1,2,3,4}, 1000 }; //结构体传参 void print1(struct S s) { printf("%d\n", s.num); } //结构体地址传参 void print2(struct S* ps) { printf("%d\n", ps->num); } int main() { print1(s); //传结构体 print2(&s); //传地址 return 0; }
上面两个代码print1传的是结构体,print2传的是结构体的地址 ,我们要首选print2这种传参方式;
原因:
函数传参的时候,参数是需要压栈,(这里可以去查看我之前的博客,函数栈帧的创建和销毁https://blog.csdn.net/sjsjnsjnn/article/details/122811828?spm=1001.2014.3001.5502)会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降
五、结构体成员的访问
1. 结构变量的成员是通过点操作符(.)访问的:结构体变量.成员变量
2. 结构体指针访问指向变量的成员,结构体指针->成员变量名
#include <stdio.h> struct Stu { char name[10];//学生的姓名 int age;//学生的年龄 char sex[10];//学生的性别 char id[15];//学生的学号 }; int main() { struct Stu stu = { "zhangsan",20,"male","10001" }; struct Stu* p = &stu; //点操作符访问成员 printf("name=%s age=%d sex=%s id=%s\n", stu.name, stu.age, stu.sex, stu.id); //指针访问成员 printf("name=%s age=%d sex=%s id=%s\n", p->name, p->age, p->sex, p->id); //通过解引用相当于得到了stu,所有用点操作符 printf("name=%s age=%d sex=%s id=%s\n", (*p).name, (*p).age, (*p).sex, (*p).id); return 0; }
六、总结
对于结构体这一章节,比较重要的是内存对齐的规则和结构体传参,掌握了这些基本的用法,相信对于结构体的使用,不是很困难。