构造类型详解及热门题型结构体大小的计算(上)

简介: 构造类型详解及热门题型结构体大小的计算

结构体类型的概念

结构体是一种由若干个成员组成的构造类型,成员可以是几种基本类型数据,也可以是另外的构造类型。既然结构体是一个构造类型,就需要先对其进行构造,我们称这个操作为声明一个结构体。

例如,一个学生包含学号,性别,分数等特点,一个老师有性别,年龄,教学科目等类别。

这两种类型就不能用普通的变量类型来表示,我们就可以自己定义一个结构体。

声明结构体的关键字为struct,一般形式如下

struct 结构体名

{

       成员列表;

};

大括号后边的分号切记不能忘记。

结构体名可以为teacher student,等等等等都可以,大括号里面的就是你所创建出的结构体具有哪些特征等。当然也可以放另一个结构体变量,我们后边会谈到。

声明上边的两种类型的结构体

如下

struct student
{
  char name[10];//名字
  int grade;//分数
  int num;//学号
  char sex;//性别
};
struct teacher
{
  char name[10];
  int age;
  char sex;
  char project[10];//任课科目
};

结构体变量的定义

前边已经介绍了如何声明一个结构体,如何使用构造的结构体才是我们的真正目的。

定义结构体变量的方法有两种

我们已经声明了student结构体,可以在程序中直接用定义一个小明,也可以再定义一个小红,要注意,声明一个结构体是创建一种新的类型名,要用新的类型名再定义变量,student的类型名为struct student。

定义如下:

struct student xiaoming;

struct student xiaohong;

结构体也可以使用typedef重命名,可以使定义变量时更加便捷。

例如

typedef struct student
{
  char name[10];//名字
  int grade;//分数
  int num;//学号
  char sex;//性别
}Student;

定义该结构体类型名为Student,再次定义一个新的变量就可以这样写

Student xiaogang;

是不是有很方便。

这种定义的方式可以写在函数内,也可以写在函数外部,写在函数外部就是全局变量。

这个时候就要说一说另一种定义变量的方式

struct student
{
  char name[10];//名字
  int grade;//分数
  int num;//学号
  char sex;//性别
}xiaoming,xiaogang;

可以看到,这种形式将定义的变量直接放在声明结构体的末尾处,需要注意的是要放在分号的前边且可以定义多个变量。

但是,这种定义方式不好的缺点是,如果这个结构体在头文件中存放,那么定义出的结构体变量都是全局变量,全局变量使用起来很危险,所以这种定义方式我们不推荐。

结构体变量的初始化

上边说过,这种直接在声明后边定义的方式并不推荐,但还是要知道,可以在声明后定义时就初始化,有点绕?

声明就是一栋房子的建造图纸,可以用这个图纸来造很多相似的房子,定义就是用图纸盖一栋房子,我们有了房子就可以在房子里放东西,布置布置,初始化就是粉刷房子,为房子内的房间装饰。

是不是懂啦

上边说边声明边定义边初始化,就是下边这样

struct student
{
  char name[10];//名字
  int grade;//分数
  int num;//学号
  char sex[20];//性别
}xiaoming = { "xiaoming",98,666,"男" };

定义的变量后边使用等号,然后将初始化的值放在大括号里,每一个数据要和结构体成员列表的顺序一样。

还有一种发方法就是定义初始化和声明分离

typedef struct student
{
  char name[10];//名字
  int grade;//分数
  int num;//学号
  char sex;//性别
}Student;
int main()
{
  Student xiaohong = { "xiaohong",99,6666,"女" };
  return 0;
}

是不是很简单就可以实现?

结构体变量的引用

如果我们想要修改结构体成员变量的值呢?

printf("%s %d %d %s",xiaohong);   ??????XXXXXX错误的哦

如果想要对结构体成员进行操作,我们就要拿出这个结构体中的变量,这个过程就叫做引用

一般形式如下

结构体变量名.成员名

例如,小红的分数更改为100

更改完成之后直接打印验证

如果是结构体里面套着结构体呢?

给Student加上birthday结构体储存其生日,如果记错了,如何修改其生日呢?

让Student结构体里有一个Birthday结构体变量,然后修改

直接公布答案

typedef struct birthday
{
  int month;
  int day;
}Birthday;
typedef struct student
{
  char name[15];//名字
  int grade;//分数
  int num;//学号
  char sex[10];//性别
  Birthday data;
}Student;
int main()
{
  Student xiaohong = { "xiaohong",99,6666,"女" ,{4,4} };
  xiaohong.data.day = 3;
  xiaohong.data.month = 3;
  xiaohong.grade = 100;
  printf("%d ", xiaohong.grade);
  printf("%d %d\n", xiaohong.data.day,xiaohong.data.month);
  return 0;
}

看见没看见没,如果是结构体里面有结构体变量,那么初始化内部的结构体变量的成员也要用大括号括起来。

结构体成员变量可以像普通变量一样进行各种运算。

结构体数组

我们已经知道了数组可以装好多种类型,当然结构体数组也不奇怪。结构体变量可以放好多组数据,结构体数组可以存放好几组结构体变量,就像一个小孩(结构体变量)有很多特征(结构体内部成员变量),一个班级(结构体数组)可以装好多小孩一样。

我们可以定义一个结构体数组

代码如下

typedef struct student
{
  char name[15];//名字
  int grade;//分数
  int num;//学号
  char sex[10];//性别
  Birthday data;
}Student;
int main()
{
  Student stu[3] = { {"dingding",66,22222,"女",{6,6}},{"shuaishuai",77,22223,"男",{6,6}} ,{"dengquan",88,22224,"男",{6,6}} };
  for (int i = 0; i < 3; i++)
  {
    printf("%s %d %d %s %d %d", stu[i].name, stu[i].grade, stu[i].num, stu[i].sex, stu[i].data.month, stu[i].data.day);
    printf("\n");
  }
  return 0;
}

运行后代码如下

       因为shuaishuai的名字长度为10,创建10个字符的数组,就无法存储结束标志\0,所以这里将名字的数组扩大为15,如果大家用汉字会报错的话,采取以下步骤

右击

高级->字符集->无

就可以正常使用汉字了,一个汉字两个字节。

       回归上边的操作,要记住的是,初始化结构体数组,每个结构体变量初始化内容要用大括号扩住,访问还是用.引用操作符,如果结构体套结构体的话,就多引用一次即可。

结构体指针

       指针可以指向整形,浮点型,甚至还可以指向他自己,变成二级指针,一个指向变量的指针表示该变量的起始地址,那么结构体指针就指向结构体变量的起始地址。

       既然指针指向结构体变量的地址,那么我们就可以通过结构体指针来访问结构体内的成员。

定义结构体指针的格式如下:

结构体类型 *指针名;

例如,定义一个Student结构类型的指针如下

Student *pstu;

重点来啦,使用结构体指针访问结构体成员有两种方法

第一种就是解引用在用.引用操作符进行引用

typedef struct birthday
{
  int month;
  int day;
}Birthday;
typedef struct student
{
  char name[15];//名字
  int grade;//分数
  int num;//学号
  char sex[10];//性别
  Birthday data;
}Student;
int main()
{
  Student xiaohong = { "xiaohong",99,6666,"女" ,{4,4} };
  Student* ptr = &xiaohong;
  (*ptr).grade = 100;
  printf("%d ", xiaohong.grade);
  return 0;
}

这里一定要注意,解引用结构体指针一定要用括号括住,这是因为.引用操作符的优先级比*解引用操作符优先级高,我们要的是先解引用结构体指针,再引用其成员变量。

还有一种方式

使用指向操作符引用结构体成员

代码如下(结构体声明部分省略)

int main()
{
  Student xiaohong = { "xiaohong",99,6666,"女" ,{4,4} };
  Student* ptr = &xiaohong;
  //(*ptr).grade = 100;
  ptr->grade = 101;
  printf("%d ", xiaohong.grade);
  return 0;
}

运行结果如图

结构体传参

结构体变量可以作为函数的参数,但是要记住哦,传参传过去的都是形参,形参的改变不影响实参,所以我们传结构体变量就只能访问其内部成员变量的值,想要在该函数里修改结构体变量,就要传结构体指针过去。

传参访问,要注意接收函数的参数类型要相同

typedef struct birthday
{
  int month;
  int day;
}Birthday;
typedef struct student
{
  char name[15];//名字
  int grade;//分数
  int num;//学号
  char sex[10];//性别
  Birthday data;
}Student;
void PrintStu(Student A)//这里给什么名字都可以,形参的名字
{
  printf("%s %d %d %s %d %d", A.name, A.grade, A.num, A.sex, A.data.month, A.data.day);
}
int main()
{
  Student xiaohong = { "xiaohong",99,6666,"女" ,{4,4} };
  Student* ptr = &xiaohong;
  //(*ptr).grade = 100;
  PrintStu(xiaohong);
  return 0;
}

我们可以访问,打印结构体成员的信息。

我们尝试着修改一个变量

void PrintStu(Student A)//这里给什么名字都可以,形参的名字
{
  printf("%s %d %d %s %d %d", A.name, A.grade, A.num, A.sex, A.data.month, A.data.day);
  A.grade = 100;
}

将分数改为100,在主函数再打印一次。

可以发现两次打印的数据没有变化,形参改变不影响实参。

传入结构体指针

再次运行

目录
相关文章
|
7月前
|
网络协议 网络安全 网络虚拟化
网工大题题型总结(3)------2018到2022大题类型总结
网工大题题型总结(3)------2018到2022大题类型总结
35 2
|
6月前
|
C语言
C语言学习记录——计算一个数的每位之和(递归实现)
C语言学习记录——计算一个数的每位之和(递归实现)
56 0
|
7月前
|
算法 C语言
化繁就简(结构体在算法中的运用)
化繁就简(结构体在算法中的运用)
33 0
|
编译器 Linux C++
构造类型详解及热门题型结构体大小的计算(下)
构造类型详解及热门题型结构体大小的计算(下)
57 0
|
C语言
C语言练习之计算一个数的每位之和(递归实现)
C语言练习之计算一个数的每位之和(递归实现)
252 0
【初阶C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)(二)
【初阶C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)(二)
【初阶C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)(一)
【初阶C语言】有关的经典题型内含数组及递归函数题型讲解(入门适用)(一)
|
Android开发 C++ 开发者
重温C与C++之结构体大小计算
C++进阶之结构体大小计算
123 0
|
人工智能 C语言
八数码问题(C+数组(学艺不精,没敢用指针和结构体QAQ))
八数码问题(C+数组(学艺不精,没敢用指针和结构体QAQ))
119 0
|
机器学习/深度学习 存储 算法
数组-题型讲解
数组-题型讲解
104 0
数组-题型讲解