赞
踩
伴随着第四次工业革命信息化汹涌澎湃的到来,我们每一个个体都要跟上时代发展的步伐,程序道路需要不断学习付出,大家加油!一起进步!
今天给大家分享的是C语言中的结构体,结构体非常重要,他的应用很广泛,运用很灵活,它可以解决数组存在类型限制的缺陷的,即将不同类型的数据聚合起来,在数据结构中结构体起到搭建指针,数据,作为桥梁建立起很多复杂的结构。所以,和指针一样,很有必要深入而且全面的去理解他。
本文章会详细介绍结构体,并在最后给出一些例题以供大家复习巩固。
在C语言中,结构体属于构造数据类型,它由若干成员组成,成员的类型既可以是基本数据类型,也可以是构造数据类型,而且可以互不相同。
结构体类型定义的一般格式如下:
- struct 结构体类型名
- {
- 类型1 成员名1;
- 类型2 成员名2;//这里的类型可以是int char float 等数据类型
- ...
- 类型n 成员名n;
- };//注意分号,结构体本身也是一条语句,分号不能省略
其中,struct是定义结构体类型的关键字;结构体类型名必须是合法的C标识符,与其前面的struct一起共同构成结构体类型名;花括号内的内容是结构体类型所包括的结构体成员,也称为结构体成员。
举个例子,直接上代码:
- struct student
- {
- //定义学生结构体
- int num;//学号
- char name[10];//姓名
- int English,math;//成绩
- };
注意事项:
1)结构体类型定义的末尾必须有分号;
2)成员类型可以是除本身所属结构体类型外的任何已有数据类型;
3)在同一作用域内,结构体类型名不能与其他变量名或结构体类型名重名;
4)同一个结构体各成员不能重名,但允许成员名与不在结构体中的变量名,函数名相同;
5)结构体类型的作用域与普通变量的作用域相同:在函数内定义,则仅在函数内部起作用;在函数外定义,则有全局作用;
我们知道,一个较复杂的实体往往由多个成员构成,每个成员可以是C语言的基本数据类型,也可以是构造类型,当结构成员的数据类型又是结构类型时,就形成了结构类型的嵌套。
直接上代码:
- struct date
- {
- int year,month,day;
- };
-
- struct student
- {
- //定义学生结构体
- int num;//学号
- char name[10];//姓名
- struct date birthday;//出生日期
- int English,math;//成绩
- };
注意:当要嵌套定义结构体的时候,必须先定义成员的结构,比如上面的代码,在student里定义birthday的时候,要先定义这个birthday,才可以进行嵌套。
引入:
- #include<stdio.h>
- struct student
- {
- int num;
- char name[10];
- int English, math;
-
- };
- int main()
- {
- struct student s1;
- struct student s2;
- system("pause");
- return 0;
- }
C语言规定,变量必须先定义后使用,主函数语句struct student s1,s2;就是结构体变量定义语句,定义了两个结构体变量s1和s2,其数据类型是struct student。
在C语言中定义结构体变量有三种方式
1) .单独定义
单独定义是指先定义一个结构体类型,再定义这种结构体类型的变量。
引入部分的代码便是单独定义。
注意:关键字struct和结构名student必须联合使用,它们合起来表示一个数据类型名;
2) .混合定义
混合定义是指在定义结构体时定义结构体变量。
例如:
- struct student
- {
- //定义学生结构体
- int num;//学号
- char name[10];//姓名
- int English,math;//成绩
- }S1,S2;//混合定义
3). 无类型名定义
无类型名定义是指在定义结构体变量时省略结构体名称。
例如:
- struct
- {
- //定义学生结构体
- int num;//学号
- char name[10];//姓名
- int English,math;//成绩
- }S1,S2;//定义结构体变量S1,S2
注意:无类型名方式只定义结构体变量,不定义结构体类型,若需要定义其他结构体变量,必须把定义过程重新写一遍。结构体变量的初始化是指在定义结构体变量时对其赋初值。
如:
struct student S1={101,”Li”,100,90};
按结构体类型定义中成员的先后顺序排列。所占内存空间等于成员所占内存(这里涉及到内存对齐的内容)空间之和。可以用长度运算符sizeof计算其所占空间,计算结果以字节为单位。
sizeof运算符的使用格式:
-
- //sizeof(类型名)或者sizeof(变量名)
- sizeof(struct student)
- sizeof(S1)
1)结构体类型与结构体变量是两个不同的概念。前者只声明结构体的组织形式,本身不占存储空间,后者是结构体类型的具体实例,在定义结构体变量时,编译系统为其分配存储空间。就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。不能去取一个结构体名的地址,也不能将它赋值给其他变量;
2)结构体变量各成员存储在一片连续的内存单元中。
使用结构体变量主要是引用其结构成员,在C语言中,使用成员运算符(.)来引用结构成员。
格式:结构体变量名.成员名
功能:引用结构体变量中指定名称的成员变量
例如:
- struct student stu;
- stu.num=1001;
- strcpy(stu.name,”Li”);
- scanf(“%d”,&stu.birthday.year);
- printf(“name: %s,stu.name”);
在C语言中可以对两个相同类型的结构体变量进行整体赋值。赋值时,将赋值符右边结构体变量的每个成员值都赋值给左边结构体变量中相应的成员。还可用结构体作为函数参数,或者用结构体类型作为函数返回值类型,以便在函数间传递复杂数据,属于值传递。
所谓结构体数组,是指数组中的每个元素都是一个结构体。
在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。
在C语言中,定义结构体数组和定义结构体变量的方式类似,请看下面的例子:
- truct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }class[5];
- //表示一个班级有五个学生,这五个学生具有相同的数据类型。
结构体在定义的时候也可以进行初始化,请看下面例子:
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }class[5] = {
- {"Li ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"He fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- };
当对数组中全部元素赋值时,也可不给出数组长度,例如:
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }class[] = {
- {"Li ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"He fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- };
结构体数组的使用也很简单,例如,获取 Wang ming 的成绩:
class[4].score;
修改 Li ping 的学习小组:
class[0].group = 'B';
计算全班学生的总成绩、平均成绩和以及 140 分以下的人数;
- #include <stdio.h>
- struct{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }class[] = {
- {"Li ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"He fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- };
- int main(){
- int i, num_140 = 0;
- float sum = 0;
- for(i=0; i<5; i++){
- sum += class[i].score;
- if(class[i].score < 140) num_140++;
- }
- printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
- return 0;
- }
运行结果:
sum=707.50
average=141.50
num_140=2
当指针指向结构体变量时,称为结构体指针。当然,指针变量也可以用来指向结构体数组中的元素。
下面是一个定义结构体指针的实例:
- //结构体
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 };
- //结构体指针
- struct stu *pstu = &stu1;
也可以在定义结构体的同时定义结构体指针:
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&,所以给 pstu 赋值只能写作:
struct stu *pstu = &stu1;
而不能写作:
struct stu *pstu = stu1;
通过结构体指针可以获取结构体成员,一般形式为:
(*pointer).memberName 或者 pointer->memberName
第一种写法中,.的优先级高于*,(*pointer)两边的括号不能少。如果去掉括号写作*pointer.memberName,那么就等效于*(pointer.memberName),这样意义就完全不对了。
第二种写法中,->是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员;这也是->在C语言中的唯一用途。
上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。
- #include <stdio.h>
- int main(){
- struct{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
- //读取结构体成员的值
- printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n",
- (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
- printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n",
- pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
- return 0;
- }
运行结果:
- Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
- Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
- #include <stdio.h>
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }stus[] = {
- {"Zhou ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"Liu fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- }, *ps;
- int main(){
- //求数组长度
- int len = sizeof(stus) / sizeof(struct stu);
- printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
- for(ps=stus; ps<stus+len; ps++){
- printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
- }
- return 0;
- }
运行结果:
- Name Num Age Group Score
- Zhou ping 5 18 C 145.0
- Zhang ping 4 19 A 130.5
- Liu fang 1 18 A 148.5
- Cheng ling 2 17 F 139.0
- Wang ming 3 17 B 144.5
计算全班学生的总成绩、平均成绩和以及 140 分以下的人数。
- #include <stdio.h>
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }stus[] = {
- {"Li ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"He fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- };
- void average(struct stu *ps, int len);
- int main(){
- int len = sizeof(stus) / sizeof(struct stu);
- average(stus, len);
- return 0;
- }
- void average(struct stu *ps, int len){
- int i, num_140 = 0;
- float average, sum = 0;
- for(i=0; i<len; i++){
- sum += (ps + i) -> score;
- if((ps + i)->score < 140) num_140++;
- }
- printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
- }
本文章介绍到这里,下一篇文章带给大家的是共用体和联合体的内容,期待大家的关注!
2023.01.24
From:努力进大厂的新青年
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。