宝玛科技网
您的当前位置:首页介绍结构体(修改)

介绍结构体(修改)

来源:宝玛科技网

一、结构体的定义:

官方来说结构体就是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。说到集合,数组也是集合,但是不同的是数组只能是相同类型元素的集合。结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。像 int、float、char 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型。而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

二、结构体的基础结构:

遵守的准则:

(1)先定义结构体类型,再定义结构体变量

(2)定义结构体类型的同时定义结构体变量

(3)直接定义结构体变量

注意:

▶结构体中各成员的定义和之前的变量定义一样,但在定义时也不分配空间

▶结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错

三、结构体的使用

(1)结构体的初始化

(2)结构体的成员访问

知识点1:

🔑为了访问结构的成员,我们使用成员访问运算符(.)。

🔑引用形式:<结构体类型变量名> . <成员名>

注意:结构体变量不能整体引用,只能引用变量成员

注意:需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。

(3)结构体数组

知识点1:

结构体数组:是指数组中的每一个元素都式结构体。

结构体数组常被用来表示一个拥有相同数据结构的群体。

例子:
​
struct student
​
{
char name[20];  //姓名
​
int num;  //学号
​
int age;  //年龄
​
char group;  //所在小组 
​
float score;  //成绩
}
class[5];//表示一个班有5个人
​
struct stu
​
{
​
char name[20];  //姓名
​
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}
};
​
Ps:当对数组中全部元素赋值时,也可以不给出数组长度
​
struct stu
​
{
​
char name[20];  //姓名
​
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}
};

(4)结构体指针--------------指向结构体变量的指针(重点!!!!)

知识点1:

结构体中可以定义指向结构的指针,方式与定义指向奇特类型变量的指针类似。

定义类型:struct 结构体名 * 结构体指针名

例子:

struct books*struct_pointer

其中 books 为结构体名 struct_pointer为结构体指针名

知识点2:

struct_pointer = &Book1;

为了使用指向该结构的指针访问结构的成员,必须使用->运算符

定义结构体指针举例:
​
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;

注意:

知识点3:注意结构体中的优先级问题;

通过结构体指针可以获取结构体成员,一般形式为:

(*pointer).memberMane                  //pointer为结构体指针名

  pointer->memberName             // 或者 

 第一种写法中, .  的优先级高于  * ,(*pointer)两边的括号不能少
 如果去掉括号写成*pointer.memberName,

 那么就等效于*(pointer.memberName),这样意义就不对了。

第二种写法中,-> 是一个新的运算符,习惯称它为“箭头”

有了它,可以通过结构体指针直接取得结构体成员,

这也是 -> 在C语言中的唯一用途。

知识点4:

结构体指针的使用:前面两种写法是等效的,我们通常采用第二种写法,这样更加直观。

(5)结构体指针--------------指向结构体数组的指针(重点!!!!)

(6) 结构体指针--------------结构体成员是指针类型变量(重点!!!!)

(7)typedef关键字与结构体、结构体指针 (超重点!!!)

1.使用typedef定义结构体

知识点1:

typedef用来定义新的数据类型,通常typedef与结构体的定义配合使用。使用typedef的目的使结构体的表达更加简练(所以说typedef语句并不是必须使用的。)

用大白话来说:

▶ struct 是用来定义新的数据类型——结构体

▶ typedef是给数据类型取别名。

 定义一个名字为TreeNode的结构体类型(现在并没有定义结构体变量,并不占用内存空间):
​
struct TreeNode   // 结构体类型
​
{
    int Element;
​
    struct TreeNode* LeftChild;   //结构体成员
​
    struct TreeNode* RightChild;
​
 };
​
为结构体起一个别名Node,这时Node就等价于struct TreeNode
​
typedef struct TreeNode Node;
​
将结构体的定义和typedef语句可以连在一起写:
​
typedef struct TreeNode   //结构体类型
​
{
    int Element;              //结构体成员
​
    struct TreeNode* LeftChild;
​
    struct TreeNode* RightChild;   
​
 }Node;     // Node 是 struct TreeNode 的别名
​
注意:Node 是 struct TreeNode 的别名(重点!!!!!!!!!)
​
注意 :不要与“定义结构体类型的同时定义结构体类型变量”混淆:
​
使用typedef关键字定义结构体类型 定义结构体类型的同时定义结构体类型变量 
​
typedef struct student
​
{
    int age;
​
    int height;
​
 }std;
​
//std相当于struct student
​
struct student
​
{
    int age;
​
    int height;
 }std1,std2;//定义了student数据类型的结构体和std1、std2结构体变量

2.使用typedef定义结构体指针

  
  知识点1:
​
使用typedef关键字用一个单词Node代替struct TreeNode,并定义指向该结构体类型的指针PtrToTreeNode:
​
struct TreeNode
​
{
    int Element;
​
    struct TreeNode* LeftChild;
​
    struct TreeNode* RightChild;
};
​
typedef struct TreeNode Node;   //用Node代替struct TreeNode
​
Node *PtrToTreeNode;            //定义指针
​
将结构体的定义和typedef连在一起写,再次缩短代码:
​
typedef struct TreeNode
​
{
    int Element;
​
    struct TreeNode* LeftChild;
​
    struct TreeNode* RightChild;
}
    Node;                          //定义结构体并用Node代替struct TreeNode
    Node *PtrToTreeNode;            //定义指针
​
3.引用鹏哥课程中的测试样例:
​
#include<stdio.h>
​
struct peo//结构体的声明(创建了一个struct的结构体类型,类似于一个图纸)
​
{
char name[20];//这四个整型加字符型都为结构体中的成员变量
​
char tele[12];
​
char sex[5];
​
int high;
​
}
//p1,p2//p1和p2是两个全局的结构体变量
​
struct st//声明名字为st的结构体
​
{
struct peo p;
​
int num;
​
float f;


}
​
int main()
​
{
struct peo p1 = {“张三”,”15596668862“,"男",181};//结构体变量的创建,创建了结构体的对象
​
struct st s ={{"lisi","15596668888","女",166},100,3.14f};//初始化st结构体的名字
​
printf("%s %s %s %d\n",p1.name,p1.tele,p1.sex,p1.high);//结构体变量。成员变量
​
printf("%s %s %s %d %d %f\n",s.p.name,s.p.tele,s.p.sex,s.p.high,s.num,s.f);
​
return 0;
}
​
//另外一种打法:printf("%s %s %s %d\n",sp->name,sp->tele,sp->sex,sp->high);
​
//结构体指针->成员变量

五、结构体题目讲解:(运行例子)

详情见牛客网上的结构体问题,此处只介绍最简单的一个:

CC13 KiKi定义电子日历类:

描述

KiKi学习了面向对象技术,学会了通过封装属性(变量)和行为(函数)定义类,现在他要设计一个电子日历类TDate。

它有3个私有数据成员:Month,Day,Year和若干个公有成员函数,要求:

(1)带有默认形参值的构造函数,默认值为0, 0, 0;

(2)输出日期函数,用“日/月/年”格式输出日期;

(3)设置日期函数,从键盘输入年、月、日。

输入描述:

一行,三个整数,用空格分隔,分别表示年、月、日。

输出描述:

一行,用“日/月/年”格式输出日期。

示例1

输入:

2019 12 30

输出:

30/12/2019

代码:
​
解法一:
​
#include<stdio.h>
​
typedef struct day_t Pday_t ;
​
typedef void (*TInitDay)(Pday_t* day);
​
typedef void (*TSetDay)(Pday_t* day, int y, int m, int d);
​
typedef void (*TShowDay)(Pday_t* day);
​
struct day_t 
{
int Day;
​
int Month;
​
int Year;
​
TInitDay init;
​
TSetDay  set;
​
TShowDay show;
​
};
​
void day_init(Pday_t* day)
{
day->Year  = 0;
​
day->Day   = 0;
​
day->Month = 0;
​
}
​
void day_set(Pday_t* day, int y, int m, int d) 
{
day->Year  = y;
​
day->Month = m;
​
day->Day   = d;
}
​
void day_show(Pday_t* day) 
{
​
printf("%d/%d/%d", day->Day, day->Month, day->Year);
}


Pday_t M_day = 
{
.init = day_init,
​
.set  = day_set,
​
.show = day_show,
}
​
int main()
{
int y, m, d;
​
scanf("%d", &y);
​
scanf("%d", &m);
​
scanf("%d", &d);
​
M_day.init(&M_day);
​
M_day.set(&M_day, y, m, d);
​
M_day.show(&M_day);
​
return 0;
}
​
解法二:
​
#include <stdio.h>
​
//配合指针缩小存储压力
​
typedef struct ki
​
{
​
 int year;
​
 int month;
​
 int day;
​
}ki;
​
 void p(ki*e,int a,int b,int c)//直接传入地址,操作ki的成员值,不再构造虚拟空间进行值传递
​
  {
  e->day=c;   //等价于(*e).day=c,加括号原因是防止*与.优先级影响结果
​
  e->month=b; //等价于(*e).month=b
​
  e->year=a;  //等价于(*e).year=a
​
  printf("%d/", e->day); 
​
  printf("%d/",(*e).month); 
​
  printf("%d",e->year); 
  }


int main() 
{
void p(ki*e,int a,int b,int c);
​
int a,b,c;
​
ki ki1={0,0,0};                          //初始化为0
scanf("%d %d %d",&a,&b,&c);
p(&ki1,a,b,c);
}

本文借鉴了以下文章的样例与知识,原文链接如下:原文链接:

————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:

因篇幅问题不能全部显示,请点此查看更多更全内容