• 【初阶】C语言初识结构体


    前言

    结构体是c语言中的一个特别重要的知识点,本篇是对结构体的一个大体介绍,重点讲解结构体的主体框架,希望看完本篇能够让各位对结构体有一个基本的认识!

    1. 浅谈结构体

    前面我们已经学过了使用charintdouble……描述简单对象,但是当我们面对像书、人这样的复杂类型的对象时我们又该用什么描述呢?答案是:结构体

    结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

    结构是一些值的集合,这些值称为成员变量。不同于数组,结构的每个成员可以是不同类型的变量。结构的成员可以是标量、数组、指针,甚至是其他结构体。

    2. 结构体类型的声明

    📝例如:用结构定义一个学生类型Stu

    //学生
    //名字+年龄+性别+身高
    struct Stu
    {
    	char name[20];//名字
    	int age;//年龄
    	char sex[5];//性别
    	int hight;//身高
    }s1,s2,s3;//全局变量
    struct Stu s4;//全局变量
    int main()
    {
    	struct Stu s5;//局部变量
    	//通常情况下定义局部变量
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3. 结构体初始化和成员访问

    (1) 普通结构体类型的初始化和成员访问

    📝实例展示:

    //坐标类型
    struct Point
    {
    	int x;
    	int y;
    };
    //学生类型
    struct Stu
    {
    	char name[20];//名字
    	int age;//年龄
    	char sex[5];//性别
    	int hight;//身高
    };
    int main()
    {
    	//结构体初始化
    	struct Point p = { 10,20 };
    	struct Stu s = { "张三",20,"男",180 };
    	//结构体成员访问 点操作符
    	printf("x = % d y = % d\n", p.x, p.y);
    	printf("%s %d %s %d\n", s.name, s.age, s.sex, s.hight);
    	
    	//结构体成员访问 ->操作符
    	struct Point* ps = &p;
    	struct Stu* pt = &s;
    	printf("x = % d y = % d\n", ps->x, ps->y);
    	printf("%s %d %s %d\n", pt->name, pt->age, pt->sex, pt->hight);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    注意:访问结构体成员有两种方式。结构体变量.结构体成员名;结构体指针->结构体成员名

    (2) 复杂结构体类型的初始化和成员访问

    📝实例展示:

    struct Point
    {
    	int x;
    	int y;
    };
    
    struct S
    {
    	char c;
    	struct Point p;
    	double d;
    	char str[];
    };
    int main()
    {
    	//结构体初始化
    	//struct S ss = {.d=3.14, .c = 'x', .p.x =100};//乱序初始化某些成员//
    	struct S ss = { 'x',{100,200},3.14,"哈哈"};
    	//结构体成员访问 点操作符
    	printf("%c %d %d %lf %s\n",ss.c,ss.p.x,ss.p.y,ss.d,ss.str);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注意:结构体的初始化通常在创建结构体变量时进行,并且支持乱序初始化某些成员。

    4. 结构体成员变量修改

    📝实例展示:

    struct S
    {
    	char name[20];
    	int age;
    };
    
    int main()
    {
    	struct S s = { .age = 20, .name = "zhansgan" };
    	printf("%s %d\n", s.name, s.age);
    	s.age = 30;//这个可以
    
    	//s.name = "zhangsanfeng";//err
    	strcpy(s.name, "zhsangsanfeng");//对字符串修改只能strcpy
    	printf("%s %d\n", s.name, s.age);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注意:对字符串修改只能strcpy,切忌使用赋值操作符。

    5. 结构体传参

    (1) 传值调用(函数参数为结构体)

    📝实例展示:

    struct S
    {
    	int data[1000];
    	char buf[100];
    };
    void print1(struct S ss)//参数是结构体类型
    {
    	int i = 0;
    	for (i = 0; i < 10; i++)//打印前十个元素
    	{
    		printf("%d ", ss.data[i]);
    	}
    	printf("%s\n", ss.buf);
    }
    
    int main()
    {
    	struct S s = { {1,2,3} , "hehe"};
    	print1(s);//传值调用
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    (2) 传址调用(函数参数为结构体指针

    📝实例展示:

    struct S
    {
    	int data[1000];
    	char buf[100];
    };
    
    void print2(struct S* ps)//参数是结构体指针类型
    {
    	int i = 0;
    	for (i = 0; i < 10; i++)
    	{
    		printf("%d ", ps->data[i]);
    	}
    	printf("%s\n", ps->buf);
    }
    
    int main()
    {
    	struct S s = { {1,2,3} , "hehe"};
    	print2(&s);//传址调用
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    结论:
    函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。如果传递结构体地址,地址占用内存很小,时间空间都会节省,程序效率会更高。因此结构体传参的时候,要传结构体的地址。

    总结

    本章篇幅不长,但是对于入门结构体也是特别重要。希望看完本篇能够给各位小伙伴们带来帮助,老铁们保持coding,我们下期再见!

  • 相关阅读:
    tomcat启动报错
    javascript二维数组(18)多个数组按照对应为准相加求和生成新的数组2
    Java获取AD域内所有用户
    解决:华为ensp软件中AR和AC,AP设备无法启动报错“40”的问题
    OpenCV实现图像的礼帽和黑帽
    将 ordinals 与 比特币智能合约集成 : 第 1 部分
    贪心算法实例(一):多任务分配问题
    【MySQL系列】使用C语言连接MySQL
    8.SpringMVC处理ajax请求
    爱上源码,重学Spring MVC深入
  • 原文地址:https://blog.csdn.net/LEE180501/article/details/126437884