结构体
注意:
1.结构体类型 可以定义在 函数里里面 但是此时作用域就被限定在该函数中
2.结构体定义形式
//形式一 限定一类型 后定义变量
struct stu
{
...
};
struct stu s;
//形式二 定义类型的同时 定义变量
struct stu
{
...
}s1,s2,*s3,s4[10];
struct stu s;
//形式三 省略了类型名-----只在使用一次的时候使用
struct
{
...
}s1,s2,*s3,s4[10];
考点:
自然边界对齐
int ------四字节------能被4整除的地址编号
shout----二字节-----能被2整除的地址编号
char-----一字节------能被1整除的地址编号
共用体
union 共用体名
{
成员列表
}; //表示定义一个共用体类型
注意:
1.初始化时 只能能给到一个值 默认是给到第一个成员变量的
2.共用体成员辅助
共用体用的数据最终储存的------是最后一次给到的值
但是只能影响到 自己数据类型对用空间中的数据
3.可以判断大小端
#include <stdio.h>
union dome
{
int a;
short b;
char c;
};
int main (void)
{
union dome s;
s.a=0x12345678;
s.b=0x1298;
s.c='c';
printf ("a=%#x\n",s.a);
printf ("b=%#x\n",s.b);
printf ("c=%#hhx\n",s.c);
return 0;
}
a=0x12341263
b=0x1263
c=0x63
4.实际用途:节约空间 、 进行数据转换
5.共用体的大小:是成员变量中是最大的那个成员的大小
6.共用体类型可以是参数 也可以是函数返回值类型
共用体,结构体类型定义出来之后:
a.定义变量;
b.定义数组;
c.定义指针;
d.做函数参数,返回值类型
枚举
一枚一枚的列举
逐个列举
如果一个变量只有几种可能的值,则可以定义为枚举类型。所谓"枚举”是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
eg:
//从键盘输入l~7
打印出对应的英文的星期
声明枚举类型用enum开头。
例如:
enum weekday //枚举类型名
{
sun , //名字---代表一个值-----符号常量
mon ,
tue ,
wed ,
thu ,
fri,
sat
};
enum //关健词---枚举
注意:
1.枚举提高了代码的可读性
2.枚举本质上是int型
枚举与整型互相兼容
3.不足:因为枚举类型本质上是一个整型类型 所以枚举类型的变量的值 并不能真正限定在指定的那些范围中
4.枚举类型可以做函数的形参和返回值,定义数组也可以,同时枚举类型本质上就是整形数据
练习:
无人机
无人机的状态
0 --flying
1 --stop
2 --holding
从键盘输入0~2 打印无人机的状态
#include <stdio.h>
enum Flight_status
{
flying,
stop,
holding
};
int main (void)
{
int a;
printf ("intput number : \n");
scanf ("%d",&a);
switch (a)
{
case flying:
printf ("flying\n");
break;
case stop:
printf ("stop\n");
break;
case holding:
printf ("holding\n");
break;
}
return 0;
}
链表
数据结构:
数据的组织形式(逻辑上理解的形式)
数组:连续性 有序性 单一性
数据的组织形式会----------决定使用数据的算法
数组的优点://随机访问很方便
缺点://增加数据就会很不方便 删除数据也不方便
链表:链式的数据表
优点: 增加删除数据很方便
缺点:找数据很不太方便
计算机中如何体现来来链式数据结构?
存放链式数据的结构:节点
[数据 | 另一个节点的指针]
一个节点:数据结构对应算法----的操作
操作:
1.创建一个链表----空链表
//有头链表----可以更方便的处理链表
//无头链表
c语言阶段:有头单向列表
相关概念:
1.节点
2.头节点---数据域值随机
3.首节点---第一个保存有效数据的节点
4.尾节点---链表的最后一个有效节点 NULL
空链表:
特点:只有头节点 并且头节点的指针域为 NULL //相当于是尾节点
strcut Node head = {0,NULL};
struct Node *p = &head;
2.链表的插入
创建一个新的节点 将节点连接起来
尾插:
头插:
#include <stdio.h>
#include <stdlib.h>
//****************************************
#if 1
struct Node
{
int data;
struct Node *next;
};
void pushBack(struct Node *head,int data) //尾插形式链表
{
struct Node *pNew = malloc (sizeof (struct Node)); //开辟一个新节点的空间放在堆区
pNew->data=data; //将定义的数值放在新节点的数值域中
struct Node *p = head; // 定义一个结构体指针p指在头节点处
while (p->next != NULL)
{
p = p->next; //让p指向下一个节点 直到指到尾节点
}
p->next = pNew;
pNew->next = NULL; //将尾节点的指针域定义为空
}
int isPuanduan (struct Node *head)
{
if (head->next==NULL) //判断头节点是否为空 空则返回1 不是空则返回0
{
return 1;
}else
{
return 0;
}
}
void PrintLinklist(struct Node *head) //打印整个链表的数据函数
{
struct Node *p = head; //定义一个结构体指针p指在头节点处
if (isPuanduan(head)==0) // 如果头链表不是空 则将头链表的指针域给到p
{
p = head->next;
while(p != NULL) // 判断指针域是否为空
{
printf ("%d\n",p->data); // 不是空就打印出每个链表中数据域的元素
p = p->next;
}
}
}
int lens(struct Node *head) //统计链表长度
{
int cont=0;
struct Node *p = head->next; //定义一个结构体指针p 指向头结点的地址
while(p->next != NULL) //判断每个链表的指针域是否为空
{
cont++;
p = p->next; //是则进入循环 并记录次数 指针p则继续指向下一个链表继续判断
}
return cont;
}
void Head_insert(struct Node *head,int data) //头插形式链表函数
{
struct Node *pNew = malloc(sizeof(struct Node)); //定义一个结构体类型的空间 地址放在堆区
pNew->data = data; //将定义好的数据放到新定义的节点中
struct Node *p = head; //定义一个结构体指针 记录首节点的位置
pNew->next = head->next; //将首节点中装的地址放到新节点中
p->next = pNew; //再将新节点本身的地址放到首节点的指针域中
}
int main (void)
{
struct Node head;
head.next = NULL; //定义一个空链表
pushBack(&head,1); //将想要打印的数组值传到尾插链表函数中
pushBack(&head,2);
pushBack(&head,3);
pushBack(&head,4);
pushBack(&head,5);
pushBack(&head,6);
pushBack(&head,7);
// PrintLinklist(&head);
printf ("len=%d\n",lens(&head)); //打印整个链表的长度
Head_insert(&head,8);
Head_insert(&head,9); //将想要打印的数组值传到头插链表函数中
Head_insert(&head,10);
Head_insert(&head,11);
Head_insert(&head,12);
Head_insert(&head,13);
PrintLinklist(&head); //将整个链表的数据打出来
return 0;
}
#endif