1、枚举
enum COLOR {RED,YELLOW,GREEN};//red,yellow,green分别与0,1,2对应,即red的值为0
//可以把enum理解成一种类型,其变量就是int
//使用
enum color t=red;//此时t为0
//可以自动计数
enum COLOR {RED,YELLOW,GREEN,NumCOLORS};
//NumCOLORS的值就是颜色的数量
#include <stdio.h>
enum DAY
{ MON=1, TUE, WED, THU, FRI, SAT, SUN} day;
int main()
{// 遍历枚举元素
for (day = MON; day <= SUN; day++) {
printf("枚举元素:%d \n", day);
}
}
枚举主要用于有意义的排比的名字,其它方面不用了解的太清楚
2、结构定义
//通常把结构的声明放在所有函数的外面,这样整个程序都可以使用
struct date{
int month;
int day;
int year;
};//最后要有分号
//另一声明方式
struct {
int month;
int day;
int year;
}p1,p2;//没给类型起名字,只定义了两个变量
//第三种
struct date{
int month;
int day;
int year;
}p1,p2;
3、结构赋值
//赋值
//挨个赋值
struct date today;//初始化
today.month=07;
today.day=31;
today.year=2020;
//整体赋值
struct date today={07,31,2020};
//部分赋值
struct date lastmonth={.day=31,.year=2020};
//缺的自动填0
//强制类型转换
p1=(struct date){07,31,2020};//把数组转化成结构
//赋值
p1=p2;//不相互关联,改变一个另一个不变
4、结构指针
//结构指针
struct date *pDate=&today;
pDate->day
结构变量可以作为函数的值传入函数,但这是新建一个新结构,把传入的结构变量复制到新的结构中。
5、结构输入输出
//输入结构
#include <stdio.h>
struct point{
int x;
int y;
};
void getStruct(struct point);
void output(struct point);
void main(){
struct point y={0,0};
y=getStruct();
output(&y);
}
void getStruct(void){
struct point p;
scanf("%d",&p.x);//即&(p.x)
scanf("%d",&p.y);
return p;
}
void output(struct point p){
printf("%d %d",p.x,p.y);
}
struct point{
int x;
int y;
}myday;
int main(){
struct date *p=&myday;
output(getStruct(p));
}
//用指针是最好的选择
void getStruct(vstruct point *p){
struct point p;
scanf("%d",&(p->x));
scanf("%d",&(p->y));
return p;
}
void output(const struct point *p){
printf("%d %d",p->x,p->y);
}
6、结构数组
//结构数组
struct time testTime[4]={
{11,59,59},{12,0,0},{1,29,59},{23,59,59}};
7、循环队列
队列是指允许在一端进行插入,在另一端进行删除的线性表,又称“先进先出”的线性表
队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这称为出队
队尾:允许插入的一端,用尾指针指向队尾元素的后一位置
队首:允许删除的一端,用头指针指向头元素
#include <stdio.h>
#define LENGTH 11 //定义队列最大长度
#define OUT 1//出队
#define GET 2 //入队
struct queue{
int data[LENGTH];#存储数组
int head;//队首
int tail;//队尾
}
int main(){
struct queue q;
int i;
int measure=0;
q.head=q.tail=0;
for (i=0;i<LENGTH-1;i++){
scanf("%d",&q.data[q.tail]);
q.tail=(q.tail+1)%LENGTH;//只要同时在队里的元素不超过最大长度就可以一直进行下去
}
//出队
scanf("%d",&measure);
if (measure==OUT){
q.head=(q.head+1)%LENGTH;
}
else if (measure==GET){
scanf("%d", &q.data[q.tail]);
q.tail=(q.tail+1)%LENGTH;
}
}
//问题:q.head==q.tail既表示队列为满也表示队列为空,要解决这个问题最好的方法是用一个元素记录队列的元素个数。
8、单向链表
#include <stdio.h>
struct link{
int data;
struct link *next;
}
与数组比较链表插入和删除比较方便,不用大量移动元素,还没有长度的限制,可以不断改变长度。但是链表元素的访问则不是很容易。
链表的基本操作
#include <stdio.h>
#include <stdlib.h>
struct link *AppendNode (struct link *head);//插入
void DisplyNode (struct link *head);//遍历
void DeletMemory (struct link *head);//删除
struct link{
int data;
struct link *next;
};
int main(void)
{
int i = 0;
char c;
struct link *head = NULL; //链表头指针一般都定义成NULL
DeletMemory(head); //释放所有动态分配的内存
return 0;
}
9、二叉树
struct node{
char data;
struct node *leftChild;
struct node *rightChild;
}
//前序遍历
void PreOrderTraverse( struct node *t, int level){
if(*t==NULL) return ;
PreOrderTraverse(t->leftChild,level+1);
printf("data=%c level=%d\n",t->data,level);
PreOrderTraverse(t->RightChild,level+1);
}