结构 struct
由多个数据类型组成的数据类型
关键词struct
声明格式类似int 即在结构类型后填写变量名
访问时使用成员运算符.字段名
#include<stdio.h>
#include<string.h>
int main()
{
struct {
char name[20];
int gender;
double height;
double weight;
}timmy;
//将timmy的数据装入结构变量
strcpy(timmy.name, "timmy");
timmy.gender = 1;
timmy.height = 170.00;
timmy.weight = 60;
//从结构变量中显示timmy的数据
printf("%s\n", timmy.name);
printf("%d\n", timmy.gender);
printf("%.2f\n", timmy.height);
printf("%.2f\n", timmy.weight);
}
结构别名
如果要定义多个内部成员一致的结构变量 则可以只声明一次结构类型 结构类型声明取一个别名 放在struct后面 相当于造了一个模板 后续声明该结构类型的变量时只需struct加别名
但如果结构类型声明在一个函数中 那么别名只能在函数内部使用 如果需要在多个函数中使用结构别名 则需要把它放在函数外面
struct person{
char name[20];
int gender;
double height;
double weight;
};
struct person timmy;
struct person david;
初始化结构
可在声明时初始化 类似数组初始化 在声明时加等号与初始化列表
- 初始化列表由花括号包括
- 花括号内为结构成员需要被初始化的值
- 初始化值按照结构成员声明时的顺序依次排列
- 每个初始化值之间用逗号分隔
struct person timmy = {"timmy",1,170.00,60.00};
结构数组
结构类型+[元素个数]
struct person people[3];
可用初始化列表初始化数组 模式如下
struct person people[3] = {
{"timmy",1,170.00,60.00},
{"david",1,175.00,65.00},
{"jane",2,165.00,55.00}
};
也可以对结构使用赋值
struct person per = people[i];
也可以用结构初始化结构
struct person per;
per = people[i];
方括号加下标访问结构数组中的元素
people[i]
嵌套结构
把结构作为结构的成员
#include<stdio.h>
#include<string.h>
int main()
{
struct contact {
char phone[20];
char email[20];
};
//通讯方式为结构的第五个成员
struct person{
char name[20];
int gender;
double height;
double weight;
struct contact c;
};
//在人员初始化列表的第五个位置填写通讯方式的初始化列表
struct person timmy = {
"timmy",1,170.0,60.00,{"12345678912","timmy@xxx.com"}
};
//.字段名访问元素
printf("%s\n", timmy.name);
printf("%d\n", timmy.gender);
printf("%.2f\n", timmy.height);
printf("%.2f\n", timmy.weight);
printf("%s\n", timmy.c.phone);
printf("%s\n", timmy.c.email);
return 0;
}
指向结构的指针
//声明
struct person* ptimmy = &timmy;
//使用时可先把指针转化成结构再使用
printf("%s\n", (* ptimmy).name);//成员运算符.高于取值运算符* 因此要用()包括
使用成员间接运算符->更简便
(* ptimmy).name等价于ptimmy->name
printf("%s\n", ptimmy->name);
结构在函数中传递
不同函数中的参数相互独立 因此要通过指针实现传递与修改
#include<stdio.h>
#include<string.h>
struct person{
char name[20];
int gender;
double height;
double weight;
};
void change(struct person*per)
{
strcpy(per->name, "david");
per->gender = 1;
per->height = 175.00;
per->weight = 65.00;
}
int main()
{
struct person timmy = { "timmy",1,170.00,60.00 };
change(&timmy);//将timmy的指针传入change函数
printf("%s\n", timmy.name);
printf("%d\n", timmy.gender);
printf("%.2f\n", timmy.height);
printf("%.2f\n", timmy.weight);
return 0;
}
将结构从函数中返回然后赋值给timmy也可以
#include<stdio.h>
#include<string.h>
struct person{
char name[20];
int gender;
double height;
double weight;
};
struct person change()
{
struct person per;
strcpy(per.name, "david");
per.gender = 1;
per.height = 175.00;
per.weight = 65.00;
return per;//函数返回结构per
}
int main()
{
struct person timmy = { "timmy",1,170.00,60.00 };
timmy=change();//把函数返回的结构赋值给timmy
printf("%s\n", timmy.name);
printf("%d\n", timmy.gender);
printf("%.2f\n", timmy.height);
printf("%.2f\n", timmy.weight);
return 0;
}
联合 union
关键词union
声明类似struct 但联合中成员首地址是重叠的 共用一段内存 因此联合的大小为联合中最大成员的大小
性质
储存一个成员后 将覆盖其他成员的数据 因此联合也被称为共用
#include<stdio.h>
#include<string.h>
int main()
{
union {
char c;
short s;
long long ll;
}u;
u.c = 123;
printf("u.c=%d\n", u.c);//u.c=123
u.s = 0;
printf("u.c=%d\n", u.c);//u.c=0
}
应用举例
有一个信息有三种形式 整数 浮点数 字符串 如果使用结构 则需要准备三个不同类型的成员 每次只出现一种形态 所以每次只使用一个成员 另外两个留空 占用内存较大 另外需要整型成员type来标记类型
此时可以使用union将三个不同类型的成员合三为一 同时使用type标记类型
#include<stdio.h>
#include<string.h>
struct message
{
int type;
union {
int n;
double f;
char* str;
}u;
};
void printmsg(struct message msg)
{
switch (msg.type)
{
case 1:
printf("%d\n", msg.u.n);
break;
case 2:
printf("%f\n", msg.u.f);
break;
case 3:
printf("%s\n", msg.u.str);
break;
}
}
int main()
{
struct message msg[3];
msg[0].type = 1;
msg[0].u.n = 123;
msg[1].type = 2;
msg[1].u.f = 3.14;
msg[2].type = 1;
msg[2].u.str = "helloworld";
for (int i = 0; i < 3; i++)
printmsg(msg[i]);
return 0;
}
还有一种匿名嵌套的写法 即省略union的成员名u union中的成员当作message的成员一样处理
struct message
{
int type;
union {
int n;
double f;
char* str;
};//省去成员名u 作为匿名嵌套成员
};
void printmsg(struct message msg)
{
switch (msg.type)
{
case 1:
printf("%d\n", msg.n);//msg.u.n省略为msg.n
break;
case 2:
printf("%f\n", msg.f);//msg.u.f省略为msg.f
break;
case 3:
printf("%s\n", msg.str);//msg.u.s省略为msg.s
break;
}
}
枚举 enum
关键词enum
一种特殊的整型 枚举类型 关键词为enum
把数字123用有意义的英文替代 比如1对应integer 2对应float
声明类似struct
枚举是特殊的整型
//枚举从0开始依次递增
#include<stdio.h>
#include<string.h>
enum msgtype
{
einteger,
efloat,
estring
};
int main()
{
printf("%d\n", einteger);//0
printf("%d\n", efloat);//1
printf("%d\n", estring);//2
return 0;
}
如果要从1开始递增 只需在einteger后加=1
也可以指定每一个枚举中每个成员对应的数值
应用举例
#include<stdio.h>
#include<string.h>
enum msgtype
{
einteger,
efloat,
estring
};
//用枚举代替数字
struct message
{
enum msgtype type;
union {
int n;
double f;
char* str;
}u;
};
//拿到信息后判断是哪一个枚举值
void printmsg(struct message msg)
{
switch (msg.type)
{
case einteger:
printf("%d\n", msg.u.n);
break;
case efloat:
printf("%f\n", msg.u.f);
break;
case estring:
printf("%s\n", msg.u.str);
break;
}
}
//使用枚举进行赋值
int main()
{
struct message msg[3];
msg[0].type = einteger;
msg[0].u.n = 123;
msg[1].type = efloat;
msg[1].u.f = 3.14;
msg[2].type = estring;
msg[2].u.str = "helloworld";
for (int i = 0; i < 3; i++)
printmsg(msg[i]);
return 0;
}