【C语言基础12——结构体】


前言

本文开始学习结构体的知识点,主要内容包括:

  • 结构体类型的声明
  • 结构体初始化
  • 结构体成员访问
  • 结构体传参

1、结构体的声明

1.1 结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量

1.2 结构的声明

struct tag
{
    
    
	member-list;
}variable-list;

下面几种方式都一样,定义了学生的结构体类型,内容包括:名字、年龄、性别、学号

//举例1
struct Stu
{
    
    
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}//分号不能丢

//举例2
struct Stu
{
    
    
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}s1,s2,s3;//定义了3个结构体类型的变量

//举例3
typedef struct stu stu;

//举例4
typedef struct stu
{
    
    
	char name[20];
	int age;
	char sex[8];
	float score;
}stu;

int main()
{
    
    
	struct stu stu4;//局部变量
	struct stu stu5;
	stu stu6;//全局变量
	return 0;
}

1.3 结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体

1.4 结构体变量的定义和初始化

struct Point
{
    
    
	int x;
	int y;
}p1; //声明类型的同时定义变量p1

struct Point p2; //定义结构体变量p2

//初始化:定义变量的同时赋初值。
struct Point p3 = {
    
     x, y };

struct Stu //类型声明
{
    
    
	char name[15];//名字
	int age; //年龄
};
struct Stu s = {
    
     "zhangsan", 20 };//初始化

struct Node
{
    
    
	int data;
	struct Point p;
	struct Node* next;
}n1 = {
    
     10, {
    
    4,5}, NULL }; //结构体嵌套初始化

struct Node n2 = {
    
     20, {
    
    5, 6}, NULL };//结构体嵌套初始化

2、结构体成员的访问

2.1 点操作符访问

  • 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数:变量名.成员
struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员

2.2 ->操作符访问

  • 指向一个结构体的指针,结构体指针访问指向变量的成员,变量名 ->成员
struct Stu
{
    
    
	char name[20];
	int age;
};
void print(struct Stu* ps)
{
    
    
	printf("name = %s age = %d\n", (*ps).name, (*ps).age);
//使用结构体指针访问指向对象的成员
	printf("name = %s age = %d\n", ps->name, ps->age);
}

3、结构体传参

3.1 参数是结构体类型的变量

struct point
{
    
    
	int x;
	int y;
}p1 = {
    
    10,20};

struct s//结构体
{
    
    
	char c;
	struct point sp;
	double d;
	char arr[20];//字符串
};

void print1(struct s ss)//传参结构体
{
    
    
	printf("%c\n", ss.c);
	printf("%d\n", ss.sp.x);
	printf("%d\n", ss.sp.y);
	printf("%lf\n", ss.d);
	printf("%s\n", ss.arr);
}
int main()
{
    
    
	struct point p1 = {
    
     100, 200 };//定义1个变量,并初始化
	struct s ss = {
    
     'w',{
    
    100,20},5.5,"hello" };//初始化
	ss.c = 'b';
	ss.sp.x = 1000;
	ss.sp.y = 2000;
	ss.d = 3.14;
	//ss.arr = "wolrd";错误的方法
	strcpy(ss.arr, "world");//字符串赋值函数
	print1(ss);//打印结构体变量
}

3.2 参数是结构体类型的变量的地址

struct point
{
    
    
	int x;
	int y;
}p1 = {
    
    10,20};

struct s
{
    
    
	char c;
	struct point sp;
	double d;
	char arr[20];//字符串
};
void print2(struct s* ss)//传参地址
{
    
    
	printf("%c\n", ss->c);
	printf("%d\n", ss->sp.x);
	printf("%d\n", ss->sp.y);
	printf("%lf\n", ss->d);
	printf("%s\n", ss->arr);
}
int main()
{
    
    
	struct s ss = {
    
     'w',{
    
    100,20},5.5,"hello" };//初始化
	ss.c = 'b';
	ss.sp.x = 1000;
	ss.sp.y = 2000;
	ss.d = 3.14;
	//ss.arr = "wolrd";错误的方法
	strcpy(ss.arr, "world");
	print2(&ss);//打印结构体变量
}

3.3 结构体传参对比

上面两种函数实现的效果一样,见下图:
在这里插入图片描述

  • 函数print1接受的是结构体类型变量,是形参,另外开辟了空间,将实参拷贝了一份,占用内存空间大
    在这里插入图片描述
    - 函数print2接受的是结构体类型的地址,定义结构体类型的指针接收地址,只开辟了空间存放地址,占用内存空间小
    在这里插入图片描述
    **要注意:**函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。因此,结构体传参的时候,要传结构体的地址,即函数 print2 比函数 print1 效果好。

总结

结构体内容较少,要牢记定义形式,和传地址的用法。

下一篇将学习一些VS的调试技巧,编程出现bug,通过调试能发现问题,并改进程序,这一步非常重要。在学语言的同时,适当的学习工具的使用,能够达到事半功倍的效果。

猜你喜欢

转载自blog.csdn.net/taibudong1991/article/details/123968636