------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
构造类型 结构体、枚举和关键字typedef
构造类型 由多个或者已经定义的类型元素用构造的方法,构造新的类型
构造类型:数组 结构体
一、结构体
1.结构体概念:
由相同类型或者不同类型的数据用构造方法,构造的类型
结构体的定义
struct 结构体名{
成员列表
}
定义一个汽车结构体
struct Car{
char*color;
int lunzi;
int speed;
};
定义结构体三种方法
1)先定义结构体,然后在定义结构体变量
struct Student{
//学生学号
int sno ;
//学生姓名
char [10];
//学生年龄
int age;
//学生成绩
float score;
};
注意:
结构体定义完以后,计算机并不会给结构体分配内存空间,会在定义结构体变量后分配变量
结构体变量定义格式 struct 结构体 结构体变量名;
struct Student stu1; 这句话表示定义一个Student结构体变量,变量名为 stu1
//stu1 是Student类型,stu1可以存放学生的信息。成绩,姓名...
struct Student stu1,stu2,stu3;可以定义多个结构体变量
2)定一结构体的同时,定义结构体变量
格式
struct 结构体名{
}结构体变量1,结构体变量2。。。;
struct Student{
//学生学号
int sno ;
//学生姓名
char [10];
//学生年龄
int age;
//学生成绩
float score;
}stu3,stu4,....;
3)匿名结构体定义结构体变量
struct {
}结构体变量1,结构体变量2,...;
struct {
int lunzi;
int speed;
char*color;
}car1,car2,car3;
2结构体变量中成员访问方法
结构体变量名.成员变量
//定义一个Car类型的结构体
struct Car{
char*pp;
int lunzi;
int speed;
};
//用结构体类型,定义结构体变量
struct Car car1;
用 car1.pp ;
car1.lunzi;
car1.speed;
3结构体变量的初始化
struct Student{
//学号
int sno;
//学生姓名
char name[21];
//学生年龄
int age ;
//学生成绩
float score;
};
struct Student stu1;
//结构体变量的初始化
stu1.sno = 28;
stu1.age = 18;
stu1.score= 36.88f;
//stu1.name="abc"; 这里是错的
char name1[21]="张三丰";
//这里是用字符串拷贝函数,将 char name1 拷贝到stu1.name,覆盖掉stu1.name
strcpy(stu1.name,name1);
printf("学号 %d\n年龄 %d\n分数%.2f\n姓名%s\n",stu1.sno,stu1.age,stu1.score,stu1.name);
//stu1.name 字符长度是多少
printf("stu1.name %ld\n",sizeof(stu1.name));
//stu1.name 字符串的长度是多少
//汉字的编码问题
//UTF-8 xcode中默认的中文的编码是utf-8格式
// 国际通用编码 一个汉字占用3个字节
//GB2312 GBK 国标 一个汉字占用2个字节
printf("stu1.name 长度:%ld\n",strlen(stu1.name));
//2定义结构体的同时,进行初始化
// 初始化值的顺序要和定义结构体的顺序一致
struct Student stu2={8,"豆比",16,57.99};
printf("学号 %d\n姓名%s\n年龄%d\n分数%.2f",stu2.sno,stu2.name,stu2.age,stu2.score);
//3.定义结构体的同时,还可以制定元素的初始化
struct Student stu3={.name = "lady Gaga"};
4 结构体变量的存储原理
结构体占用到内存空间时每个成员占用的字节数之和(对齐考虑)
结构体对齐的含义:1)结构体总长度
2)结构体内部个数据的成员的内存对齐,即数据成员相对结构体的起始位置
结构体大小计算方法和步骤
1)先找对齐模数:对齐模数事基本数据类型中占用字节数最大的那个
2)在计算结构体变量的中个成员占用到字节和
struct A{
short a;//2
char b;//1
float c//4
};
这里可以看到 模数是4,然后先分配4个字节。 锕占两个自己。还多两个,b一个字节补到 a的后面 。c这时是4个自己 。先分配到不够用了。于是就再开辟一个4个自己的内存来直接存储c。所以得到 这个结构体的内存是8个字节。
5.结构体作用域
定义在函数外部的结构体是全局变量
定义在函数体内部的位局部变量。函数退出结构体消失
二、结构体数组
结构体数组: 用来存放大量的结构体相同的结构变量
1.结构体数组的定义
定义的第一种方法
1)定义结构体数组的同时定义结构体变量
strcut Student{
int age;
char*name;
float score;
}stu[5];
2)先定义结构体,后定义数组
struct Student boy[5];
2.结构体数组的初始化方法
1)定义结构体的同时初始化
strcut Student{
int name[21];
int age;
}boys[3]={{"zbx",18},{"ddf",34},{"tyu",23}};
2)定义的同时进行初始化
strcut Student girl[2]={{"zbz",18},{"lzl",23}};
3)先定义后初始化 ,整体赋值
struct Student ds[2];
ds[0]=(struct Student){"xzmly",18}
ds[1]=(struct Student){"bdjy",1}
4)定义结构体数组,后初始化
strcut Student stu[2];
//stu[0].name={"zbz"}; 错误的写不进去
//可以用 strcpy(stu[0].name "zzl");
//或者
scanf("%s",stu[0].name);
stu[0].age = 18;
结构体数组的遍历
for(int i =0;i<3;i++){
printf("name:%s,age:%d\n",boys[i].name,boys[i].age);
}
3.代码实现
利用结构体计算不及格到人数,和成绩在80到100点人的名字,成绩
#include <stdio.h>
int main(int argc, const char * argv[]) {
//结构体
struct Student {
int num;
char*name;
char sex;
float score;
};
//1定义结构体数组
struct Student boy[5]={
{101,"li ping",'f',45},
{102,"zhang ping",'m',62.5},
{103,"he fang",'f',92.5},
{104,"cheng ling",'m',87},
{105,"wang ming",'m',58}
};
float sum=0;
float avg=0;
int count=0; //计算不及格人数
for (int i=0; i<5; i++) {
sum += boy[i].score;
if (boy[i].score<60) {
count++;
}else if(boy[i].score >=80 && boy[i].score <= 100){ //判断成绩
printf("姓名%s 成绩%.2f\n",boy[i].name,boy[i].score);
}
}
printf("平均分是%.2f 不及格的人数%d",avg = sum/5.0,count);
return 0;
}
用结构体数组实现通讯录
思路 :
定义一个结构体数组,姓名电话和电话号码
输入完成打印下来。
#include <stdio.h>
#define LEN 5
struct Person{
char name[21];
char number[18];
};
int main(int argc, const char * argv[]) {
struct Person people[LEN];//定义结构体数组
//利用循环输入联系人信息
for(int i=0;i<LEN;i++){
printf("请输入第%d个人的姓名:电话:\n",i+1);
scanf("%s %s",people[i].name,people[i].number);
}
//打印联系人信息
for (int i =0;i<LEN;i++){
printf("姓名:%s 电话 :%s\n",people[i].name,people[i].number);
}
return 0;
}
三、结构体指针
结构体指针就是用来存放结构体变量地址的指针变量
1结构体指针的定义
struct 结构体名 *变量名
struct Car{
int lunzi;
int speed;
}car1;
struct Car *p = NULL;//定义一个结构体指针变量
p=&car1;//正确 。这里是结构体变量的地址
2结构体指针间接访问成员值
格式(*结构体指针变量).成员 或者结构体指针变量->成员变量
//定义一个结构体
struct Student{
int age;
char*name;
}
//定义一个结构体变量
struct Student stu1 ={18,"三丰"};
//结构体变量访问成员变量
stu1.age 值时18
stu.name 值 张三丰
用结构体指针间接访问
struct Stdent *p=&stu1;
(*p).name 访问年龄
(*p).age 访问姓名
或者 p->name ;
p->age; //p事一个结构体指针
//这里不能用结构体变量stu1->name是错误的。
3,结构体的嵌套
结构体定义中,结构体的成员又是另外一个结构体体变量
结构体的嵌套使用注意:
1)结构体定义可以嵌套其他结构类型的变量
不可以嵌套自己
struct Date{
int year;
int month;
int day;
};
struct Student {
char *name ;
int age ;
float score;
//struct Student stu; 这是错误的 。。
// struct Student *stu;//这是对的。指针调用自己
struct Date birthday;
};
//2)初始化
struct Student stu1={"zhangsanf",25,45.66f,{2015,12,12}};
//结构体嵌套访问
printf("姓名 %s,年龄%d,分数%.2f 生日(%d-%02d-%02d)\n",stu1.name,stu1.age,stu1.score,stu1.birthday.year,stu1.birthday.month,stu1.birthday.day);
4结构体变量作为函数参数
1)用结构体变量成员值作为函数参数,实质是值传递
2)用结构体变量作为函数参数。也是值传递
#include <stdio.h>
struct Car {
int lunzi ;
int speed;
};
void xiuche(struct Car c1){
c1.lunzi =2;
}
void xiuche2(struct Car *car1){
(*car1).lunzi =2
}
int main(int argc , const char *argv[]){
struct Car car1 ={4,100};
xiuche(car1); printf("car1的lunzi数%d\n",car1.lunzi);
//这也是值传递所以car1的*数还是4;
//结构体指针作为函数的参数
xiuche2(&car1);//结构体的地址传递给函数 可以理解为结构体指针作为函数参数
printf("car1的lunzi个数%d\n");
//这样lunzi数改为2.实质是地址传递
return 0;
}
四、枚举类型
枚举类型: c语言提供了一种类型,这种类型的变量值呗限定在一定的范围之内。
枚举的定义:
enum 枚举类型{枚举值1,枚举值2,枚举值3,//枚举变量列表};
enum Weekday {zhouyi,zhouer,zhousan,zhouri,};
enum Sex{SexMan,SexWomen};
//全局变量,局部变量的定义和结构体一样。
枚举类型的变量的定义
1)先定义枚举类型 再定义枚举变量
enum iColor{iColorWhite,iColorbBlock,iColorTHJ}
enum icolor iPhoneColor;
// 这里iPhoneColor的取值有要求 只能取,iColorWhite,iColorbBlock,iColorTHJ
2)定义枚举类型的同时,定义枚举变量
enum iColor{
iColorWhite,
iColorbBlock,
iColorTHJ
}iPhoneColor;
枚举类型变量的初始化
iPhoneColor = iColorBlock;
枚举变量的值
枚举类型定义完成以后,系统会自己给枚举的每一个元素都会赋值一个整型的初值,
默认的初值 从第一个元素开始值为0,以后每个在前一个的基础上+1
五、typedef 关键字的介绍
typede 就是给别人起外号
typedef 原类型名 新类型名
typedef 的用法
1.基本数据类型起别名
int a =4;
typedef int LD;
则 可以 用LD c=4 ; LD就相当与是int
2 用在数组名上
int a[5];
typedef int ARRAY[5];
ARRAY c ={1,2,3,4,5}; 数组长度为 5
3给结构体起别名
strcut Student stu1;
typedef struct Srudent P;//表示给结构体起别名
可以用 p stu2 ={12,"zbz"};
或者 tyedef strcut Car {
int lunzi;
int speed;
}MYCAR;
MYCAR car1={4,200};
4给枚举起别名
typedef enum Sex{SexWomen ,Sexman} ISEX;
ISEX 就是这个枚举类型的别名
ISEX s1,s2; s1=SexWomen; s2=SexMan;
5给函数指针起别名
int(*p)(int,int);
typedef int(*FUN)(int,int); //FUN是个别名
FUN f1,f2; 都是函数的指针
f1 =sum; f2 =jian;