结构
为什么需要结构体
c语言后很多类型 比如 char short int double float long long
再例如比较难的 数组 指针类型
但是你会发现 这些类型都是定死的 就是说int 就是int 不能再放别的
int[] 的数组中只能放 int 的数据
char name[20]
short sex
int weight
double height
但是这很明显 很难满足某些需求 例如人员信息 有身高int 有姓名char[] 有体重int…
我们想要一种 能够直接把多种数据综合起来的数据结构
于是就有了 struct{} 的结构
struct {
char name[20]
short sex
int weight
double height
}
这一大坨就是一个类型 和int 等价
结构体的构建
1.首先 需要struct关键词来声明
2.需要 {} 包裹 里面存放这要存储的数据
3.包裹的数据和正常的数据声明一样 比如姓名 char [20] 是一个char[]的字符串
4.数据要有;结尾
struct {
char name[20];
short sex;
int weight;
double height;
}
结构体的声明
例如 int a; 类型 名字
类型 名字
struct {
char name[20]
short sex
int weight
double height
} people;
结构体数组的声明
和正常数组一样
int a[];
用struct 和int是等价的
struct {
char name[20]
short sex
int weight
double height
} people[20];
创建一个结构体的数组 里面的类型就是 struct
访问和赋值结构体数据
通过 . 访问
struct {
char name[20]
short sex
int weight
double height
} people;
people.name
people.sex
people.weight
people.height
people.name="娃哈哈"
strcpy(people.name, "Timmy");
people.sex=1
people.weight=23
people.height=56
之后会有->的访问 简单提一下那是指针的替代 等价 (*people).name people->name
访问和赋值结构体数组数据
通过 [] 和 . 访问
struct {
char name[20]
short sex
int weight
double height
} people[20];
people[0].name
people[0].sex
people[0].weight
people[0].height
people[0].name="娃哈哈"
strcpy(people.name, "Timmy");
people[0].sex=1
people[0].weight=23
people[0].height=56
输入和输出结构体的数据
struct {
char name[20];
int gender;
double height;
double weight;
}arr[10];
int numOfPerson=0;
scanf("%s %d %lf %lf", &arr[numOfPerson].name, &arr[numOfPerson].gender, &arr[numOfPerson].height,&arr[numOfPerson].weight)
把输入的数据 赋值给结构体数组arr 的第numOfPerson的数据
为什么要用& 因为scanf 是一个函数 函数的实参和形参是不一样的
这就一意味着函数无法改变外部的值
所以需要 & 把指针也就是地址传递进去 这样函数就能修改外部的值
把输入的数据给外部arr
//控制台输入数据到结构体 scanf(“%s %d %lf %lf”, &arr[numOfPerson].name, &arr[numOfPerson].gender, &arr[numOfPerson].height,&arr[numOfPerson].weight) 把输入的数据 赋值给结构体数组arr 的第numOfPerson的数据
为什么要用& 因为scanf 是一个函数 函数的实参和形参是不一样的 这就一意味着函数无法改变外部的值 所以需要 & 把指针也就是地址传递进去 这样函数就能修改外部的值 把输入的数据给外部arr
输出
int i=0;
printf("%s %d %.2f %.2f\n", arr[i].name, arr[i].gender, arr[i].height, arr[i].weight)
结构别名
创建多个结构体
struct {
char name[20];
int gender;
double height;
double weight;
}timmy;
struct {
char name[20];
int gender;
double height;
double weight;
}david;
如果要声明2个结构体变量 就需要一个 声明2次
而且 结构体长得一样
所以我们需要一种通用的方式
所以出现了结构体别名 避免重复的写结构体代码
struct person{
char name[20];
int gender;
double height;
double weight;
};
person就是别名 和int的类型起到了同样的效果
struct person david;
struct person jane;
struct{
char name[20];
int gender;
double height;
double weight;
} user;
和
struct user{
char name[20];
int gender;
double height;
double weight;
};
struct user zhangsan1;
struct user zhangsan2;
struct user zhangsan3;
如果结构类型声明在一个函数中,那么别名只能在函数内部使用。
void func1()
{
struct person{
char name[20];
int gender;
double height;
double weight;
};
struct person timmy;
}
void func2()
{
struct person david;
}
函数 func1 声明了一个结构类型,它的别名为 person 。并且使用别名声明了一个结构变量 timmy 。
函数 func2 中,使用别名 person ,声明另一个结构变量,但是别名 person 无法在函数 func2 中使用,
因此将编译报错。
如果需要在多个函数中使用结构别名,那么可以把它放到函数外面
struct person{
char name[20];
int gender;
double height;
double weight;
};
void func1()
{
struct person timmy;
}
void func2()
{
struct person david;
}
初始化结构
初始化:
\1. 初始化列表由花括号包括。
\2. 花括号内为结构成员需要被初始化的值。
\3. 初始化值按照结构成员声明时的顺序依次排列
\4. 每个初始化值之间由逗号分隔。
struct people{
char name[20]
char sex
double weight
double height
};
struct people zhangsan={"张三",'N',72,180};
printf("%s\n", zhangsan.name);
printf("%d\n", zhangsan.gender);
printf("%.2f\n", zhangsan.height);
printf("%.2f\n", zhangsan.weight);
结构体数组初始化
struct person{
char name[20];
int gender;
double height;
double weight;
};
struct person people[3] = {
{"timmy", 1, 170.00, 60.00},
{"david", 1, 175.00, 65.00},
{"jane", 2, 165.00, 55.00}
};
for(int i = 0; i < 3; i ++)
{
struct person per = people[i];
printf("%s ", per.name);
printf("%d ", per.gender);
printf("%.2f ", per.height);
printf("%.2f\n", per.weight);
}
初始化列表也可用于初始化结构数组,初始化列表中依次填每个结构的初始化列表,每个结构的初始化
列表之间由逗号分隔。
{
{"timmy", 1, 170.00, 60.00},
{"david", 1, 175.00, 65.00},
{"jane", 2, 165.00, 55.00}
};
嵌套结构体
当一个结构体 里面值包含另一个结构体
比如 联系方式{手机 email qq 微信}
人 {姓名 性别 年龄 联系方式}
在人的结构体中包含了 联系方式的结构体
struct contact {
char phone[20];
char email[20];
};
struct person{
char name[20];
int gender;
double height;
double weight;
struct contact c;
};
初始化嵌套结构体
struct person zhangsan = {
"张三", 1, 170.00, 60.00,
{"130123456678", "timmy@xxx.com"}
};
结构的指针
指针可以指向基本数据类型或者是数组。当然可以指向结构体
struct person{
char name[20];
int gender;
double height;
double weight;
};
struct person zhangsan = {"张三", 1, 170.00, 60.00};
struct person *pzhangsan = &zhangsan;
对于指针 *指针变量 可以根据地址取值
printf("%s\n", (*pTimmy).name);
printf("%d\n", (*pTimmy).gender);
printf("%.2f\n", (*pTimmy).height);
printf("%.2f\n", (*pTimmy).weight);
由于成员运算符 . 的优先级高于取值 * 。为了让取值 * 先运算符,必须使用括号 *pTimmy 包括。
另外,C****语言中提供了更加方便的写法,成员间接运算符 -> 。
(*pTimmy).name 等价于 pTimmy->name 。
printf("%s\n", pTimmy->name)
printf("%d\n", pTimmy->gender)
printf("%.2f\n", pTimmy->height)
printf("%.2f\n", pTimmy->weight)
结构在函数中传递
struct person{
char name[20];
int sex;
double height;
double weight;
};
void change(struct person per)
{
strcpy(per.name, "zhangsanwasn");
per.sex = 1;
per.height = 175.00;
per.weight = 65.00;
}
int main()
{
struct person zhangsan = {"zhangsan", 1, 170.00, 60.00};
change(zhangsan);
printf("%s\n", zhangsan.name);
printf("%d\n", zhangsan.gender);
printf("%.2f\n", zhangsan.height);
printf("%.2f\n", zhangsan.weight);
return 0;
}
由于实参 zhangsan与实参 per 是相互独立的。修改函数 change 内的 per 无法改动实参 zhangsan。
使用指针当传递结构体
struct person{
char name[20];
int sex;
double height;
double weight;
};
void change(struct person *per)
{
strcpy((*per).name, "zhangsanwasn");
(*per).sex = 1;
(*per).height = 175.00;
(*per).weight = 65.00;
strcpy(per->name, "zhangsanwasn");
per->sex = 1;
per->height = 175.00;
per->weight = 65.00;
}
int main()
{
struct person zhangsan = {"zhangsan", 1, 170.00, 60.00};
change(&zhangsan);
printf("%s\n", zhangsan.name);
printf("%d\n", zhangsan.gender);
printf("%.2f\n", zhangsan.height);
printf("%.2f\n", zhangsan.weight);
return 0;
}
|