定义:
结构是一些值的集合,成员类型可以不一样;
//结构体定义:
struct peo
{
char name[20];
int age;
char sex[6];
} x, arr[20],* p;
// struct peo 是自定义的类型名,类似于int ,char
// x是这个类型的全局变量,
// arr[20]是这个类型的数组
// p 是struct peo*型指针
匿名结构体:
// 匿名结构体 : 这个结构体只能使用一次
struct
{
int age;
char name[20];
} p1;
int main()
{
//因为在创建结构体的时候已经创建了p1,所以可以用
p1={18,"lisi"};
//但是我们不能再创建变量
return 0;
}
结构体与 typedef :
//结构体与 typedef(重命名)
typedef struct peo
{
int age;
char name[20];
}peo_,* point;
// 相当于 typedef struct peo peo_;
// 相当于 typedef struct peo* point;
// struct peo s1 == peo_ s1; peo_ 就是struct peo类型
// struct peo * p == point p; point 就是struct peo* 型
结构体变量的定义与初始化:
//结构体变量的定义和初始化
// p1,p2 都是全局变量,而p3,p4,p 是局部变量
struct peo
{
char name[20];
int age;
} p1={"lisi",18};
struct peo p2 = { "zhangsan",20 };
struct stu
{//结构体里面套结构体:
struct peo p4;
int math;
int Eng;
};
int main()
{
struct peo s3 = { "wanger",30 };
struct stu p = { {"zhuwu,24"},90,60 };
printf("%s %d %d %d\n", p.p4.name, p.p4.age, p.math, p.Eng);
return 0;
}
内存对齐:
(求结构体所占内存大小)
#include<stdio.h>
#include<stddef.h>
struct s1
{
char c1;
int i;
char c2;
};
struct s2
{
char c1;
char c2;
int i;
};
int main()
{
struct s1 a;
struct s2 b;
printf("%d\n", sizeof(a));
// 12
printf("%d\n", sizeof(b));
// 8
// offsetof 是宏,可以求成员在结构体中的偏移量 <stddef.h>
printf("%d ", offsetof(struct s1, c1));
printf("%d ", offsetof(struct s1, i));
printf("%d \n", offsetof(struct s1, c2));
// 0 4 8
printf("%d ", offsetof(struct s2, c1));
printf("%d ", offsetof(struct s2, c2));
printf("%d \n", offsetof(struct s2, i));
// 0 1 4
return 0;
}
struct s3
{
double d;
char c;
int i;
};
//16
struct s4
{
char c1;
struct s3 S;
double d;
};
//32
为什么这么设计呢?
其实是在用空间换取时间,当不进行对齐的时候,读取一个完整的数据要对内存做两次访问,而对齐的话,只需要进行一次访问。
为了节省空间:尽量占用空间小的成员集中在一起,
像s1和s2,虽然里面成员类型相同,但s1所占空间远大于s2。
修改默认对齐数:
使用 #pragma (一般设置为 2 的倍数)
#pragma pack(4)
struct S1
{
int i;
double d;
};
//恢复默认对齐数
#pragma pack()
struct S2
{
int i;
double d;
};
int main()
{
printf("%d\n", sizeof(struct S1)); // 12
printf("%d\n", sizeof(struct S2)); // 16
return 0;
}
结构体传参:
struct S
{
int arr[10];
int i;
};
void print_1(struct S as)
{
for (int i = 0; i < 4; i++)
printf("%d ", as.arr[i]);
printf("%d\n", as.i);
}
void print_2(const struct S* ps)
{
for (int i = 0; i < 4; i++)
printf("%d ", ps->arr[i]);
printf("%d\n", ps->i);
}
int main()
{
struct S s1 = { {1,2,3,4},66 };
//传值
print_1(s1);
//传地址
print_2(&s1);
return 0;
}
第①种是将s1的值拷贝给临时变量as,又调用了空间;
第②种是将s1的地址给ps,通过地址访问其中的每个数据,加上const 修饰,保证不能随意被修改
so 结构体传参 的时候最好 传地址
标签:struct,自定义,int,s1,char,peo,printf,类型,结构 From: https://blog.csdn.net/weixin_65994469/article/details/144325252