在c语言表针中有多种数据类型,他们的应用使变量的应用变得灵活多变。而除了c语言默认的int ,float ...等类型外,我们还可以自己定义一些数据的类型,结构体类型便是可以实现数据类型自定义的类型。
结构体是一种类型,他的应用和int,float等变量类型的应用方法一致,切记,结构体是一种类型,不可当作变量进行使用。
在结构体类型使用时要先进行结构体类型的定义。例如
#include<>
struct student
{
int num;
char name[20];
int score[3];
int aver;
};
这便是定义了一个结构体类型。结构体的定义必须应用struct关键词,关键词后紧跟着的是结构体名,然后在这个结构体中有四个成员,分别是 整形类型的变量num,字符型数组 name[20],整形数组 score[3], 整形类型变量aver,这就完成了一个结构体类型的定义。此时这个结构体类型是 struct student ,在应用时就以这个结构体类型来定义结构体变量。注意,结构体是类型,不是变量,不能直接应用,要定义一个结构体变量才能应用。换句话说,花了一个图纸不等于盖了一栋房子,图纸还只是图纸,仍旧需要砖瓦来盖大楼。例如
#include<>
struct student
{
int num;
char name[20];
int age;
int score;
};
int main()
{
struct student student1={0,name,0,0};
struct student student2={0};
}
在以上例子中,在main函数中定义了两个结构体变量,分别是 student1 和 student2 ,他们的类型是struct student,这就完成了结构体变量的定义,再定义后可以进行初始化,例子中的花括号中的内容就是初始化的内容。如果只初始化了一部分内容,则剩余的部分的结构体成员均被编译器自动初始化为 0。
既然定义了一个结构体,那么如何应用一个结构体呢?其实结构体变量的应用和我们平常所使用的变量没有太大的区别,只是换了一种访问的方式。例如
#include<>
int main()
{
struct stduent
{
int num;
char name[20];
int age;
int score;
};
struct student student1 = { 0, name, 0, 0};
struct student student2 = { 0 };
printf("Plase input stduent1:\n");
scanf("%d%s%d%d", &, , &, &);
printf("Plase input stduent2:\n");
scanf("%d%s%d%d", &, , &, &);
if ( > )
{
printf("stduent1 :\n%d\n%s\n%d\n%d\n", , , , );
}
else if ( < )
{
printf("stduent2 :\n%d\n%s\n%d\n%d\n", , , , );
}
else
{
printf("stduent1 :\n%d\n%s\n%d\n%d\n", , , , );
printf("stduent2 :\n%d\n%s\n%d\n%d\n", , , , );
}
system("pause");
return 0;
}
这便是一个完整结构体应用的代码,目的是输入两个学生的学号,姓名,年龄和成绩,然后比较两个人的成绩,然后输出成绩较高的同学的所有信息。在结构体变量成员的访问中需要用到的运算符是" . "该运算符可以对结构体变量成员进行访问。
既然结构体是一种类型,那么就一定有结构体指针了。前面说过,结构体是一种类型,他的应用方法和c语言默认的数据类型的应用方法一致,因此,其它类型的的指针如何使用,结构体指针就如何使用。例如,定义一个结构体指针 p,将一个结构体变量的变量名赋给p,则此时p指向的是结构体的首地址,如果对想通过结构体指针p来访问该结构体变量的成员,就需要进行节引用运算。方法如下
1. (*p). 成员名
2. p -> 成员名
这两种访问的方式是等价的。
以上便是结构体的解析。下面介绍链表以及结构体链表。
链表,顾名思义,即是一条链状的数据。链表是由一个 head 指针变量和许多节点组每个节点有许多元素,最后一个元素是一个指向下一个节点首地址的指针,第一个节点的首地址交给head,末尾的指针指向第二个节点的首地址,以此类推,到达最后一个节点,最后一个节点的末尾指针指向 NULL;这就是一条链表。一条链表必须有一个 head 指针才能寻找到第一个节点,否则无法进行链表的访问,并且每个节点的末尾指针必须指向下一个节点的首地址,否则就无法进行链式访问数据,并且最后一个节点的末尾指针必须指向NULL,避免指针指向未知区域。
现在我们来创建一个项目,来实现一个链表的创建。首先,先定义一个节点结构体,这个结构体可以存放数据和末尾指针。
struct stduent
{
long num;
float score;
struct stduent * next;
};
然后在写一个链表创建函数。
#define _CRT_SECURE_NO_WARNINGS 1
#define LEN sizeof(struct stduent)
#include<>
#include<>
struct stduent
{
long num;
float score;
struct stduent * next;
};
int n = 0;
struct stduent * creat(void)
{
struct stduent * head = NULL;
struct stduent * p1 = NULL;
struct stduent * p2 = NULL;
p1 = p2 = (struct stduent*)malloc(LEN);
printf("请输入索要存储的学生学号和成绩:\n");
printf("如果需要退出请输入 0 \n");
printf("学号 成绩\n");
scanf("%ld,%f", &p1->num, &p1->score);
while (p1->num != 0)
{
n += 1;
if (n == 1)
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct stduent *)malloc(LEN);
printf("学号 成绩\n");
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return head;
}
这时,一个链表创建函数已经创建完毕。在链表的创建过程中,通过动态内存开辟来实现空间的创建。如果输入的num=0;
就表明链表创建完毕,结束创建。最后,再添加一个main函数就可以实现这个程序的运行了。
#define LEN sizeof(struct stduent)
#include<>
#include<>
struct stduent
{
long num;
float score;
struct stduent * next;
};
int n = 0;
struct stduent * creat(void)
{
struct stduent * head = NULL;
struct stduent * p1 = NULL;
struct stduent * p2 = NULL;
p1 = p2 = (struct stduent*)malloc(LEN);
printf("请输入索要存储的学生学号和成绩:\n");
printf("如果需要退出请输入 0 \n");
printf("学号 成绩\n");
scanf("%ld,%f", &p1->num, &p1->score);
while (p1->num != 0)
{
n += 1;
if (n == 1)
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct stduent *)malloc(LEN);
printf("学号 成绩\n");
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return head;
}
int main()
{
struct stduent*pt = NULL;
pt = creat();
if (pt!=NULL)
{
do
{
printf("%-4ld%4.1f\n", pt->num, pt->score);
pt = pt->next;
} while (pt != NULL);
}
system("pause");
return 0;
}