1,结构体和结构体变量
2,结构体是自定义的数据类型,表示的是一种数据类型
结构体变量代表一个具体变量
struct Cat cat1; Cat是结构体数据类型,cat1 是一个Cat变量
Cat就像一个“模板”,定义出来的结构体变量都含有相同的成员,也可以将结构体比作“图纸”,将结构体比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。
3,养猫问题:张老太养了两只猫,一只名字叫小白,今年3岁,白色,还有一只叫小花,今年100岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色,如果用户输入的小猫名错误,则显示,张老太没有这只猫。
1 void main() { 2 //创建结构体 Cat 3 struct Cat { 4 char* name; //名字,使用指针,指向字符串 5 int age; 6 char* color; 7 }; 8 //使用Cat结构体,创建变量 9 struct Cat cat1; 10 struct Cat cat2; 11 12 //给cat1的各个成员赋值 13 cat1.name = "小白"; 14 cat1.age = 3; 15 cat1.color = "白色"; 16 17 //给cat2的各个成员赋值 18 cat2.name = "小花"; 19 cat2.age = 100; 20 cat2.color = "花色"; 21 22 //输出两只猫的信息 23 printf("第一只猫:name=%s age=%d color=%s ", cat1.name, cat1.age, cat1.color); 24 printf("第二只猫:name=%s age=%d color=%s ", cat2.name, cat2.age, cat2.color); 25 }
结构体体变量在内存中的布局:
4,声明结构体
struct 结构体名称 { //结构体首字母大写
成员列表; //成员也可以是结构体
}
5,成员
①从叫法上看,有些书上称为成员,有些书说,结构体包含的变量
②成员是结构体的一个组成部分,一般是基本数据类型,也可以是数组,指针,结构体等。
③成员声明语法同变量 数据类型 成员名
④字段的类型可以为:基本类型 数组或指针 结构体等。
⑤不同结构体变量的成员是独立的,互不影响的,一个结构体变量的成员 更改,不影响另外一个。
6,在创建一个结构体变量后,需要给成员赋值,如果没有赋值就使用可能导致程序异常终止。
7,创建结构体和结构体变量
①方式1,
struct Stu {
char* name;
int num;
int age;
char group; //所在学习小组
float score;
};
struct Stu stu1,stu2 ;
②方式2,在定义结构体的同时,创建结构体变量
struct Stu {
char* name;
int num;
int age;
char group;
float score;
} stu1,stu2;
③方式3,如果只需要 stu1,stu2两个变量,后面不需要再使用结构体类型,定义其他变量,在定义时也可以不给出结构体名
struct { //没有写Stu
char* name;
int age;
char group;
}stu1,stu2;
该结构体数据类型,没有名字,匿名结构体
8,成员的获取和赋值
结构体和数组类似,也是一组数据的集合,整体使用没有太大意义,数组使用下标获取单个元素,结构体使用点号获取单个成员,获取结构体成员的一般格式为:
结构体变量名.成员名
9,编写一个Dog结构体,包含 name(char[10]),age(int),weight(double)属性
编写一个 say 函数,返回字符串,方法返回信息中包含所有成员值
在 main 方法中,创建 Dog 结构体变量,调用 say 函数,将调用结果打印输出
1 //定义结构体 2 struct Dog { 3 char* name; //name是一个字符串,可以用char* 字符指针保存,相当于char name[50] 4 int age; 5 double weight; 6 }; 7 //say函数,返回字符串,信息中包含所有成员值 8 char* say(struct Dog dog) { 9 static char info[50]; //将这个信息放入到一个字符串(字符数组中),info保存信息,最终返回它 10 sprintf(info, "name=%s age=%d weight=%.2f", dog.name, dog.age, dog.weight);//把小狗信息格式化存入到info中 11 dog.name = "小花"; //结构体默认是值传递,所以这里的"小花"并不会影响到main中的"小黄" 12 return info; 13 } 14 void main(){ 15 //测试 16 struct Dog dog; 17 dog.name = "小黄"; 18 dog.age = 16; 19 dog.weight = 3.4; 20 char* info = say(dog); 21 22 printf("小狗信息:%s: ", info); 23 printf("小狗名字=%s ", dog.name); //仍然是"小黄" 24 }
10,景区门票案例
一个景区根据游人的年龄收取不同价格的门票。请编写游人结构体(Vistor),根据年龄段决定能够购买的门票价格并输出,规则:年龄 > 18 ,门票为20元,其他情况免费。可以循环从控制台输入名字和年龄,打印门票收取情况,如果名字输入 n ,则退出程序
1 struct Vistor { 2 char* name; 3 int age; 4 double pay; 5 }; 6 double getPay(struct Vistor* vistor) { 7 if ((*vistor).age> 18) { 8 return 20.0; 9 } 10 else { 11 return 0.0; 12 } 13 } 14 void main() { 15 struct Vistor vistor; 16 /*vistor.name = "jack"; 17 vistor.age = 20; 18 vistor.pay = getPay(&vistor); 19 printf("该游客应付:%.2f元", vistor.pay);*/ 20 21 while (1) { 22 printf("请输入游客名字: "); 23 scanf("%s", &vistor.name); 24 if (!strcmp("n", &vistor.name)) { //相当于strcmp("n", vistor.name) == 0 25 printf("退出循环"); 26 break; 27 } 28 else { 29 printf("请输入游客年龄: "); 30 scanf("%d", &vistor.age); 31 vistor.pay = getPay(&vistor); 32 printf("该游客应付:%.2f元 ", vistor.pay); 33 } 34 } 35 36 }
说明:因为结构体默认是值传递,会拷贝一份完整数据,效率较低,因此,为了提高效率,我们直接接收地址(指针)