赞
踩
C语言属于面向过程的一门语言,C语言开发工程师在编写代码时也要具有对象的思想,
C语言表示对象的方式就是结构体类型。在C语言中通过结构体类型描述一个对象。什么是对象?
事件的万事万物都可以看出一个对象,通过编程语言抽象的描述一个对象。如何描述一个对象?
将一类对象具有共同的属性和行为剥离处理,非共性的东西剥离出去;
比如人:姓名,年龄,身高,体重,性别,外貌, 吃喝拉撒睡。属性:对象的名词,形容词,量词 —> 抽象成代码:使用变量表示
行为:对象的动词(可以干什么)—> 抽象成代码:使用函数表示结构体的概念
结构体属于C语言中的一个自定义的构造类型,关键字(struct)。
将很多不同的数据类型封装成一个新的数据类型,这个数据类型就是结构体类型,
结构体中的成员在内存空间中是连续的,并且每个成员都有其独立的内存空间。声明一个结构体类型
没有结构体的沟通类型,如何描述一个对象:char name[20]; int age; char sex; int score; ----> 只能描述一个对象,
- 1
- 2
- 3
- 4
如果描述多个对象,在重新定义多次。
如果描述多个对象,在重新定义多次。
有结构体的沟通类型,如何描述一个对象:
struct student{ // 声明一个结构体类型,此时struct student就表示一个结构体类型名, // 使用此类型可以定义结构体类型的变量 char name[20]; int age; char sex; int score; };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
// 定义一个对象
struct student stu1;
// 定义100个对象
struct student stu_arr[100];
// 1. 声明一个结构体类型, 声明结构体类型时并没有在内存中分配空间
struct 结构体名{
数据类型 变量名1;
数据类型 变量名2;
数据类型 变量名3;
…
数据类型 变量名n;
};
此时"struct 结构体名"就是自己构造的新的结构体类型,使用此结构体类型定义结构体类型的变量。
结构体中的成员的类型可以是:基本的数据类型,数组类型,指针类型,指针数组,数组指针,函数指针,
函数指针数组,嵌套的结构体类型,枚举类型,联合体类型。
- 定义普通的结构体类型的变量:
struct 结构体名 结构体变量名;- 定义结构体指针类型的变量:
struct 结构体名 *结构体指针变量名;
- 定义普通的结构体类型的变量:
结构体变量名.成员变量名;- 定义结构体指针类型的变量:
结构体指针变量名->成员变量名;
声明结构体类型
struct student{ char name[20]; int age; char sex; int score; };
- 1
- 2
- 3
- 4
- 5
- 6
定义普通结构体类型的变量 : struct 结构体名 结构体变量名;
struct student stu;
对结构体中的成员进行初始化
3.1> 定义结构体类型变量的同时进行初始化
struct student stu1 = {"yy", 18, 'M', 100};
// 要求按照结构体中成员的类型依次进行初始化
3.2> 先定义结构体类型变量,后进行初始化 : 结构体变量名.成员变量名 = 初始值;struct student stu2; strcpy(stu2.name, "yy"); stu2.age = 18; stu2.sex = 'M'; stu2.score = 100;
- 1
- 2
- 3
- 4
- 5
3.3> 定义结构体类型变量的同时进行初始化
struct student stu1 = { .name = "yy", .age = 18, .sex = 'M', .sorce=100 };
- 1
- 2
- 3
- 4
- 5
- 6
优点:可以只对部分成员初始化,成员初始化的顺序没有要求。
#include <stdio.h> #include <string.h> // 1. 声明结构体类型,结构体类型中的成员根据自己的对象添加对应的成员 struct student { char name[20]; int age; char sex; int score; }; // 相同结构体类型的变量,可以进行赋值操作, // 结构体类型作为函数的形参使用 void print(struct student s) { printf("我的名字叫%s,我的年龄%d,我的性别%c,我的成绩%d\n", s.name, s.age, s.sex, s.score); } int main(int argc, const char *argv[]) { /*your code*/ // 1. 先定义结构体类型的变量,在对结构体变量中的成员初始化 struct student stu1; strcpy(stu1.name, "yy"); stu1.age = 18; stu1.sex = 'M'; stu1.score = 100; print(stu1); // 2. 定义结构体类型变量的同时进行初始化 struct student stu2 = {"yy", 28,'M',88}; print(stu2); // 3. 定义结构体类型变量的同时进行初始化 struct student stu3 = { .name = "lisi", .sex = 'W', .age = 24, .score = 99 }; print(stu3); return 0; }
声明结构体类型的同时定义结构体类型的变量
struct student{ char name[20]; int age; char sex; int score; }stu1, stu2, stu3;
- 1
- 2
- 3
- 4
- 5
- 6
对结构体类型的变量进行初始化
2.1> 声明结构体类型的同时定义结构体变量,同时初始化。struct student{ char name[20]; int age; char sex; int score; }stu1={"yy",18,'M',100};
- 1
- 2
- 3
- 4
- 5
- 6
2.2> 声明结构体类型的同时定义结构体变量,同时初始化。
struct student{ char name[20]; int age; char sex; int score; }stu2 = { .name = "yy", ,age = 18, .sex = 'M', .score = 100};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
2.3> 声明结构体类型的同时定义结构体变量,最后在进行初始化。
struct student{ char name[20]; int age; char sex; int score; }stu3; strcpy(stu3.name, "yy"); stu3.age = 18; stu3.sex = 'M'; stu3.score = 100;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
没有结构体名字的结构体:
声明结构体类型的同时定义结构体类型的变量, 省略结构体的名字,
后续不可以单独使用这个结构体类型在定义新的变量。struct { char name[20]; int age; char sex; int score; }stu1, stu2, stu3;
- 1
- 2
- 3
- 4
- 5
- 6
对结构体类型的变量进行初始化
2.1> 声明结构体类型的同时定义结构体变量,同时初始化。struct { char name[20]; int age; char sex; int score; }stu1={"yy",18,'M',100};
- 1
- 2
- 3
- 4
- 5
- 6
2.2> 声明结构体类型的同时定义结构体变量,同时初始化。
struct { char name[20]; int age; char sex; int score; }stu2 = { .name = "yy", ,age = 18, .sex = 'M', .score = 100 };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.3> 声明结构体类型的同时定义结构体变量,最后在进行初始化。
struct { char name[20]; int age; char sex; int score; }stu3; strcpy(stu3.name, "yy"); stu3.age = 18; stu3.sex = 'M'; stu3.score = 100;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
练习题:定义教师结构体类型,成员姓名(字符数组name),年龄(age),工资(salary)。
并使用类定义结构体变量,对成员进行初始化。
#include <stdio.h> #include <string.h> // 声明结构体类型的同时定义结构体变量 struct teacher { char name[20]; int age; int salary; }tea1 = {"yy", 18, 30000}, tea2 = { .name = "yy", .age = 18, .salary = 35000}, tea3; void print(struct teacher t) { printf("姓名:%s, 年龄:%d, 工资:%d\n", t.name, t.age, t.salary); } int main(int argc, const char *argv[]) { /*your code*/ // 先声明结构体类型,定义结构体变量,后进行初始化 strcpy( tea3.name, "yy"); tea3.age = 16; tea3.salary = 32000; print(tea1); print(tea2); print(tea3); return 0; }
声明结构体类型
struct student { char name[20]; int age; char sex; int score; };
- 1
- 2
- 3
- 4
- 5
- 6
定义结构体指针变量
struct student *p;
对结构体指针变量进行初始化
3.1 结构体指针变量指向栈区的空间:struct student stu = {"yy", 18, 'M', 100}; // 定义普通结构体变量 struct student *p = &stu; struct student *p = NULL; p = &stu;
- 1
- 2
- 3
- 4
3.2 结构体指针变量指向堆区的空间:
struct student *p = (struct student *)malloc(sizeof(struct student)); strcpy(p->name, "yy"); p->age = 18; p->sex = 'M'; p->score = 100;
- 1
- 2
- 3
- 4
- 5
如果定义的是结构体指针变量,没有以下初始化的方式,原因是结构体指针变量占8字节空间(64位系统)
struct student *p = { ->name = "yy", ->age = 18, ->sex = 'M', ->score = 100, };
- 1
- 2
- 3
- 4
- 5
- 6
测试:
#include <stdio.h> #include <string.h> #include <stdlib.h> // 1. 声明结构体类型 struct student { char name[20]; int age; char sex; int score; }; // 函数的形参是一个结构体指针类型 void print(struct student *t) { printf("姓名:%s, 年龄:%d, 性别:%c, 成绩:%d\n", t->name, t->age, t->sex, t->score); } int main(int argc, const char *argv[]) { /*your code*/ // 2. 定义结构体指针类型的变量,指向一个栈区的结构体变量 struct student stu = {"yy", 18, 'M', 100}; print(&stu); struct student *p1 = &stu; print(p1); // 3. 定义结构体指针类型的变量,指向一个堆区的空间。 struct student *p2 = (struct student *)malloc(sizeof(struct student)); if (p2 == NULL) { printf("malloc memory failed!\n"); return -1; } strcpy(p2->name, "yy"); p2->age = 18; p2->sex = 'M'; p2->score = 100; print(p2); return 0; }
1. 声明结构体类型 struct student { char *name; int *age; }; 2. 定义结构体类型的变量并进行初始化 int m_age = 18; struct student stu = {"yy", &m_age}; // char *name指向的是一个字符串常量 char m_name[20]= "yy"; int m_age = 18; struct student stu = {m_name, &m_age}; // char *name指向的是一个字符数组 struct student stu; stu.name = (char *)malloc(sizeof(char)*20); // char *name成员指向堆区空间 stu.age = (int *)malloc(sizeof(int)); // int *age成员指向堆区空间 strcpy(stu.name, "yy"); *stu.age = 18; struct student *p1 = &stu; struct student *p2 /*定义结构体指针变量,p2在栈区分配8字节空间 */ = (struct student *)malloc(sizeof(struct student)); /* 让P2指向堆区空间, 给p2->name成员分配8字节空间,存放地址 给p2->age成员分配8字节空间,存放地址 */ /*对p2中的name成员分配堆区空间并指向堆区的空间 */ p2->name = (char *)malloc(sizeof(char)*20); // char *name成员指向堆区空间 /*对p2中的age成员分配堆区空间并指向堆区的空间 */ p2->age = (int *)malloc(sizeof(int)); // int *age成员指向堆区空间 // 对堆区的空间进行初始化。 strcpy(p2->name, "yy"); *p2->age = 18;
测试:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct student { char *name; int *age; }; void print(struct student *s) { printf("姓名:%s, 年龄:%d\n", s->name, *s->age); } int main(int argc, const char *argv[]) { /*your code*/ int m_age = 18; // 定义普通的结构体变量,并进行初始化 struct student stu1 = {"yy", &m_age}; // char *name指向的是一个字符串常量 // int *age 指向的一个int类型的变量 print(&stu1); char m_name[20] = "yy"; // 定义普通的结构体变量,并进行初始化 struct student stu2 = {m_name, &m_age}; // char *name指向的是一个字符数组 // int *age 指向的一个int类型的变量 print(&stu2); // 定义普通结构体变量,让结构体中的指针类型的成员指向堆区空间 struct student stu3; stu3.name = (char *)malloc(sizeof(char) * 20); // char *name成员指向堆区空间 stu3.age = (int *)malloc(sizeof(int)); // int *age成员指向堆区空间 // 对堆区的空间进行初始化操作 strcpy(stu3.name, "ff"); *stu3.age = 18; print(&stu3); // 定义结构体指针变量, 指向普通的结构体类型的变量 struct student *p1 = &stu3; print(p1); // 定义结构体指针变量,指向堆区空间,结构体中的成员也指向堆区空间 struct student *p2 /*定义结构体指针变量,p2在栈区分配8字节空间 */ = (struct student *)malloc(sizeof(struct student)); /* 让P2指向堆区空间, 给p2->name成员分配8字节空间,存放地址 给p2->age成员分配8字节空间,存放地址 */ /*对p2中的name成员分配堆区空间并指向堆区的空间 */ p2->name = (char *)malloc(sizeof(char) * 20); // char *name成员指向堆区空间 /*对p2中的age成员分配堆区空间并指向堆区的空间 */ p2->age = (int *)malloc(sizeof(int)); // int *age成员指向堆区空间 // 对堆区的空间进行初始化。 strcpy(p2->name, "ff"); *p2->age = 18; print(p2); return 0; }
声明结构体类型
struct student { char name[20]; int age; char sex; int score; };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
定义结构体数组变量 : struct student 结构体数组名[数组的长度];
struct student arr[2];
对数组的成员进行初始化
3.1> 定义的同时进行初始化
struct student arr[2] = {{"yy",18,'M',100},{"yy",18,'M',90}};
3.2> 定义的同时进行初始化
struct student arr[2] = { [0] = { .name = "yy", .age = 18, .sex = 'M', .score = 100 }, [1] = { .name = "yy", .age = 18, .sex = 'M', .score = 90 } };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.3> 先定义结构体数组,后进行初始化
struct student arr[2]; strcpy(arr[0].name, "yy"); arr[0].age = 18; arr[0].sex = 'M'; arr[0].score = 100; strcpy(arr[1].name, "yy"); arr[1].age = 18; arr[1].sex = 'M'; arr[1].score = 90;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
结构体数组中每个元素中的每个结构体成员的访问
void print(struct student *s, int len) { int i; for (i = 0; i < len; i++) { printf("%s %d %c %d\n", s[i].name, s[i].age, s[i].sex, s[i].score); printf("%s %d %c %d\n", (s + i)->name, (s+i)->age, (s+i)->sex, (s+i)->score); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
练习题:定义教师结构体类型,成员姓名(字符数组name),年龄(age),工资(salary)。
并使用类定义结构体变量,对成员进行初始化
结构体数组实现:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct teacher { char name[20]; int age; int salary; }; int main(int argc, const char *argv[]) { struct teacher tea[10]; int n=0;//教师人数 printf("请输入教师人数>"); scanf("%d",&n); for(int i=1;i<=n;i++){ printf("教师%d的姓名:",i); scanf("%s",tea[i].name); printf("年龄:"); scanf("%d",&(tea[i].age)); printf("工资:"); scanf("%d",&(tea[i].salary)); } printf("打印教师工资表>\n"); for (int i=1; i<=n;i++) { printf("教师%d的姓名:%s 年龄:%d 工资:%d\n",i,tea[i].name,tea[i].age,tea[i].salary); } return 0; }
结构体指针实现:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct teacher { char name[20]; int age; int salary; }; int main(int argc, const char *argv[]) { int n=0;//教师人数 printf("请输入教师人数>"); scanf("%d",&n); // struct teacher tea[10]; struct teacher *tea=(struct teacher *)malloc(sizeof(struct teacher)*n); if(NULL==tea) printf("malloc memory filed!\n"); for(int i=0;i<n;i++){ printf("教师%d的姓名:",i+1); // scanf("%s",(*(tea+i)).name); scanf("%s",(tea+i)->name); printf("年龄:"); // scanf("%d",&((*(tea+i)).age)); scanf("%d",&(tea+i)->age); printf("工资:"); // scanf("%d",&((*(tea+i)).salary)); scanf("%d",&(tea+i)->salary); } printf("打印教师工资表>\n"); for (int i=0; i<n;i++) { // printf("教师%d的姓名:%s 年龄:%d 工资:%d\n",i+1,(*(tea+i)).name,(*(tea+i)).age,(*(tea+i)).salary); printf("教师%d的姓名:%s 年龄:%d 工资:%d\n",i+1,(tea+i)->name,(tea+i)->age,(tea+i)->salary); } return 0; }
结构指针数组:本质是一个数组,数组中的成员都是结构体的指针。
格式:
struct 结构体名 *结构体指针数组名[元素个数];初始化:
struct 结构体名 结构体变量0;
struct 结构体名 结构体变量1;
…定义结构体指针数组的同时进行初始化:
struct 结构体名 *结构体指针数组名[元素个数] = {&结构体变量0, &结构体变量1};先定义结构体指针数组,后进行初始化:
struct 结构体名 *结构体指针数组名[元素个数];
结构体指针数组名[下标] = &结构体变量0;
结构体指针数组名[下标] = &结构体变量1;访问结构体指针数组的每个元素,每个元素都是一个结构体指针类型,并访问结构体中的每个成员。
结构体指针数组名[下标]->结构体成员名;
结构体数组指针 : 本质是一个指针,指向的是一个结构体二维数组
格式:
struct 结构体名 (*结构体数组指针名)[元素个数];初始化
定义的同时进行初始化:
struct 结构体名 结构体数组名[元素个数] = {{},{},…};
struct 结构体名 (*结构体数组指针名)[元素个数] = &结构体数组名;先定义后进行初始化:
struct 结构体名 (*结构体数组指针名)[元素个数];
结构体数组指针名 = &结构体数组名;成员的访问
(*结构体数组指针名)[下标].结构体成员名;或者
((*结构体数组指针名)+下标)->结构体成员名;
相同结构体类型的变量可以进行赋值操作。
struct student
{
char name[20];
int age;
char sex;
int score;
};
struct student stu1 = {"yy", 18, 'M', 100};
struct student stu2 = stu1; // 普通结构体变量进行赋值
struct student *p = NULL; // 结构体指针变量进行赋值
*p = &stu1;
struct student *p2 = p; // 结构体指针变量进行赋值
声明一个结构体类型:
struct teacher{ char *name; int age; char sex; int salary; };
- 1
- 2
- 3
- 4
- 5
- 6
// 1. 定义普通的结构体变量,并初始化,完成成员的访问(3种)
// 2. 定义结构体指针, 并初始化,指向堆区的空间或者栈区空间,并访问成员(堆区、栈区)
// 3. 定义结构体数组,并初始化,已经完成数组的每个元素及元素中的每个成员的访问(3种)
// 4. 定义结构体指针数组, 并初始化,访问成员(2种)
// 5. 定义结构体数组指针,并初始化,以及成员的访问
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct teacher{ char *name; int age; char sex; int salary; }tea; int main(int argc, const char *argv[]) { //1. 定义普通的结构体变量,并初始化,完成成员的访问(3种) tea t1={"y1",18,'M',10000};//方法一 tea t2={.name="y2",.age=19,.sex='M',.salary=100};//方法二 //方法三 tea t3; t3.name="y3"; t3.age=20; t3.sex='M'; t3.salary=10000; // 2. 定义结构体指针, 并初始化,指向堆区的空间或者栈区空间,并访问成员 //在栈区 tea t4={"y4",18,'M',10000}; tea *p1_t4=&t4; //在堆区 tea *p2=(tea *)malloc(sizeof(tea)); if(NULL==p2)printf("malloc memory filed!\n"); // 给结构体中的指针赋值的方式(3种) //结构体中name指针直接指向常量区 p2->name="p2"; //结构体中name指针指向栈区 char name[20]="yy"; p2->name=name; //结构体中name指针指向堆区 p2->name=(char *)malloc(sizeof(20)); strcpy(p2->name,"yy"); p2->age=20; p2->sex='M'; p2->salary=1000; free(p2); p2=NULL; // #define DEBUG #ifdef DEBUG1 //error初始化,原因:指针的大小只有8字节(64位系统),不能存储那么多数据 int *p3={ ->name="p3", ->age=20, ->sex='M', ->salary=200} #endif // 3. 定义结构体数组,并初始化,已经完成数组的每个元素及元素中的每个成员的访问(3种) tea t5[2]={{"y5",18,'M',10000},{"y6",18,'M',10000}};//方法一 tea t6[2]={ [0]={"y5",18,'M',10000}, [1]={"y6",18,'M',10000} };//方法二 //方法三 tea t7[2]; t7[0].name="y7"; t7[0].age=20; t7[0].sex='M'; t7[0].salary=2000; t7[1].name="y8"; t7[1].age=20; t7[1].sex='M'; t7[1].salary=2000; //访问 for(int i=0;i<2;i++){ printf("%s %d %c %d\n",t7[i].name,t7[i].age,t7[i].sex,t7[i].salary); printf("%s %d %c %d\n",(*(t7+i)).name,(*(t7+i)).age,(*(t7+i)).sex,(*(t7+i)).salary); printf("%s %d %c %d\n",(t7+i)->name,(t7+i)->age,(t7+i)->sex,(t7+i)->salary); } // 4. 定义结构体指针数组, 并初始化,访问成员(2种) tea t9={"y9",18,'M',10000}; tea t10={"y10",18,'M',10000}; tea *t8[2]={&t9,&t10};//方法一,定义结构体指针数组的同时进行初始化 //访问 for(int i=0;i<2;i++){ printf("%s %d %c %d\n",(*t8[i]).name,(*t8[i]).age,(*t8[i]).sex,(*t8[i]).salary); } //方法二,先定义结构体指针数组,后进行初始化 tea *t11[2]; t11[0]=&t9; t11[1]=&t10; //访问 for(int i=0;i<2;i++){ printf("%s %d %c %d\n",t11[i]->name,t11[i]->age,t11[i]->sex,t11[i]->salary); } // 5. 定义结构体数组指针,并初始化,以及成员的访问(2种) //方法一:定义的同时进行初始化 tea t13[2]={{"y13",18,'M',10000},{"y13",19,'M',10000}}; tea (*t12)[2]=&t13; //访问: for(int i=0;i<2;i++){ printf("%s %d %c %d\n",(*t12)[i].name,(*t12)[i].age,(*t12)[i].sex,(*t12)[i].salary); printf("%s %d %c %d\n",(*((*t12)+i)).name,(*((*t12)+i)).age,(*((*t12)+i)).sex,(*((*t12)+i)).salary); printf("%s %d %c %d\n",((*t12)+i)->name,((*t12)+i)->age,((*t12)+i)->sex,((*t12)+i)->salary); } //方法二:先定义后进行初始化 tea (*t14)[2]; t14=&t13; //访问: for(int i=0;i<2;i++){ printf("%s %d %c %d\n",(*t14)[i].name,(*t14)[i].age,(*t14)[i].sex,(*t14)[i].salary); printf("%s %d %c %d\n",(*((*t14)+i)).name,(*((*t14)+i)).age,(*((*t14)+i)).sex,(*((*t14)+i)).salary); printf("%s %d %c %d\n",((*t14)+i)->name,((*t14)+i)->age,((*t14)+i)->sex,((*t14)+i)->salary); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。