🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》
⛺️生活的理想,就是为了理想的生活!
🌈hello! 各位宝子们大家好啊,前面我们学完指针了就正式进入到结构体这一章节了。 ⛳️结构体使我们自定义类型的一种,应用可以说非常广泛了。今天就给大家大家详细解析一下,结构的内容详解以及各种注意事项! 📚本期文章收录在 《C语言初阶》,大家有兴趣可以看看呐! ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!
⛳️ 关于结构体我们可以这样理解,数组是一些相同元素的集合,那么结构体就是不同类型值的的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
那么结构体该如何定义呢?结构体其实就和 int 整形是一模一样的,结构体也是一个类型。想定义一个结构体变量首先需要先声明这个结构的类型成员是那些!
struct
📚 结构体的语法形式:
struct tag
{
member - list;
}variable - list;
结构体的关键字是
struct
后面跟的tag
是 结构体的标签名,可以自定义。我们也根据实际情况自定义!
member - list
大括号里面需要的就是我们成员列表了variable - list
这个是变量列表的意思可能各位,铁汁还是不明白。我们来看一下实际例子大家就明白了!例如描述一个学生:
姓名
年龄
性别
和 学号
📚 代码演示:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}; //分号不能丢
总结:
结构体类型的声明和定义都回了。那么一个结构体类型我们该怎么创建一个结构体的变量呢?答案是使用结构体的标签名用来定义结构体变量,或者在创建结构体的时候直接在后面跟上结构体变量
📚 代码演示:
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
//全局变量
int main()
{
struct Point p2;//直接使用标签名定义
//局部变量
return 0;
}
而初始化的话也非常简单和数组是差不多的每个成员赋值用大括号扩起来,单引号隔开就好了!
📚 代码演示:
struct Point
{
int x;
int y;
}p1 = { 2, 1 };//创建时直接赋值
int main()
{
struct Point p2 = {12,13};//直接使用标签名定义
//然后进行赋值
return 0;
}
这时候大家就会发现诶呀!结构体的变量的定义也太麻烦了吧!还要写结构体的关键字和标签名一点也不简便!那么有没有简便的方法呢!这时候就需要用到 typedef 重命名关键字来重新定义结构体名称了!
📚 代码演示:
#include <stdio.h>
typedef struct Point
{
int x;
int y;
}Pt;//重定义后的类型名
int main()
{
Pt p2 = { 12,13 };//typedef重定义类型名定义
//结构体变量然后进行赋值
return 0;
}
📑 代码结果:
typedef
的结构体初始化和标签名初始化一模一样但是,不能和标签名一样在结构体类型的最后一行直接创建结构体变量和初始化了。
📚 代码演示:
#include <stdio.h>
typedef struct Stu
{
char name[20];//姓名
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;
//全局变量
Stu p1 = { .id = "20202356",.age = 18, .name = "lisi",.sex = "nan" };
int main()
{
printf("姓名\t年龄\t性别\t学号\n");
//局部变量
Stu p2 = { .id = "202329",.age = 20, .name = "zhangsan",.sex = "nan" };
printf("%-10s\t %d\t %s\t %s\n", p1.name, p1.age, p1.sex, p1.id);
printf("%-10s\t %d\t %s\t %s\t", p2.name, p2.age, p2.sex, p2.id);
return 0;
}
📑 代码结果:
通过点操作符(.)访问其实非常简单:
.
)找到我们要访问的成员就好了。📚 代码演示:
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main()
{
struct Point s = { 20, 2 };//初始化
printf("%d\t%d",s.x,s.y);
return 0;
}
📑 代码结果:
诶我们点的操作符是不是不难,通过点操作符我们可以访问到结构体成员,那么是不是可以给结构体成员单独赋值呢?答案是可以的
📚 代码演示:
#include <stdio.h>
typedef struct Point
{
int x;
int y;
}Pt;
int main()
{
Pt s = { 0 };
s.y = 10;
s.x = 20;
printf("%d %d", s.x, s.y);
return 0;
}
📑 代码结果:
但是我们注意在给数组赋值的时候是否可以这样写?假设结构体成员 char name[20] 是个数组s.name = “李四”;这样赋值正确吗?答案是不正确;
name
是什么?是地址啊? 我们通过点操作符找到的是地址。🔥 注:左值是指空间的意思!
所以我们在给结构体数组赋值的时候,如果是字符数组,就需要用
strcpy
库函数赋值,如果是整形数组就只能用循环遍历然后利用下标找到空间一个个赋值。
strcpy
拷贝字符串库函数赋值循环遍历
然后利用下标
找到空间一个个赋值📚 代码演示:
#include <stdio.h>
#include <string.h>
typedef struct Stu
{
int arr[10];
int age;
char name[20];
}S;
int main()
{
S s = { 0 };
s.age = 26;
int i = 0;
for (i = 0; i < 10; i++)
{
s.arr[i] = i;
printf("%d ", s.arr[i]);
}
printf("\n");
strcpy(s.name, "张三");
printf("%d %s", s.age, s.name);
return 0;
}
📑 代码结果:
如何我们拿到的是一个结构体指针那么该如何访问呢?那么这时就可以使用 -> 箭头操作符来进行访问了。
现在的编译器已经十分智能了,一旦我们使用的是结构体指针,他就会给我们转换为 箭头访问的方式!
.
) ,就需要先对指针解引用找到指针所指向的空间.
) 找到成员 (*x).y = 20 。所以我们在使用结构体指针的时候一定要要使用箭头访问,这样程序才更加高效!
📚 代码演示:
#include <stdio.h>
typedef struct Point
{
int x;
int y;
}Pt;
void test(Pt* x)
{
x->x = 10;
x->y = 20
}
int main()
{
Pt ps = { 0 };
test(&ps);
printf("%d %d", ps.x, ps.y);
return 0;
}
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;
}
上面的 print1 和 print2 函数哪个好些?答案是:首选print2函数。因为:
🔥 由于函数在传递参数时,如果我们传的是实参,那么形参将是实参的一份临时拷贝。如果我们传过去的结构体很大,那么形参也要开辟相同大小的空间就会照成空间的浪费!
我们来看一下下面这个例子大家就明白了,这里我们在
main()
主函数里面创建了结构体变量想通过test()
函数进行赋值。
传值调用
,所以改变形参并不会改变实参。#include <stdio.h>
typedef struct Point
{
int x;
int y;
}Pt;
void test(Pt pf)
{
pf.x = 2;
pf.y = 3;
}
int main()
{
Pt p2 = {0};
test(p2);
printf("%d %d", p2.x, p2.y);
return 0;
}
📑 代码结果:
所以我们在结构体传参的时候一定要使用 传址调用 ,这样才能改变我们的结构体!
📚 代码演示:
#include <stdio.h>
typedef struct Point
{
int x;
int y;
}Pt;
void test(Pt* x)
{
x->x = 10;
x->y = 5;
}
void test1(const Pt* x)
{
printf("%d %d", ps.x, ps.y);
}
int main()
{
Pt ps = { 0 };
test(&ps);
test1(&ps);
printf("%d %d", ps.x, ps.y);
return 0;
}
📑 代码结果:
✅ 归纳:
好了以上就是关于结构体的万字解析,和使用的全部注意事项就全部讲解完毕啦!
结构体的声明与定义
结构体变量的创建与初始值
点操作符(.)使用的注意事项
箭头操作符的讲解
结构体传参的注意事项
☁️ 把本章的内容全部掌握,铁汁们就可以彻底拿捏结构体了!
看到这里了还不给博主扣个:
⛳️ 点赞
☀️收藏
⭐️ 关注
!
💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。