初识结构体
**
1.结构体类型的声明
2.结构体初始化
3.结构体成员访问
4.结构体传参
**
1. 结构体的声明
1.1 结构体的定义
结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据
1.2 结构体的作用
结构体在函数中的作用不是简便,其最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了
1.3 结构的声明
结构体声明是描述结构体组合的主要方法,语法格式为:
struct 结构体名称 { 结构体成员1; 结构体成员2; 结构体成员3; };//分号不能丢
注意:
结构体成员既可以是任何一种基本的数据类型,也可以是另一种结构体,如果是后者就相当于结构体的嵌套。(俗称套娃)
struct tag //struct为结构体关键字,tag为结构体的标志 { member-list; //为结构体成员列表其必须列出其所有成员 }variable-list; //variable-list为此结构体声明的变量 例如描述一个学生: struct Stu { char name[20];//姓名 int age;//年龄 char sex[5];//性别 int hight;//身高 }; //没有声明变量
具体如以下图示:
1.4 结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
1.5 结构体变量的定义和初始化
我们可以用结构体来描述一个学生的基本情况:
struct Stu { //成员变量 char name[20]; short age; char sex[5]; int hight; }b1,b2;//b1,b2是全局变量,放在静态区 //一般不推荐使用全局变量,因为全局变量可以随意更改,不便于控制管理 int main() { struct Stu s;//创建结构体变量 return 0; }
结构体的初始化:
struct Stu { //成员变量 char name[20]; short age; char sex[5]; int hight; }; struct Stu s = {"zhangsan", 20,"男", 180};//完成对应的初始化操作
结构体嵌套初始化:
如果访问嵌套的结构体成员的话,就需要使用多层点号运算符来进行操作。因为C语言的结构体只能对最底层的成员进行访问,如果存在多级结构体嵌套的话,就需要一级一级地深入,直到找到最底层的成员才行
struct Point { int x; int y; }; struct S { char c; struct Point p; double d; char str[20]; }; int main() { struct S ss = { 'x', {100, 200}, 3.14, "hello bit"}; return 0; }
2. 结构体成员的访问
结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数
例如以下例子:
struct Stu { //成员变量 char name[20]; short age; char sex[5]; int hight; }; int main() { struct Stu s = {"zhangsan", 20,"男", 180}; printf("名字:%s\n", s.name); printf("年龄:%d\n", s.age); printf("性别:%s\n", s.sex); printf("身高:%d\n", s.hight); return 0; }
结果如下:
还有一种便是结构体指针访问结构体:
构体指针访问结构体成员有以下两种方法:
(1)(*结构体指针).成员名
(2)结构体指针->成员名
这里声明了一个指向指针变量s;
struct Stu { //成员变量 char name[20]; short age; char sex[5]; int hight; }; int main() { struct Stu s = { "张三",20, "男", 180 }; struct Stu *ss = &s;//拿到地址的方式 printf("名字:%s\n", (*ss ).name); printf("年龄:%d\n", (*ss ).age); printf("性别:%s\n", (*ss ).sex); printf("身高:%d\n", (*ss ).hight); printf("名字:%s\n", ss->name); printf("年龄:%d\n", ss->age); printf("性别:%s\n", ss->sex); printf("身高:%d\n", ss->hight); return 0; }
结果如下:
注意:
1.数组名指向的是第一个元素的地址,所以可以直接将数组名赋值给指针变量。但是结构体变量的变量名并不是指向该结构体的地址,所以要使用取地址运算符(&)才能获取其地址。
2.以上两种方法在实现的时候完全等价。但是,点号(.)只能用于结构体,而箭头(->)只能用于结构体指针,当二者皆可用的时候,优先采用第二种方法。
3. 结构体传参
这里也有两种方法:
1.结构体传参
2.结构体地址传参
struct Stu { //成员变量 char name[20]; short age; char sex[5]; int hight; }; void print1(struct S ss) { printf("名字:%s\n", ss.name); printf("年龄:%d\n", ss.age); printf("性别:%s\n", ss.sex); printf("身高:%d\n", ss.hight); } void print2(struct S* ss) { printf("名字:%s\n", ss->name); printf("年龄:%d\n", ss->age); printf("性别:%s\n", ss->sex); printf("身高:%d\n", ss->hight); } int main() { struct Stu s = { "张三",20, "男", 180 }; //print1(s);//传值调用 print2(&s);//传址调用 return 0; }
结果如下:
既然两种传参的到的结果都是一样的,请问哪种传参的方式更好一些呢?
答案是:首选print2函数。
原因:
函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降
结论:
结构体传参的时候,要传结构体的地址。
总结:
本文介绍的是C语言结构体的一些基础知识,结构体的内容还远远不止这些,在以后学习到了更深入的内容之后,会再写一篇博客深入介绍。最近一段时间由于 种种原因耽搁了,导致好长一段时间尚未更新了,希望大家多多包涵,最后希望能对看到的大家有所帮助!