为什么在C语言引入结构体:
基本数据类型可以定以各种基本数据
数组可批量处理相同类型的数据
指针可以处理空间的地址
如何同时处理不同数据类型的数据 ---- 通过结构通
可以将结构体理解为不同数据类型的集合
结构体关键字:struct
结构体的定义:
在C语言中,结构体(struct)指的是一种数据结构,是C语言中复合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。
结构体是编译器预留给开发人员自行定义的一种数据结构,开发人员可以根据自己的设计需求在结构体内部声明需要的结构体成员
结构体的定义:
结构体的定义格式可以分为三种:
定以数据结构不占用空间
第一种:无名结构体
struct {
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
};
提示:
无名结构体只能在定以结构体的同时定以结构体变量,之后不能在通过已经定义
的无名结构体定义一个结构体变量
无名结构体定义结构体变量的格式:
struct {
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}VarName1,VarName2,VarName.......;
一个人拥有以下的基本信息:姓名、年龄、性别、身份证号
struct {
char name[20];
int age;
char sex;
char idcard[18];
}person1,person2,*person3;
格式二:有名结构体
struct StructName{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
};
提示:
有名结构体不但可以在定以结构体的同时定以结构体变量,还能在通过已经定义
的有名结构体定义一个结构体变量
有名结构体定义结构体变量的格式:
格式一:
struct MyStruct{
DataType1 value1;
DataType2 value2;
DataType3 value3;
…
}VarName1,VarName2,VarName…;
格式二:
struct MyStruct VarName1,VarName2,.....;
基本信息:姓名、年龄、性别、身份证号
struct Person{
char name[20];
int age;
char sex;
char idcard[18];
}person1,person2;
struct Person person3;
struct Person *person4;
格式三:重定义结构体
typedef struct [MyStruct]{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}NewStructType,*pNewStructType;
[]括起来的部分标识可有可无
NewStructType:被重定义的新的结构体类型名,后期可以直接使用此类型定以结构体的
变量
pNewStructType:被重定义的新的结构体指针名,后期可以直接使用此类型定以结构体的
指针变量
有名结构体定义结构体变量的格式:
typedef struct [MyStruct]{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}NewStructType,*pNewStructType;
格式:
NewStructType VarName1,VarName2,VarName.......;//此处为结构体普通变量
pNewStructType VarName1,VarName2,.....; //此处为结构体指针变量
基本信息:姓名、年龄、性别、身份证号
typedef struct Per{
char name[20];
int age;
char sex;
char idcard[18];
}Person,*pPerson;
Person person1; // 等同于struct Per person1;
pPerson *person2;// 等同于struct Per *person2;
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}Per,*pPer;
//typedef (struct Person) Per;
//typedef (struct Person *) pPer;
int main()
{
Per person; //定义了一个结构体变量
//等同于struct Person person;
pPer pPerson;//定义了一个结构体之怎指针变量
//等同于struct Person *person;
system("pause");
return 0;
}
结构体成员的访问方式:
第一种:
除指针以外的结构体变量访问结构体内部的成员通过.的方式
格式:
typedef struct [MyStruct]{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}NewStructType,*pNewStructType;
格式:
NewStructType VarName1,VarName2,VarName.......;//此处为结构体普通变量
VarName1.value1;
第二种:z结构体指针变量访问结构体内部成员通过->
格式:
typedef struct [MyStruct]{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}NewStructType,*pNewStructType;
格式:
pNewStructType VarName1;
VarName1->value1;
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}Per,*pPer;
//typedef (struct Person) Per;
//typedef (struct Person *) pPer;
int main()
{
Per person; //定义了一个结构体变量
//等同于struct Person person;
pPer pPerson=&person;//定义了一个结构体之怎指针变量
//等同于struct Person *person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person.name, person.age, person.sex,\
person.idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
pPerson->name, pPerson->age, pPerson->sex, \
pPerson->idcard);
system("pause");
return 0;
}
结构体初始化:
格式:
typedef struct [MyStruct]{
DataType1 value1;
DataType2 value2;
DataType3 value3;
...............
}NewStructType,*pNewStructType;
全部初始化格式:
NewStructType VarName1={value,value,value......},
VarName2={value,value,value......},
VarName={value,value,value......}.......;
//此处为结构体普通变量
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}Per,*pPer;
//typedef (struct Person) Per;
//typedef (struct Person *) pPer;
int main()
{
Per person = {
"张三",25,'m',"11010119800110999"
}; //定义了一个结构体变量
//等同于struct Person person;
pPer pPerson=&person;//定义了一个结构体之怎指针变量
//等同于struct Person *person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person.name, person.age, person.sex,\
person.idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
pPerson->name, pPerson->age, pPerson->sex, \
pPerson->idcard);
system("pause");
return 0;
}
局部初始化:
NewStructType VarName1={value,value,value},
VarName2={value,value,value},
VarName={value,value,value}.......;
//此处为结构体普通变量
结构体的初始化和数组的初始化顺序一致,都是从最前面开始向后初始化,如果想要有
针对性的初始化,可通过一下方式
指定初始化:
NewStructType VarName1={
.value3=value;
.value8=value;
},
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}Per,*pPer;
//typedef (struct Person) Per;
//typedef (struct Person *) pPer;
int main()
{
Per person = {
.name="张三",
//.age=25,
//.sex='m',
.idcard="11010119800110999",
}; //定义了一个结构体变量
//等同于struct Person person;
pPer pPerson=&person;//定义了一个结构体之怎指针变量
//等同于struct Person *person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person.name, person.age, person.sex,\
person.idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
pPerson->name, pPerson->age, pPerson->sex, \
pPerson->idcard);
return 0;
}
结构体成员赋值:
和普通变量一样
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}Per,*pPer;
//typedef (struct Person) Per;
//typedef (struct Person *) pPer;
int main()
{
Per person = {
"张三",25,'m',"11010119800110999"
}; //定义了一个结构体变量
//等同于struct Person person;
scanf("%s", person.name);
pPer pPerson=&person;//定义了一个结构体之怎指针变量
//等同于struct Person *person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person.name, person.age, person.sex,\
person.idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
pPerson->name, pPerson->age, pPerson->sex, \
pPerson->idcard);
system("pause");
return 0;
}
结构体的大小:
通过sizeof计算可得
struct Person
{
char name[20];
int age;
char sex;
char idcard[18];
}
结构体:
和数组的关系
结构体也是一种数据类型结构体,所以可以定义结构体数组
和指针的关系
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#pragma pack (1)
typedef struct Person
{
char name[20];
char sex;
int age;
char idcard[18];
}Per,*pPer;
int main()
{
pPer p=NULL;
Per person[2] = {
{"张三",'f',25,"123456789"},{ "李四",'m',28,"9876543210" }
};
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person[0].name, person[0].age, person[0].sex, \
person[0].idcard);
p = person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
p[1].name, p[1].age, p[1].sex, \
p[1].idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
(p+1)->name, (p + 1)->age, (p + 1)->sex, \
(p + 1)->idcard);
system("pause");
return
0;
}
定义结构体变量一定会分配空间,但是定义结构体指针一定没有空间
相同类型的结构体之间可以进行赋值操作
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#pragma pack (1)
typedef struct Person
{
char name[20];
char sex;
int age;
char idcard[18];
}Per,*pPer;
int main()
{
pPer p=NULL;
Per per;
Per person[2] = {
{"张三",'f',25,"123456789"},{ "李四",'m',28,"9876543210" }
};
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person[0].name, person[0].age, person[0].sex, \
person[0].idcard);
p = person;
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
p[1].name, p[1].age, p[1].sex, \
p[1].idcard);
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
(p+1)->name, (p + 1)->age, (p + 1)->sex, \
(p + 1)->idcard);
per = person[0];
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
per.name, per.age, per.sex, \
per.idcard);
system("pause");
return
0;
}
和函数的关系
结构体可以作为形参也可以做返回值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#pragma pack (1)
typedef struct Person
{
char name[20];
char sex;
int age;
char idcard[18];
}Per,*pPer;
void Print(Per person[5])
{
printf("name:%s\tage:%d\tsex:%c\tidcard:%s\n", \
person[0].name, person[0].age, person[0].sex, \
person[0].idcard);
printf("size:%lu\n", sizeof(person));
}
int main()
{
pPer p=NULL;
Per per;
Per person[2] = {
{"张三",'f',25,"123456789"},{ "李四",'m',28,"9876543210" }
};
Print(person);
system("pause");
return 0;
}
共用体:
在计算机科学中,联合体(英语:union)又名共用体,是一种具有多个类型或格式的值,或者把它定义为一种由具有这样的值的变量形成的数据结构。一些编程语言可以支持被称为“联合体”的特殊的资料类型,来表示上述的变量。换句话说,一个联合体的定义(definition)会指定一些允许的可以存储在实例内的原始数据类型(例如整型,浮点)。和记录(record)(或结构,structure)那些可以被定义去包含一个浮点数或整型不同的是,在一个联合体任何时候只有一个值
共用体:内部所有成员公用一个空间的数据结构
共用体的关键字:
union
共用体的定义:
同结构体,将struct更改为union
共用体成员的访问:
同结构体,将struct更改为union
区别:
空间大小:
结构体空间是所有成员的空间之和(遵循字节对齐)
共用体的空间大小为包含成员中最大的空间(遵循字节对齐)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef union Person
{
char name[22];
char sex;
int age;
char idcard[18];
}Per,*pPer;
int main()
{
printf("size:%lu\n", sizeof(Per));
system("pause");
return 0;
}
赋值:
结构体可以针对内部不同的成员进行赋值操作,各个成员之间没有相互的干扰。
公用体赋值操作会进行覆盖,后面的赋值会覆盖掉前面的赋值
注意:当进行连续输入操作且中间存在对字符进行输入操作的时候,需要进行空格的消除(吸收回车)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef union Person
{
char name[22];
char sex;
int age;
char idcard[18];
}Per,*pPer;
int main()
{
Per ion;
scanf("%s", ion.name);
scanf("%s", ion.idcard);
getchar();
scanf("%c", &ion.sex);
printf("%s\n", ion.name);
printf("size:%lu\n", sizeof(Per));
system("pause");
return 0;
}
枚举:
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。
枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。
注意:结构体和公用体内部是变量,枚举是常量
枚举的说明与结构和联合相似,其形式为:
enum 枚举名{
标识符①[=整型常数],
标识符②[=整型常数],
...
标识符N[=整型常数],
}枚举变量;
如果枚举没有初始化,即省掉"=整型常数"时,则从第一个标识符开始,顺次赋给标识符0,1,2,3…,但当枚举中的某个成员赋值后,其后的成员按依次加1的规则确定其值。例如下列枚举说明后x1, x2, x3, x4的值分别为0 1 2 3
enum string{x1, x2, x3, x4}x;
当定义改变为:
enum string
{
x1,
x2=0,
x3=50,
x4,
}x;
x1=0, x2=0, x3=50, x4=51
注意:
枚举中每个成员(标识符)结束符是",", 不是";",最后一个成员可省略","。
初始化时可以赋负数,以后的标识符仍依次加1。
枚举变量只能取枚举说明结构中的某个标识符常量
enum string
{
x1=5,
x2,
x3,
x4,
};
enum string x=x3;
//此时,枚举变量x3实际上是7。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
enum week {
SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY
};
int main()
{
enum week var;
scanf("%d", &var);
switch (var)
{
case SUNDAY:printf("Today is SUNDAY\n"); break;
case MONDAY:printf("Today is MONDAY\n"); break;
case TUESDAY:printf("Today is TUESDAY\n"); break;
case WEDNESDAY:printf("Today is WEDNESDAY\n"); break;
case THURSDAY:printf("Today is THURSDAY\n"); break;
case FRIDAY:printf("Today is FRIDAY\n"); break;
case SATURDAY:printf("Today is SATURDAY\n"); break;
}
system("pause");
return 0;
}
枚举内部只能是标识符
枚举类型,指一个被命名的整型常数的集合。即枚举类型,本质上是一组常数的集合体,只是这些常数有各自的命名。枚举类型,是一种用户自定义数据类型。
枚举变量,由枚举类型定义的变量。枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以
枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节),枚举类型所占内存大小也是这样。