入门C语言第六话:初阶结构体

前言

 当我们要描述一个物体时,这时我们目前学到整形,浮点数之类的只能描述一种特征的数据类似已经不能够满足现状,这时我们就需要一个将它们整合起来的类型——结构体.
 如果你学过结构体,不妨思考下列的问题,来考验一下你对结构体的了解程度;如果没学过,那就让我们带着这些问题,走入结构体的学习吧!
在这里插入图片描述
小小建议:手机/电脑 保存下来看,清晰度更高!

正文

一.结构体与数组

数组:有限个相同元素的集合,有序的元素序列。
结构体:可以是不同变量的集合,也可以是相同变量的集合,可以是结构体,指针,数组,整形,字符类型等。

结构体数组:是结构体还是数组?是数组,准确的说,是存放结构体的数组。

二.结构体变量的定义与初始化

法1:

#include<string.h>
struct BOOK
{
	char name[20];
	int price;
	
}stu;
int  main()
{
	strcpy(stu.name,"shun_hua");
	stu.price = 8;
	return 0;
}

stu是一个全局变量,因为定义在函数的外部。

图解:
在这里插入图片描述
法2:

struct BOOK
{
	char name[20];
	int price;
	
}stu = { "shun_hua",8 };
//在定义结构体的同时,同时定义与初始化结构体变量。

法3:
匿名结构体类型(即使匿名结构体的类型相同但还是两个不同的结构体)

struct
{
	char name[20];
	int price;
}stu;
struct
{
	char name[20];
	int price;
}*p;
int  main()
{
	strcpy(stu.name,"shun_hua");
	stu.price = 8;
	//*p=&stu;这个代码在编译器的角度来说就是错误的。
	return 0;
}

缺点:这样的结构体定义过后只能用定义的那一个变量(stu)。
法4:

struct BOOK
{
	char name[20];
	int price;

};
int main()
{
	struct BOOK author = { "shun_hua",18 };
	//逆序初始化:struct BOOK author ={.price=18,.name="shunhua"};
	return 0;
}

图解:
在这里插入图片描述
法5:

typedef struct BOOK
{
	char name[20];
	int price;
}stu;
int main()
{
	stu author = { "shun_hua",18 };
	return 0;
}

图解:
在这里插入图片描述

注意:
  1.结构体成员的初始化,最好按照顺序来赋值。
  2.结构体的定义是可以定义在函数内部的,不过不建议,全局变量方便函数之间使用。
  3.结构体成员定义时,中文写分号不会报错,只会在你使用时,才会报错。
  4.结构体定义时,成员只能声明,不能赋值。

三.结构体的访问

1.结构体变量访问成员用 .
2.结构体指针访问成员用 ->
注意:这两种符号只能访问结构体成员。没有结构体指针->结构体指针->结构体成员的用法。

1.变量访问

typedef struct MEN
{
	char name[20];
	float weight;
}men;
typedef struct BOOK
{
	char name[20];
	char author[20];
	men man;
}stu;
int main()
{
	stu book = { "c语言程序与设计","谭浩强",{"舜华",70} };
	//scanf("%s %s", &book.author, &book.name);
	printf("%s %s", book.author, book.name);
	printf("%s %.1f", book.man.name, book.man.weight);
	return 0;
}

在这里插入图片描述

2.指针访问

typedef struct MEN
{
	char name[20];
	float weight;
}men;
typedef struct BOOK
{
	char name[20];
	char author[20];
	men man;
}stu;
int main()
{
	stu book = { "c语言程序与设计","谭浩强",{"舜华",70} };
	stu* p = &book;
	//scanf("%s %s", &p->author, &p->name);
	printf("%s %s", p->author, p->name);
	printf("%s %.1f", p->man.name, p->man.weight);
	return 0;
}

在这里插入图片描述

补充:结构体的自引用

注意:结构体自身是不能在结构体成员里面再出现,这样陷入了无限套娃的层次,不合法。但是结构体自身的指针是可以被直接引用的。

//第一种
struct Book
{
	int book;
	struct BOOK* next;
};
//第二种
typedef struct man
{
	int age;
	struct man* next;
}man;

下面的是错误的:

typedef struct 
{
	int age;
	man* next;
}man;

可以这样理解编译器在扫描时是从上往下扫描的,里面的man在编译器的角度看是不符合语法规定的,所以不合法。

四.结构体传参

1.传值调用:函数接收的是结构体的值,是一份临时拷贝,并不是传入的的那个结构体变量本身。
2.传址调用:函数接收的结构体指针的值,是指针的一份临时拷贝,不是传入的结构体指针本身。
联想数组:数组传进去的本质是指针。数组名是数组首元素的地址。

1.传值

typedef struct MEN
{
	char name[20];
	float weight;
}men;
typedef struct BOOK
{
	char name[20];
	char author[20];
	men man;
}stu;


stu  print(stu book1)
{
	scanf("%f", &book1.man.weight);
	return book1;
}
int main()
{
	stu book = { "c语言程序与设计","谭浩强",{"舜华",70} };
	book=print(book);
	printf("%f", book.man.weight);
	return 0;
}

在这里插入图片描述

2.传址调用

typedef struct MEN
{
	char name[20];
	float weight;
}men;
typedef struct BOOK
{
	char name[20];
	char author[20];
	men man;
}stu;


void print2(stu* p1)
{
	scanf("%f", &p1->man.weight);
}
int main()
{
	stu book = { "c语言程序与设计","谭浩强",{"舜华",70} };
	stu* p = &book;
	print2(p);
	printf("%f", p->man.weight);
	return 0;
}

在这里插入图片描述

联系两种调用:这里的两种代码都可以完成任务,但是由于内存中,拷贝地址(一个16进制的数)和拷贝整个结构体相比,传址调用明显更省内存空间,并且调用过程中的时间也会减少,性价比更高。

总结

 在下的讲解到此就结束了,功非一日之成,勤非一时之恒。编程的世界细节满满,只怕有心人。希望你能有所收获。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值