版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第7章 结构体与共用体,Contents,7.1 结构体,7.2 结构体数组,7.3 指向结构体类型数据的指针,7.4 结构体与链表,7.5 共用体,7.6 枚举,7.7 用typedef定义类型,7.1 结构体,前面已介绍过数组,它存储的是一组相同类型的数据。但在实际问题中,一组数据往往具有不同的数据类型。例如,一个学生的信息包括学号、姓名、性别、年龄和成绩等。这些数据的类型各不相同:姓名为字符型,学号为整型或字符型,性别为字符型,年龄为整型,成绩为实型,这显然不能用一个数组存放。为了解决这一问题,C语言提供了一种构造数据类型结构体,它能将不同类型的数据存放在一起。,一、结构体类型的定义 s
2、truct 结构体名 成员列表 ; 例如,表示学生基本信息的结构体类型可定义如下: struct student int num; char name20; char sex; int age; float score; ;,7.1 结构体,二、结构体类型变量的定义 1、先定义结构体再定义变量 struct student ; struct student stu1, stu2; 为了使用方便,可以通过宏定义用一个符号常量来表示一个结构体类型,还可以用typedef来自定义数据类型。 #define STUDENT struct student STUDENT int num; ; STUDE
3、NT stu1, stu2;,7.1 结构体,typedef 已有类型名 新类型名; 如:typedef int INTEGER; 则 INTEGER i; 等价于 如:typedef int NUM10; 则 NUM a; 等价于 如:typedef char *STRING; 则 STRING p; 等价于 如:typedef struct int num; STUDENT; STUDENT stu1, stu2;,int i;,int a10;,char *p;,7.1 结构体,由此可见,一个C程序结构一般为: #include /*文件包含处理*/ #define /*宏定义*/ ty
4、pedef struct /*定义结构体类型*/ STUDENT; int max(int x, int y); /*函数说明*/ main() /*主函数*/ int max(int x, int y) /*子函数*/ ,7.1 结构体,注意: (1)结构体类型所占字节数=各成员所占字节数之和。 (2)如何求结构体类型所占字节数? 运算符sizeof求某种数据类型所占字节数。 如:sizeof(int)=2 sizeof(float)=4 sizeof(struct student)= 2、定义类型同时定义变量 struct student stu1, stu2;,2+20+1+2+4=29
5、,7.1 结构体,3、直接定义结构体类型变量(无结构体名) struct stu1, stu2; 说明: (1)一般采用“先定义类型再定义变量”。 (2)成员名可与程序中的变量同名,但表示的是两个不同的量。 (3)成员也可以为一个结构体。如: struct date int year; int month; int day; ;,struct student struct date birthday; ;,7.1 结构体,三、结构体变量的初始化 (按顺序依次给各成员赋初值) 如:struct student stu=100, “Liu”, M, 19, 95.5; 不能写成: struct s
6、tudent stu; stu=100, “Liu”, M, 19, 95.5; 说明:C允许对结构体变量进行初始化,但不允许将一组常量通过赋值语句直接赋给一个结构体变量。,7.1 结构体,四、结构体变量的引用 相同类型的结构体变量可相互整体赋值,但一般情况下,不能整体引用,只能对各个成员分别引用。 如: struct student stu1, stu2=100, “Liu”, M, 19, 95.5; stu1=stu2; 如:printf(“ “, stu1); 引用成员方式:结构体变量名成员名 如:printf(“ “, stu1.num, , ); 正确。 注意:若
7、成员本身为一个结构体,则需一级一级展开,只能对最低级的成员进行引用。 如:printf(“ “, stu1.birthday);,正确,错误,错误,7.1 结构体,printf(“ “, stu1.birthday.year, stu1.birthday.month, stu1.birthday.day); 正确。 【例7-1】设计一个程序,输入一个学生的信息并显示。 【程序分析】 假设学生信息包括:学号、姓名、性别、年龄和成绩,则定义一个结构体类型struct student表示学生信息。,7.1 结构体,struct student int num; char name20; char s
8、ex; int age; float score; ;,【程序源代码】 #include stdio.h #include string.h struct student int num; char name20; char sex; int age; float score; main() struct student student1; char ch;float x; printf( input sutdent1 information:n); printf(num name age sex scoren); scanf(%d,7.1 结构体,ch=getchar(); scanf(%c
9、, ,7.1 结构体,结构体数组是指每个元素为同一结构体类型的数组。 一、结构体数组的定义 struct student int num; char name20; char sex; int age; float score; ; struct student stu3; 定义了一个数组stu,该数组有3个元素,均为struct student类型,包含5个成员(如图7-2所示)。,7.2 结构体数组,7.2 结构体数组,二、结构体数组的初始化 如:struct student stu3=100, “Li”, F, 20, 80, 101, “Xiao”, M, 19, 90, 102, “
10、Chen”, M, 18, 95;,【例7-2】求四个学生的五门课的平均成绩并输出。 【程序分析】 假设学生信息包括:学号、姓名、5门课成绩、平均分,则定义一个结构体类型struct chengji表示学生信息。 struct chengji int num; char name10; float s5; float aver; ; 该题要对4个学生的信息进行处理,故需定义一个结构体数组stud4,将4个学生信息存入。 struct chengji stud = ,;,三、结构体数组的应用,7.2 结构体数组,求第i个学生5门课成绩(studi.s0,studi.s4)的平均分,赋给studi
11、.aver。 studi.aver=0; for(j=0;j5;j+) studi.aver+=studi.sj; studi.aver/=5.0; 【程序源代码】 #include”stdio.h” struct chengji int num; char name10; float s5; float aver; ; /*结构体类型定义*/,7.2 结构体数组,main() int i ,j; struct chengji stud =111, “zhang san”,67,89,76, 54,86,0,105, “li si”,87,73,88,75,78,0,109, “wang wu
12、”,79,82,56,64,77,0,107, “zhang na”,60,53,91,75, 65,0; /*结构体数组定义及初始化*/ for(i=0;i4;i+) for(j=0;j5;j+) studi.aver+=studi.sj; studi.aver/=5.0; printf(“%d % -10s %3.0f %3.0f %3.0f %3.0f %3.0f %5.1f n”,studi.num,, studi.s0, studi.s1, studi.s2, studi.s3,studi.s4, studi.aver); ,7.2 结构体数组,【例7-3】有三个
13、候选人,10个人投票,每人只能投一个候选人的票,统计三个候选人的总票数。 【程序分析】 定义一个结构体类型struct person表示候选人信息(包括姓名、票数)。 struct person char name8; int count; ; 定义一个结构体数组leader3存放3个候选人信息,并进行初始化,首先使票数都置零。 struct person leader3= ZHANG,0, WANG,0, LI,0;,7.2 结构体数组,如何统计票数? 输入一个被选人的名字(用字符数组lead_name存放),然后将该名字与3个候选人的名字进行比较,若与某候选人名字(即leaderj.nam
14、e)相同,则该候选人的票数加1(即leaderj.count+),直至10个人投完票。 【程序源代码】 #include stdio.h #include string.h struct person char name8; int count; ; main() int i,j; struct person leader3= ZHANG,0, WANG,0, LI,0; char lead_name8;,7.2 结构体数组,for(i=1;i=10;i+) /*统计票数*/ scanf(%s,lead_name); for(j=0;j3;j+) if(strcmp(lead_name,lea
15、)=0) leaderj.count+; for(j=0;j3;j+) printf(%8s: %dn,,leaderj.count); ,练习:有3个学生,每个学生信息包括:学号、姓名、三门课成绩,请输入3个学生的信息并输出。,7.2 结构体数组,一、指向结构体变量的指针 如:struct student int num; ; struct student stu=100, “Liu”, M, 98; struct student *p; p=,(*p).num,p-num,7.3 指向结构体类型数据的指针,由此可见:结构体成员的引用方式(3种):
16、结构体变量名成员名 (*p)成员名 p-成员名 注意: (*p).num及p-num表示:p所指结构体变量中的成员num 区分:p-n, p-n+, +p-n,7.3 指向结构体类型数据的指针,二、指向结构体数组的指针 如: struct student int num; char name20; char sex; float score; ; struct student stu3=100, “Li”, F, 80, 101, “Xiao”, M, 90, 102, “Chen”, M, 95; struct student *p=stu;(则p+1指向下一个元素stu1) 通过指针p输出
17、3个学生的信息,如何实现? for(; pnum, p-name, p-sex, p-score);,7.3 指向结构体类型数据的指针,三、结构体变量作函数参数 采取 “值传递” ,将实参(各成员)的值传递给形参,形参也必须是同类型的结构体变量。 【例7-6】有一个结构体变量stu,内含学生学号、姓名和3门课程的成绩。编程输出该结构体变量各成员的值。要求定义一个函数list输出一个结构体变量的值。 【程序源代码】 #include stdio.h struct student int num; char name20; float score3; void list(struct studen
18、t stu2) printf(%d,%s,%5.1f,%5.1f,%5.1fn,stu2.num,,stu2.score0,stu2.score1,stu2.score2); ,7.3 指向结构体类型数据的指针,main() struct student stu1=1001, LiLin,67.5,89,78; list(stu1);/*调用list函数*/ 四、结构体指针作函数参数 如:struct student int num; char name20; char sex; float score; ; main() struct student stu3=100, “
19、Li”, F, 80, 101, “Xiao”, M, 90, 102, “Chen”, M, 95; output(stu, 3); ,7.3 指向结构体类型数据的指针,void output(struct student *p, int n) /*输出指针p所指结构体数组中n个元素的各成员值*/ struct student *p_end=p+n; for(; pnum, p-name, p-sex, p-score); ,7.3 指向结构体类型数据的指针,一、链表概述 假设定义这样一个结构体: struct node int data; struct node *next; /*next
20、是指向该类结构体的指针*/ 再定义3个该类型的结构体变量: NODE n1, n2, n3; 执行下列语句: n1.data=10; n2.data=20; n3.data=30; n1.next= n3.next=NULL,typedef NODE;,7.4 结构体与链表,通常在链表中设立一个指针head指向第一个结点,称为“头指针”。 当head所指链表为空时head=NULL,则判链表非空的条件是?,使得n1, n2和n3“链接”起来(如下图所示):,我们将这样的表(通过指针将若干个元素链接起来的表)称为“链表”,表中的每一个结构体称为“结点”。n2称为n1的“后继”结点,n1称为n2的
21、“前驱”结点。,由此可见,链表的每个结点由两部分构成:数据域(data)、指针域(next)。,7.4 结构体与链表,二、链表的建立 【例7-9】编写一个创建链表的函数:输入若干学生的信息存入链表中,以学号为0作为结束标志。 【程序分析】用什么存放这若干学生的信息?用“数组”?数组长度如何确定?可不可以根据输入学生信息的个数来确定数组长度?若输入10个学生信息,就定义为10,输入20个,就定义为20? struct student int num; int n=0; scanf(%d%f,7.4 结构体与链表,不能。因为C语言中,数组长度必须预先定义好,不能动态定义。如果数组长度定义得过大则浪
22、费内存空间,若过小则不够用。对于这一类问题(即:用户所需的内存空间取决于实际输入的数据而无法预先确定),用数组很难解决。为此,C语言提供了一些动态分配内存空间的函数,称为“动态存储分配函数”,可以按需要动态地分配内存空间,也可把不再使用的空间回收。,7.4 结构体与链表,我们主要介绍2个动态存储分配函数: (类型说明符 *)malloc(size) 功能:分配一个长度为size字节的连续空间。函数返回值是一个指针,即该段空间的起始地址。如:char *pc; int *pi; pc=(char *)malloc(100); 或者 pi=(int *)malloc(100); 表示分配100个字
23、节的内存空间,该空间用来存放字符型数据,函数返回值强制转换为字符型指针,并将该指针赋给指针变量pc。简言之,也就是分配一块大小为100字节的内存空间,用指针pc指向。 free(void *p) 功能:回收(释放)p所指的内存空间。,7.4 结构体与链表,【例7-9】建立单链表的基本思想:先建立一个空表,再将各结点逐个插入到表尾。 设头指针head,指针p指向当前表尾结点,指针s指向创建的新结点。 建立一个空表。,p=head=NULL;,7.4 结构体与链表,将第1个结点插入到表尾。 输入第1个学生信息 scanf(%d%f,7.4 结构体与链表,将其它各结点插入到表尾。 输入下一个学生信息
24、 scanf(%d%f,7.4 结构体与链表,将最后一个结点的next域置空。 p-next=NULL;,7.4 结构体与链表,注:可合并在一块 if(head=NULL) head=s; else p-next=s;,【程序源代码】 struct student int num; /*学号*/ float score; /*成绩*/ struct student *next; /*指向下一个结点的指针*/ ; struct student *create() /*创建一个链表,返回其头指针*/ struct student *head,*p,*s; int num; float score;
25、 scanf(%d%f,7.4 结构体与链表,while (num!=0) if (head=NULL) head=s; /*若插入第一个结点*/ else p-next=s; /*若插入其它结点*/ p=s; /*p指向新的表尾*/ scanf(%d%f, /*返回链表的头指针*/ ,7.4 结构体与链表,【例7-10】定义一个函数:输出头指针head所指单链表中各结点的值(简称为:输出单链表head)。 void print(struct student *head) struct student *p; for(p=head; ; ) printf(%d,%3.1fn,p-num ,p-
26、score ); ,p=p-next,p!=NULL,思考/练习:编程:输入若干学生的信息存入链表中并输出,以学号为0作为结束标志。,7.4 结构体与链表,三、链表的插入 在*p后插入*s 设p指向链表中某结点,s指向待插入的新结点,将*s插入到*p的后面,插入操作如下图所示。 注意:两个指针的操作顺序不能交换。,s-next=p-next; p-next=s;,7.4 结构体与链表,在*p前插入*s 先找到*p的前驱*q,再插入。,设链表头指针为head,操作如下: q=head; while ( ) q=q-next; /*找*p的直接前驱*/ s-next=q-next; q-next=
27、s;,q-next!=p,7.4 结构体与链表,由此可见: 在链表上进行插入操作,必须首先找到插入位置的前一个结点。 链表的插入,通常是先修改待插结点*s的next指针,再修改插入位置的前一个结点的next指针。,【例7-11】已有一个学生链表,各结点是按照学号(num)由小到大顺序排列的。编写一个插入函数insert,插入一个新生的结点,要求插入后的链表依然有序。 【程序分析】 设s指向待插入结点(即新生结点),p指向学生链表的第一个结点(即第一个学生),从第一个结点开始,不断将p所指结点的成员num(学号)与s所指结点的成员num(学号)进行比较,若s-num大于p-num,则移动p指针,
28、指向下一个结点,继续比较,直到s-nump-num为止或者p指向尾结点之后结束。这时找到了插入位置,将*s插入到*p的前面,而链表的插入需要找到插入位置的前一个结点,所以还需找到*p的前驱,用q指向。,7.4 结构体与链表,注意两种特殊情况:一是链表为空,二是s-num第一个结点的成员num,这两种情况都需要修改头指针。 【程序源代码】 struct student *insert(struct student *head,struct student *s) /*将s所指新生的结点插入到head所指的学生链表中,插入后使得该链表仍然有序,函数返回插入后的链表头指针*/ struct stud
29、ent *p,*q; if(head=NULL|s-numnum) /*表空或待插结点第一个结点时*/ s-next=head;head=s;return; q=head;p=q-next; /*q指向第一个结点,p指向第二个结点,即q指向*p的前驱*/,7.4 结构体与链表,while(p!=NULL ,7.4 结构体与链表,q=head; while (q-next!=p) q=q-next; /*找*p的直接前驱*/ q-next=p-next; free(p);,四、链表的删除 设p指向链表中某结点,删除*p,操作如下: 先找到*p的前驱*q,再删除。,7.4 结构体与链表,由此可见:
30、在链表上进行删除操作,必须先找到删除位置的前一个结点。,【例7-12】编写一个删除函数del,删除链表中指定学号所在的结点。 【程序分析】 设p指向学生链表的第一个结点,从第一个结点开始,不断将p所指结点的成员num(学号)与指定学号num进行比较,若p-num不等于num,则移动p指针,指向下一个结点,继续比较,直到p-num = num为止或者p指向尾结点之后结束。这时找到了待删除结点,即*p,而链表的删除需要找到删除位置的前一个结点,所以还需找到*p的前驱,用q指向。 注意3种特殊情况:一是链表为空时不能删除;二是找到的待删结点是第一个结点,这时需要修改头指针;三是待删结点不存在。,7.
31、4 结构体与链表,【程序源代码】 struct student *del(struct student *head,int num) /*在head所指的学生链表中删除其学号等于num的结点,返回删除后的链表头指针*/ struct student *p,*q; if (head=NULL) /*如果是空链表*/ printf(“List is nulln”);return(head); p=head; while(p!=NULL ,7.4 结构体与链表,练习: 在一个单链表中,已知q所指结点是p所指结点的前驱,若在*q和*p之间插入s所指结点,则执行_。 A. s-next=p-next;
32、p-next=s; B. p-next=s-next; s-next=p; C. q-next=s; s-next=p; D. p-next=s; s-next=q; 在一个单链表中,若删除p所指结点的后继结点,则执行_。 A. p=p-next-next; B. p=p-next; p-next=p-next-next; C. p-next=p-next; D. p-next=p-next-next;,7.4 结构体与链表,五、链表的应用举例 【例7-13】编写一个函数:将链表L中的元素逆置,逆置前表中元素为(a1,a2,an),逆置后表中元素为(an,a2,a1)。要求用原有结点,不能重新
33、申请结点。,7.4 结构体与链表,【程序分析】 设指针p指向表中各结点,设指针s指向待插入结点。首先让p指向第一个结点,接着将表L置空,即L=NULL;然后让s指向*p作为当前待插入结点,p指向下一个结点,并将*s插入到,L的表头,接着再让s指向*p作为当前待插入结点,直到p指向表尾之后,即p为空结束。此时得到的就是一个逆置的链表。 【程序源代码】 struct node *invert(struct node *L) /*将链表L中的元素逆置,逆置后返回头指针*/ struct node *p,*s; p=L; L=NULL; while(p!=NULL) s=p; p=p-next; /*
34、将*p作为当前待插结点,用s指向,p指向下一个结点*/ s-next=L; L=s; /*将*s插入到表头*/ return( L ); ,7.4 结构体与链表,【例7-14】将两个递增有序的链表A、B,归并成一个递增有序的单链表C,要求用A、B中的原结点形成,不能重新申请结点。 如:A=(3,5,8,11) B=(2,6,9,15,20) 归并后:C=(2,3,5,6,8,9,11,15,20) 【程序分析】 设指针t指向C表的表尾。先建立一个空表C,即C=t=NULL;再依次比较A、B表中的相应元素,将较小者插入到C的表尾,得到的C表则为递增有序的。 设三个指针变量p, q和s,其中p,
35、q分别指向A、B表中某个结点,s指向当前待插结点。若p-datadata,则让s指向p所,7.4 结构体与链表,指结点作为当前待插结点,并将p指向A的下一个结点;否则,让s指向*q作为当前待插结点,并将q指向B的下一个结点。接着将待插结点*s插入到C的表尾,然后继续比较p-data与q-data,直到其中一个表归并完。最后将另一个表的剩余部分链接到C的表尾。 【程序源代码】 struct node *merge(struct node *A, struct node *B) /*将两个递增有序的链表A、B归并成一个递增有序的链表C,函数返回C表头指针*/ struct node *C,*t,*
36、p,*q,*s; p=A; q=B;/*p,q分别指向A,B表中第一个结点*/ C=t=NULL;/*建立一个空表C*/,7.4 结构体与链表,while(p!=NULL ,7.4 结构体与链表,一、共用体类型的定义 如:union data int a; float b; char c6; ; 二、共用体变量的定义 1、定义(类似“结构体”,也有3种) 如:union data ; union data udata;,7.5 共用体,2、共用体与结构体的区别 (1)结构体中各成员占用连续的不同的内存单元,而共用体中各成员占用相同的内存单元(故称为“共用体”多个不同类型的数据共同占用同一内存单
37、元)。 (2)结构体类型的长度等于各成员长度之和,而共用体类型的长度等于最长成员的长度。如: struct data int a; float b; char c6; a;,union data int a; float b; char c6; b;,问: a占?字节,b占?字节。 12 6,7.5 共用体,三、共用体变量的引用 1、不能整体引用共用体变量,只能引用成员。 2、不允许对共用体变量进行初始化,每次只能给一个成员赋值。 如: union data int a; float b; char c6; udata=10,85.5, “jsj”; 错误。 如:udata.a=10; uda
38、ta.b=85.5; strcpy(udata.c, “jsj”);,如: union data udata; udata =10,85.5, “jsj”; 错误。,正确。,7.5 共用体,共用体变量的特点: (1)共用体变量的地址和它各成员的地址相同。 (2)共用体变量不能整体赋值,不能整体输入输出。 (3)在共用体变量所占内存空间中,任一时刻只能存放其中的一个成员,而不是同时存放所有成员。即任一时刻只有一个成员有效,也就是说共用体变量的所有成员不是同时都存在和有效。 如:union data int i; char ch; float fa; a.i=1; a.ch=A; a.f=3.5;
39、 则:printf(“%d, %c, %fn”, a.i, a.ch, a.f); printf(“%fn”, a.f);,问:此时,哪个成员有效? a.f有效,a.i和a.ch均无意义。,错误。,正确。,7.5 共用体,【例7-15】设有一个教师与学生通用的表格,教师数据有姓名,年龄,职业,教研室四项。学生有姓名,年龄,职业,班级四项。编程输入人员数据,再以表格输出。 【程序分析】 根据题意,每个人员信息包含4项,故定义一个结构体类型struct person包含4个成员,其中,“职业”一项可用“t”表示教师,用“s”表示学生,故“职业”定义成字符型;而“单位”这一项学生应填入班级编号,教师
40、应填入教研室名,班级编号可用整型表示,教研室名只能用字符型数组存放。,7.5 共用体,也就是说,此时“单位”这一项中包含了两种不同类型的数据,而且这两种数据不可能同时存在,要么填入的是班级编号,要么填入的是教研室名,故需将其定义为共用体类型。类型定义如下: struct person char name10; int age; char job; /*职业*/ union int class; /*班级编号*/ char office10; /*教研室名*/ depa; /*单位*/ ;,7.5 共用体,struct person body2; /*定义结构体数组存放两个人员信息*/ 如果输入(输出)的人员是学生(即bodyi.job=s),则输入班级编号存入bodyi.depa.class中;否则输入教研室名存入bodyi.depa.office中。如下所示: if(bodyi.job=s) scanf(%d,7.5 共用体,main() struct person body2; int i; for(i=0;i2;i+) /*输入*/ printf(input name,age,job and departmentn); scanf(%s %d %c, ,7.5 共用体,for(i=0;i2;i+) /*输出*/ if(bodyi.job
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 科技与创新的舞台:小学主题班会课件
- 口腔助理医师护理考试题
- 数字化营销实战操作指南
- 中国冰淇淋行业市场发展现状及竞争策略与投资前景研究报告
- 航空公司空姐乘务员服务质量KPI考核表
- 通知改进客户服务流程函5篇范本
- 生物医药实验室检测服务市场分析与前景展望
- 办公网络安全策略及解决方案
- 立陶宛金融资产管理行业市场现状供需分析及投资评估规划分析研究报告
- 零售业数字化营销趋势报告
- GB/T 45953-2025供应链安全管理体系规范
- DBJT15-242-2022 道路照明工程技术规范
- DBJ15-101-2014 建筑结构荷载规范
- 中医内科副高级职称考试历年真题及答案
- 产品质量投诉处理流程与技巧
- 2025-2030中国注册安全工程师考试大纲修订对安全生产培训市场冲击报告
- 《肉羊智慧养殖技术规范》征求意见稿
- 2024年(煤矿)采煤班组长培训考试题库附答案(含各题型)
- 学堂在线 日语与日本文化 章节测试答案
- 福建省福州第八中学2025届高一下化学期末教学质量检测试题含解析
- QGDW12505-2025电化学储能电站安全风险评估规范
评论
0/150
提交评论