结构体

C语言中有许多内置类型,例如int、float、short、char等等,这些是系统已经帮我们规定好的东西,但是在实现操作中我们会发现仅仅只有这些类型是不够的,因此就产生了自定义类型,最知名的自定义类型就是结构体、联合体、枚举体

结构体定义

结构体就是把一组不同类型的元素放在一个集合里,这些元素构成的集合叫做结构体
结构体声明
struct tag
{};
//注意分号
tag作为结构体的标签,在后续结构体的修改赋值操作中起到重要作用,当然你也可以忽略tag创建一个匿名结构体,但是它在后续中无法修改(只能调用一次)
例:

struct stu
{
	char name[20];
	int age;
	int height;
}student={"xxx",18,170};

//or

struct stu
{
	char name[20];
	int age;
	int height;
};
int main()
{
	struct stu student={"xxx",18,170};
	return 0;	
}	

建立了一个标签位stu的结构体,结构体中包含name、age、height三个信息,并且创建并初始化了student结构体变量

结构自我调用

struct stu
{
	int i;
	struct stu next;
};	//①

struct stu
{
	int i;
	struct stu* next;
};  //②

上述代码,①报错②正常,①式中我们知道意义是在结构体中装入int和本身,显而易见肯定是不行的,相当于一个房子里放一个相同大小的房子,这怎么可能呢,但是如果我们放入的是房子的地址牌,那是不成问题的。
②式同理,对于指针来说,无非就是4字节or8字节。
结论:结构体不能装入自己

结构体访问

常见的结构体访问有两种,直接访问和指针访问,对应得操作符也不同
直接访问:

struct tag
{
	char name[20];
	int age;
	float height;
}stu;
int main()
{
	struct tag stu={"xxx",18,170.0};
	printf("%s ",stu.name);
	printf("%d ",stu.age);
	printf("%f ",stu.height);
	return 0;
}

变量名 . 元素名

指针访问

struct tag
{
	char name[20];
	int age;
	float height;
}stu;
int main()
{
	struct tag stu={"xxx",18,170.0};
	struct tag* ptr=&stu;
	printf("%s ",ptr->name);
	printf("%d ",ptr->age);
	printf("%f ",ptr->height);
	return 0;
}

结构体内存对齐

*⾸先得掌握结构体的对⻬规则:

  1. 结构体的第⼀个成员对⻬到相对结构体变量起始位置偏移量为0的地址处
  2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。 对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。 - VS中默认的值为8 - Linux中没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
  3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的 整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。*

例:

struct S1
{
 char c1;
 int i;
 char c2;
};
int main()
{
	printf("%zd\n", sizeof(struct S1));
	return 0;
}

下意识得觉得输出为6,实际上其实是12,下列我们来图解一下
在这里插入图片描述

结构体传参

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;
}

两种方法在语法层面都是允许的,但是如果考率时间空间问题我们要优先使用地址传参,
结构体在内存中是存储在堆区,我们去调用结构体是需要去压栈开辟空间,如果直接调用,在结构体本身非常大的情况下需要开辟大量空间,而地址不一样,不是4B就是8B,空间开辟效率高,带来的结果就是空间省,时间短。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shall#

你的鼓励将是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值