构造类型:也称自定义类型,构造类型是由基本数据类型组成的复合类型。一般用于存储较为复杂的数据。常见的构造类型有结构体(struct)、共用体(union)和枚举(enum)。
目录
正文
一、结构体(struct)
1、结构体概念:
2、定义结构体类型与结构体变量
3、结构体变量的初始化与引用
3、结构体数组
4、结构体指针
*二、共用体(union)
三、枚举类型
四、用typedef声明新的类型名
1、常用的方法有 :
(1、命名一个新的类型名代表结构体
( 2、命名一个新的类型名来代表数组类型
(3、命名一个新的类型来代表指针类型
2、归纳起来,声明一个新的类型的方法是:
总结
结构体是一种用户自定义的数据类型,可以将多个不同类型的变量组合成一个整体,形成一个新的数据类型。结构体中的每一个变量称为成员,可以通过结构体名和成员名来访问。
注意:结构体长度为所有成员变量长度相加
(1)定义一个结构体的一般形式为:
struct 结构体名{成员表列};
// 定义了一个结构体,该结构体由三个系统类型构成
struct MyStruct{
int a;
char c;
a[];
};
struct Struct1{
a[];
struct MyStruct a; // 在定义是成员可以为其他结构体
};
(2)定义结构体变量
// 1、先声明结构体,在定义该类型的变量
struct MyStruct
{
int a;
int b;
};
// 当我们定义完结构体之后,可以直接使用(struct 结构体名)来定义变量
struct MyStruct a,b; // 定义两个类型为struct MyStruct的变量
// 2、在定义结构体的同时定义变量
struct MyStruct
{
int a;
int b;
} a,b; // 定义结构体的同时定义两个结构体变量
// 3、不指定类型名而直接定义结构体类型变量
struct
{
int a;
int b;
} a,b;
(1)在定义结构体变量时可以对它进行初始化。初始化列表是用花括号括起来的一些常量,这些常量的依次赋给结构体中的各成员。
struct Student{
char name[10];
int id;
}a = { "南墙",12}; // 对结构体中所有的元素进行初始化
// 在c99标准允许对某一成员变量进行初始化
struct Student b = {.name = "南墙"}; // 针对结构体中某一项元素进行初始化,在成员名前有成员运算符
(2)在结构体变量中我们可以使用成员操作符'.'来对a中的成员来进行引用,引用方式为:
结构体变量名.成员名
struct Student{
char name[10];
int id;
}a = {.name = "南墙"};
scanf("%s %d",a.name,&a.id); // 引用成员进行输出,注意成员非地址变量是需要添加取址符
printf("%s %d",a.name,a.id);
注意:成员操作符'.'它是所有运算符中优先级最高的,因此可以将a.name看作一个整体;
结构体变量之间可以进行相互赋值,但必须为同类型的结构体变量,如下是正确的:
struct Student {
char name[10];
int id;
}a = { .name = "南墙" }, b;
scanf("%s %d", a.name, &a.id); // 引用成员进行输出,注意成员非地址变量是需要添加取址符
b = a;
printf("%s %d", b.name, b.id);
注意:在结构体变量中的只能对结构体变量中的各个成员进行分别输入和输出:
printf("%s",a); // 这是错误的行为,必须通过引用成员进行输入,输出
当我们需要多个同类型结构体变量是我们可以直接使用结构体数组,用来存储,定义方式:
struct 结构体名 {成员列表} 数组名[数组长度];
结构体类型 数组名[数组长度]; // 注意结构体类型为 : struct 结构体名 {成员列表} 与定义结构体变量第一种方式类似。
struct Student {
char name[10];
int id;
}a[3] = { "南墙",12,"也",13,"撞碎",14 }; // 定义结构体时定义结构体数组,并进行初始化
// struct Student a[3] = {"南墙",12,"也",13,"撞碎",14}; //使用结构体类型名来定义
for (int i = 0; i < 3; i++) {
printf("姓名:%s,id:%d", a[i].name, a[i].id);
}
指向结构体的指针,作用与普通指针类似
struct Student {
char name[10];
int id;
}a = {"南墙",12};
struct Student* p = &a;
printf("姓名:%s,id:%d\n", (*p).name, (*p).id);
为了使用方便和直观,C语言允许把(*p).name用p->num代替。
struct Student {
char name[10];
int id;
}a[3] = { "南墙",12,"也",13,"撞碎",14 };
struct Student* p = a; // 令p指向a
printf("%s %d\n", p->name, p->id); // 将输出a数组首地址的值
for (int i = 0; i < 3; i++) {
printf("姓名:%s,id:%d\n",(p+i)->name,(p+i)->id); // 通过循环来输出a数组中的值
}
当我们想把一个整型变量、一个字符型变量和一个实型变量存放在一个地址中。即可以使用共用体(联合),利用覆盖技术,将后一个数据将覆盖前面一个数据。
注意:共用体的长度,等于共用体成员列表中长度最长的数据类型。
共用体的一般形式为:
union 共用体名{成员列表} 变量表列; // 定义共用体类型与变量和结构体类似
union {
char c;
int b;
}a; // 定义共用体的同时,定义共用体变量
scanf("%d",&a.b); // 输入97
printf("%c",a.c); // 输出'c'
值得注意的是,在共用体中因为不同的类型所占的内存空间不同,在引用时也不会引用超过自身的大小的内存空间。这也导致了,使用内存较大的数据类型存储,在使用内存较小的内存类型进行引用时出现输出结果不准确的情况,通过以下代码我们可以看出不同类型在内存中的存储情况:
union {
char c[4]; // char占1个字节
int b; // 在64为操作系统中int型占4个字节
}a;
puts("请输入一个十六进制数");
scanf("%x",&a.b); // 输入十六进制41424344时
printf("%x %x %x %x", a.c[0],a.c[1],a.c[2],a.c[3]); // 输出结果为:44 43 42 41
枚举类型允许程序员定义一组具有名称和对应整数值的常量。通过枚举类型,程序员可以将一组相关的常量放在一起,提高代码可读性和可维护性。
枚举类型与变量的定义:
enum 枚举类型名 { 枚举常量1, 枚举常量2, ... 枚举常量n } 枚举变量;
枚举类型 枚举变量;
其中,每个枚举常量都是一个标识符,它们的值分别为0、1、2、...、n-1
// 定义枚举类型与枚举变量
enum Weekday {
MONDAY, // 默认值为0
TUESDAY, // 默认值为1
WEDNESDAY, // 默认值为2
THURSDAY, // 默认值为3
FRIDAY, // 默认值为4
SATURDAY, // 默认值为5
SUNDAY // 默认值为6
}day; // 定义枚举变量的方式与结构体类似
printf("%d", day=MONDAY); // 输出结果为0
我们也可以为它们手动指定一个整数值,但是需要注意,在指定值之后,其后面的数据也会同时进行改变。
例如:
enum Weekday {
MONDAY, // 默认值为0
TUESDAY, // 默认值为1
WEDNESDAY=5, // 默认值为2, 修改后为5
THURSDAY, // 默认值为3 修改后为6
FRIDAY, // 默认值为4 修改后为7
SATURDAY, // 默认值为5 修改后为8
SUNDAY // 默认值为6 修改后为9
}day;
day = TUESDAY;
printf("%d\t", day); // 输出1
day = WEDNESDAY;
printf("%d\t", day); // 输出5
day = THURSDAY;
printf("%d\t", day); // 输出6
在C语言中除了可以直接使用C提供的标准类型名(如int、float、char等)和自己声明的结构体、共用体、枚举类型外,还可以使用typedef指定新的类型名来代替已有的类型名。
例如:
typedef int INT;
INT a; // ==> int a;
typedef struct Student {
char name[10];
int id;
}student; // 表示使用student来代替struct Student来作为类型名
// typedef struct Student student; // 也可以定义完之后再使用typedef
student stu; // 定义一个类型为struct Student的结构体类型变量
strcpy(stu.name,"南墙");
stu.id = 15;
printf("%s %d",stu.name,stu.id);
typedef int Num[100];
Num a;
printf("%d",sizeof(a)); // 输出:400 64为操作系统int站四个字节
typedef int Num[100];
Num a; // 定义长度为100的数组
typedef int* Pointer;
Pointer p, s[10]; // p为整型指针,s为整型指针数组
a[0] = 10;
s[0] = a;
p = a;
printf("%d %d", *p,*s[0]); // 输出:10 10
以命名一个新的类型名来代表数组类型为例:
1、先按定义数组的类型变量形式书写:int a[100];
2、将变量名a换成自己命名的类型名:int Num[100];
3、在前面加上typedef,得到:typedef int Num[100];
4、使用自己命名的类型名定义变量:Num b; //定义一个长度为100的数组
本文主要记录了C语言中的构造类型与自定义类型名的方法。