目前,定制正在变的愈来愈广泛,定制服务、定制衣服、甚至使用的键盘都是定制了。在C语言中虽然也包括了整型、字符型和浮点型等基本类型,也有基本的组合数据类型数组。可是这些类型都是针对某一种特定类型时应用没有问题,可是类型自己严格限定了数据的存储特征、取值范围、可以进行的操做等方面。可是在面对复杂多变的世界时,有些数据只用基本数据表示,使用将边的异常复杂;甚至有的时候只是借助基本类型都没法表示有些数据,所以数据的多样性就很是有必要了。多样的主要途径就是数据类型定制,C语言中数据定制的基础包括:指针、结构体、位段、联合体、枚举和关键字typedef,经过将这些东东进行简单的组合实现数据的类型定义。数组
1、结构体概念和干年:函数
一、主要针对须要较多种类的数据才能表示的数据,采用结构体表示会很是方便,例如须要表示在校生的学号、姓名、年龄、性别、成绩、其余等信息时数据类型规划以下:spa
学号 long指针
姓名 char[]code
年龄 intblog
性别 boolj内存
成绩 float编译器
很明显看出,不管是采用那种基本的数据类型都没法完整的表示学生的信息。采用自定义数据类型就成了惟一的选择,采用结构体数据类型才能把这些数据有效的组织在一块儿。编译
二、结构体的关键字:struct,常见的教材中的声明方式为结构体关键字struct,结构体的标签stu,结构体的成员声明long sNo; char sName[30]; int sAge; bool sSex; float sScore;等,能够包括其余的自定义类型的数据,全部的成员放置到一对大括号{}中,括号后面必须有“;”代表结构体声明的结束,在此直接接一个结构体的变量名,这是第一种结构体变量声明的方法: class
1 struct stu{ 2 long sNo; 3 char sName[30]; 4 int sAge; 5 bool sSex; 6 float sScore; 7 } stu1;
初始化的方法为:
1 stu1.sNo = 0001; 2 //stu1.sName = "zhangsan"; 3 strcpy(stu1.sName, "zhangsan"); 4 stu1.sAge = 20; 5 stu1.sSex = true; 6 stu1.sScore = 78.5;
输出方法很简单:
1 printf("%s's info: sNo--%d\t sAge--%d\t sSex--%d\t sScore--%f\n", stu1.sName, stu1.sNo, stu1.sAge, stu1.sSex, stu1.sScore);
应该没有任何问题,可是存在一个问题就是,在定义结构体的同时进行结构体变量的定义,另外的结构体变量声明方法,若想再次定义,必须使用struct stu stu2之类的方式定义
1 struct stu stu2; 2 3 stu2.sNo = 0002; 4 strcpy(stu2.sName, "lisi"); 5 stu2.sAge = 21; 6 stu2.sSex = true; 7 stu2.sScore = 80.8; 8 9 printf("%s's info: sNo--%d\t sAge--%d\t sSex--%d\t sScore--%f\n", stu2.sName, stu2.sNo, stu2.sAge, stu2.sSex, stu2.sScore);
整个的结果是:
1 zhangsan's info: sNo--1 sAge--20 sSex--1 sScore--78.500000 2 lisi's info: sNo--2 sAge--21 sSex--1 sScore--80.800003
说明:一、结构体类型声明必须有struct关键字,后又数据类型名
二、定义体现了用户使用的自主性,能够有不一样的数据组合
三、结构体全部成员,包含类型和名称,必须包含在大括号中,成员能够为基本类型和自定义类型(结构体、枚举、联合体、指针、数组等),甚至能够为结构体自身,结构体定义能够嵌套
四、结构体成员内部之间不容许有重名,可是能够和其余的结构体成员名称同样,结构体成员在结构体的命名空间中
五、结构体的声明只能告诉编译器结构体的特征,以及使用时的数据特征,必须等结构体变量完成初始化后,才有内存分配
六、结构体定义通常做为全剧变量,放置到全部函数的外部,或者放置到实现文件的外部,放置到头文件中
七、结构体一旦定义以后,能够和普通类型同样使用,能够定义结构体数组,结构体变量,结构体指针,甚至,可让函数传递和返回结构体变量
八、结构体在分配内存时,存在着内存对齐的状况,最好不要人工计算结构体的内存大小,直接使用sizeof(struct stu)能够获取咱们定义的结构体的大小
其实咱们也能够先定义结构体,在使用struct stu stu2这样的方法来定义结构体变量。
在定义结构体的同时,声明结构体的变量时,能够定义匿名结构体,可是,必须在声明的同时,声明结构体的变量。
1 struct { 2 long sNo; 3 char sName[30]; 4 int sAge; 5 bool sSex; 6 float sScore; 7 } stu3; 8 9 stu3.sNo = 0003; 10 strcpy(stu3.sName, "wangwu"); 11 stu3.sAge = 23; 12 stu3.sSex = true; 13 stu3.sScore = 83.10; 14 15 printf("%s's info: sNo--%d\t sAge--%d\t sSex--%d\t sScore--%f\n", stu3.sName, stu3.sNo, stu3.sAge, stu3.sSex, stu3.sScore);
1 zhangsan's info: sNo--1 sAge--20 sSex--1 sScore--78.500000 2 lisi's info: sNo--2 sAge--21 sSex--1 sScore--80.800003 3 wangwu's info: sNo--3 sAge--23 sSex--1 sScore--83.099998
因而可知,实际上,有名和无名结构体使用时同样的,不同的就是再次定义时,特别有结构体嵌套时,更加明显。
1 typedef struct _stu{ 2 long sNo; 3 char sName[30]; 4 int sAge; 5 bool sSex; 6 float sScore; 7 } Student; 8 9 Student stu4; 10 11 stu4.sNo = 0004; 12 strcpy(stu4.sName, "zhaoliu"); 13 stu4.sAge = 24; 14 stu4.sSex = true; 15 stu4.sScore = 90.16; 16 17 printf("%s's info: sNo--%d\t sAge--%d\t sSex--%d\t sScore--%f\n", stu4.sName, stu4.sNo, stu4.sAge, stu4.sSex, stu4.sScore);
执行结果:
1 zhangsan's info: sNo--1 sAge--20 sSex--1 sScore--78.500000 2 lisi's info: sNo--2 sAge--21 sSex--1 sScore--80.800003 3 wangwu's info: sNo--3 sAge--23 sSex--1 sScore--83.099998 4 zhaoliu's info: sNo--4 sAge--24 sSex--1 sScore--90.160004
这种定义使用时更加的连贯和流畅。
2、结构体的引用和成员的引用
结构体的应用和普通变量的引用彻底同样,可是对结构体变量的赋值,其实是对结构体变量的成员变量赋值操做的过程,注意方式方法。
结构体变量成员的引用,须要使用成员访问符号“.”,方法就是stu4.sName访问结构头体变量stu4中的成员变量sName的值,一切so easy!
可是一旦面对结构体指针变量时,就有两种方法(*ptrStu4).sName访问结构体指针变量ptrStu4中的成员变量sName的值,也可使用ptrStu4->sName这样的方法,特别是后者,用的不少,可是不作说明,很是容易搞糊涂的。好了,到此为止吧。