本文章对c语言的特殊类型:结构体、枚举、共同体和typedef类型进行讲解
1、结构体
(1)、结构体变量
定义和使用
struct 结构体名称{
数据类型 变量名;
};
//定义
struct 结构体名称 结构体变量名或者指针;
//使用
结构体变量.变量名
eg: student.name;
(2)、结构体数组
定义和使用
struct 结构体名称{
数据类型 变量名;
}结构体数组名[长度];
eg:
struct Student{
int number;
char name[20];
}stu[3];
//使用
for(int i=0;i<3;i++){
scanf("%d%s",stu[i].number,stu[i].name);
}
(3)、结构体指针
定义和使用
struct Student(结构体名称){
数据类型 变量名;
};
//在函数中调用
struct Student stu;
struct Student *p;
p=&stu;
*p2=stu2;
//使用时
p->变量名
做参数使用时
struct Student(结构体名称){
数据类型 变量名;
};
//在函数中调用
void input(struct Student stu2[]);
struct Student stu[10];
struct Student *p;
p=stu;
input(p2);
(4)、结构体链表
一、静态链表
//定义结构体
struct Student{
int number;
char name[20];
struct Student *next;//指向下一个
};
int main(){
struct Student a,b,c,*head,*p;//假设有三个结构体,是静态的
//对结构体的变量赋值
a.number=10101;
b.number=10103;
c.number=10106;
//将链头指向第一个结构体的地址;根据地址连接
head=&a;
//将其他的指向下一个
a.next=&b;
b.next=&c;
//最后一个结构体的next指向NULL,说明链表结束
c.netx=NULL;
//遍历链表
//先将链头指向一个空的结构体指针
p=head;
//设置循环条件!至关重要
while(p!=NULL){
//输出链表排列的内容
printf("%d ",p->number);
//将链指向下一个链
p=p->next;
}
return 0;
}
二、动态链表(很重要)
#include <stdlib.h> //这个很重要,因为这里使用了动态存储malloc,free
#include <stdio.h>
//宏定义,定义一个结构体的长度空间
#define KJ sizeof(struct Student)//sizeof(struct Student)是获取一个结构体Student的长度
//定义结构体
struct Student{
int number;
char name[20];
struct Student *next;//指向下一个
};
//因为是动态创建链的内容,所以写一个创建函数,并返回一个链头
struct Student *create(void){
//定义结构体指针
struct Student *head,*p1,*p2;
int n=0;
//给两个指针变量各自分配一个结构体空间
p1=p2=(struct Student *)malloc(KJ);
//有空间了,那就将内容存储进去,动态输入
//给p1结构体输入内容
scanf("%d,%s",&p1->number,&p1->name);
//现在结构体p1有内容了,要将内容做成一个链
//首先将链头置为NULL
head=NULL;
//设置约定俗成,如果输入的number为0时,则不创建链表
//循环条件
while(p1->number!=0){
n=n+1;
//将链头指向p1这个结构体
if(n==1){
head=p1;
}
else{
//这里比较绕,作用是下一步的p2.next指向最新的链,这里的p1是最新的链
p2->next=p1;
}
//这里很关键!当n=1时,链头实际是指向了p2,p2做为上一个链,然后链接下一个时,是p2.next指向最新的链
p2=p1;
p1=(struct Student *)malloc(KJ);
scanf("%d,%s",&p1->number,&p1->name);
}
//结束后,给p2的尾链指向NULL,意味着链表结束,创建完成。
p2->next=NULL;//如果上面的循环理解了,这一步就知道为什么不是p1.next=NULL。p1表示新输入的链,p2表示原链。
//创建一个链表完成了,只需要返回链头就可以了
return (head);
}
//主函数的使用
int main(){
//设置一个结构体链头指针变量,接收创建传过来的链头
struct Student *head;
head=create();
//打印链表(遍历链表)
while(head!=NULL){
printf("number=%d\nname=%s\n",head->number,head->name);
//将当前链指向下一个链
head=head->next;
}
//用完要释放空间
free(head);
return 0;
}
2、共用体
(1)、共用体的定义
共用体变量所占的内存长度等于最长的成员的长度。
也就是说:共用一个空间,取最长的长度。第二次输入的内容会覆盖第一次输入的内容。
//定义的方法,和结构体一样,但是功能却不相同。
union 共用体名{//共用体名要遵循标识符命名规则,且一般首字母大写用于区分变量名
成员列表
}变量列表;
注意:不能初始化几个成员,因为占同一段存储单元!
(2)、共用体的使用
一般用于同一单元,却有不用的内容。例如:把学生所属班级和老师的职务放在同一给存储单元,但因为存储的类型不一致,则需要共同体。
#include <stdio.h>
#include <stdlib.h>
struct{
int num;
char name[10];
char job;
union{
int clas;
char position[10];
}category;
}person[2];
int main(){
int i;
for(i=0;i<2;i++){
printf("please enter the data of person:\n");
scanf("%d %s %c",&person[i].num,&person[i].name,&person[i].job);
if(person[i].job=='s'){
scanf("%d",&person[i].category.clas);
}
else if(person[i].job=='t'){
scanf("%s",&person[i].category.position);
}
else {
printf("Input error");
}
}
printf("\n");
printf("No. name sex job class/position\n");
for(i=0;i<2;i++){
if(person[i].job=='s'){
printf("%-6d%-10s%-4c%-10d\n",person[i].num,person[i].name,person[i].job,person[i].category.clas);
}
else{
printf("%-6d%-10s%-4c%-10s\n",person[i].num,person[i].name,person[i].job,person[i].category.position);
}
}
return 0;
}
3、枚举类型
枚举类型的特殊之处
- 一个变量表示几个可能出现的值,比如抽奖活动,变量代表 ’‘票’‘ ,枚举的值代表 ’‘是否中奖,中了几等奖’‘,把可能出现的值一 一列举出来,就是枚举。
- 枚举的按顺序第一个元素的值为0,后面一个元素的值都是前面一个元素的值+1;
- 枚举类型的元素不能当做变量赋值,只能在内部赋值,且为整数
- 枚举的变量可以赋值,但只能赋值为整数
代码演示:
enum 枚举名{枚举元素列表};
enum Weekday{
sun,mon,tue,wed,thu,fri,sat //注意:这里用逗号隔开,并且末尾没有分号
};
//定义枚举变量名
enum Weekday weekday;
//以下是错误的赋值写法!
sun=1;
//以下的写法是正确的
weekday=sun;//这里的意思是weekday=0
weekday=1;//这个写法也是正确的
//给枚举类型的元素赋值,只能在内部赋值,也就是定义的时候就赋值了
enum Weekday{
sun=7,mon=1,tue,wed,thu,fri,sat //从mon开始,后面一个元素的值都是前面一个元素的值+1;
};
4、typedef 声明新类型名
特点是用新的类型名代替原有的类型名,用简单的类型名代替复杂的类型,使代码更加的精洁
代码演示
//typedef声明普通类型
typedef int Integer;//将Integer做为类型名,作用与int相同
typedef float Fu;//将Fu做为类型名,作用与float一致
//typedef声明结构体
//原结构体
struct Student{
int num;
}stu;
//用typedef声明
typedef struct{
int num;
}Stu;