C语言-结构体详解

结构体详解

文章目录

  • 结构体详解
    • 1.结构体的声明
      • 匿名结构体
      • 结构体的自引用
    • 2.结构体的定义和初始化
    • 3.结构体的大小
    • 4.结构体传参

结构体是什么?
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
看了这个概念你有没有联想到其他,跟数组定义很类似,数组的是 相同类型元素的集合。
语法

1.结构体的声明

C语言的内置类型(int ,char , float…)无法描述一个复杂的变量,比如我需要描述一个人,需要姓名,年龄,性别这些信息,所以我们需要创建一个结构体类型来描述一个学生。

struct student
{
	char name[20];
	int age;
	char sex[5];
}

关键词是struct, 括号里面是结构体的成员列表。在这要注意一点,结构体声明的时候不能初始化。

匿名结构体

这是一种特殊的结构体声明,如图所示

struct
{
	char name[20];
	int age;
	char sex[5];
}s1={0};

需要注意的是匿名结构体声明只能用一次,看下面的代码。

 struct 
 {
 	int a;
 	char c;
 	float f;
 }x;
 struct 
 {
 	int a;
 	char c;
 	float f;
 }*p;

请问能不能写成

p=&x;

答案是不行,因为编译器会认为p和 x是两个完全不同的类型。

结构体的自引用

结构体里面能不能包含自己本身呢?当然可以,不过需要注意的是,得写成指针得形式

struct s
{
	int a;
	char c;
	struct s z;
}//error
struct s
{
	int a;
	char c;
	struct s* ps;
}

如果写成第一种的形式,用sizeof(struct s)计算这个结构体的大小就可以看出这是完全不行的。

2.结构体的定义和初始化

struct student
{
	char name[20];
	int age;
	char sex[5];
}s1={"zhangsan",21,"male"};
int main()
{
	struct student s2={.age=21,.name="lisi",.sex="male"};
	return 0;
}

s1和s2都是定义的结构体变量,这两个的区别就是s1是全局变量,s2是局部变量。
. 操作符可以访问结构的成员变量,如果不按顺序初始化可以用.操作符

3.结构体的大小

这里涉及到内存对齐,先来看一下内存对齐的规则

1.结构体的第一个成员永远相较与结构体起始变量位置的偏移量为0的位置
2.从第二个成员开始,往后的每个成员都要对齐到某个对齐数的整数倍处
对齐数:结构体成员自身的大小和默认对齐数的较小值
3.结构体的总大小,必须是最大对齐数的整数倍(最大对齐数是所有成员的对齐数中最大的值)

这里简单举个例子

#include 
struct s
{
	int a;//对齐数是4;
	char b;//对齐数是1
	int c;//对齐数是4
}int main()
{
	printf("%d\n", sizeof(struct s));
	return 0;
}

问结构体的大小是多少,看图
C语言-结构体详解_第1张图片

很简单,对照着规则应该很容易看懂
可以验证一下
C语言-结构体详解_第2张图片

4.结构体传参

这里简单说一下两者的区别

struct s
{
	int a;
	char b;
	int c;
};
int main()
{
	struct s s1={12, 'c', 41};
	print(s1);//传参
	print(&s1);传址
	return 0;
}

image.png
用人话讲大概就是传址更节省空间,毕竟一个地址只有4/8个字节,而如果传参就是要重新开辟一个结构体大小的空间。

你可能感兴趣的:(c语言)