结构体和共用体
注:本文为学习《C语言从入门到精通》时,对部分章节的总结
1、结构体
1.1、结构体类型的概念
结构体是一种构造类型,由若干成员组成。成员可以是一个基本数据累心,也可以是一个构造类型。
struct 结构体名 {
成员列表
};
关键字struct表示声明结构,其后的结构已经表示该结构的类型名。
1.2、结构体变量的定义
a、先声明结构体类型,在定义变量
struct Student {
char name[20];
unsigned int age;
}; // 声明结构体
struct Student student1; // 定义一个结构体
构造类型 变量名、
b、在声明结构类型时,同时定义变量
struct结构体名 {
成员列表
}变量名列表;
struct Student {
char name[20];
unsigned int age;
} student1, student2;
c、直接定义结构体类型变量
struct {
成员列表
} 变量名列表;
struct {
char name[20];
unsigned int age;
} student1, student2;
1.3、结构体变量的引用
结构变量名.成员名
比如:
student1.name = “zhangsan”;
student2.age = 18;
1.4、结构体类型的初始化
struct Student {
char name[20];
unsigned int age;
}student1 = {“zhangsan”, 18};
struct Student student2 = {“wangwu”, 22};
2、结构体数组
2.1、定义结构体数组
struct 结构体名 {
成员列表;
} 数组名;
2.2、初始化结构体数组
struct 结构体名 {
成员列表;
} 数组名 = {初始化列表};
3、结构体指针
3.1、指向结构体变量的指针
结构体类型 *指针名;
例如:
struct Student *pStudent;
使用方式有两种:a、(*pStudent).成员名
b、PStudent->成员名
3.2、指向结构体数组的指针
3.3、结构体作为函数参数
4、包含结构的结构
5、链表
5.1、链表概述
5.2、创建动态链表
a、malloc函数
void *malloc(unsigned int size);
功能:在内存中动态地分配一块size大小的内存空间,返回一个指向分配的内存的指针,分配控件错误时,返回NULL
b、calloc函数
void *calloc(unsigned int n, unsigned int size);
功能:在内存中动态地分配n个长度为size的连续内存空间数组,返回一个指向分配的连续内存的指针,分配控件错误时,返回NULL
c、free函数
void free(void *ptr);
功能:使用由指针ptr指向的内存区,是部分内存区能被其它变量使用。
typedef struct Student {
char name[20]; //姓名
unsigned int num; //学号
struct Student* next; //指向下一个节点
} Student;
unsigned int count; //链表长度
//创建链表
Student* CreateList()
{
Student* head = NULL; //初始化链表头
Student* newList = NULL;
Student* endList= (Student*)malloc(sizeof(Student));
if (endList == NULL) {
return NULL;
}
newList = endList;
count = 0; //初始化链表长度
if (scanf("%s %u", newList->name, &newList->num) == EOF) {
return NULL;
}
while (newList->num != 0) {
count++;
if (count != 1) {
newList->next = NULL;
endList->next = newList;
endList = newList;
} else {
newList->next = NULL;
head = newList;
}
newList = (Student*)malloc(sizeof(Student));
if (newList == NULL) {
return head;
}
if (scanf("%s %u", newList->name, &newList->num) == EOF) {
return head;
}
}
free(newList);
newList = NULL;
return head;
}
5.3、输出链表
//遍历链表
//head:头指针
void PrintList(Student* head)
{
Student* tmp = head;
unsigned int index = 1;
while (tmp != NULL) {
printf("[member %u] [name %s] [num %u]\n", index, tmp->name, tmp->num);
tmp = tmp->next;
index++;
}
}
6、链表相关操作
6.1、链表的插入操作
链表的插入操作可以再链表的头结点、中间、和尾结点后
//链表头插法
//head:头指针
unsigned int Insert(Student* head)
{
Student* newNode = (Student*)malloc(sizeof(Student*));
if (newNode == NULL) {
return 1; //插入失败
}
if (scanf("%s %u", newNode->name, &newNode->num) == EOF) {
return 1;
}
newNode->next = head;
head->next = newNode;
count++;
return 0;
}
6.2、链表的删除操作
//删除某个节点
//head:头指针
//index:需要删除的节点下标
unsigned int Delete(Student* head, unsigned int index)
{
Student* pre = head; //需要删除的节点的前一个节点
if (index > count || index == 0) {
return 1;
}
while (index--) {
pre = pre->next;
}
Student* tmp = pre->next;
pre->next = tmp->next;
free(tmp);
tmp = NULL;
count--;
return 0;
}
//清空链表
//head:头指针
void ClearList(Student* head)
{
Student* tmp = head;
Student* p = tmp->next;
while (p) {
free(tmp);
tmp = p;
p = tmp->next;
}
}
7、共用体
共用体和结构体类似,关键字换成了union。
区别:结构体:定义了一个有多个数据成员组成的特殊类型
共用体:定义了一块为所有数据成员共享的内存
7.1、共同体的概念
共用体也称联合体,使所用成员变量存放在同一段内存中,所以共用体在同一时刻只能有一个值,它属于某一个数据成员。共同体的大小等于最大的成员大小
union 共用体名 {
成员列表
} 变量列表;
7.2、共用体变量的引用
共用体变量.成员名;
7.3、共用体变量的初始化
定义共用体变量时,可以同时进行初始化。初始化时,只需要一个初始化值就可以,其类型必须和共用体第一个成员类型一致;如果第一个成员类型为结构体,则初始化值为一组值。
8、枚举类型
利用关键字enum声明枚举类型,可以定义枚举类型变量,一个枚举变量包含一组相关的标识符(必须是唯一的),每个标识符对应一个整数值,称为枚举常量。
enum Colors {Red, Green, Blue};
Colors为枚举变量,括号中的第一个标识符(Red)对应数值0,第二个(Green)对应1,以此类推。