枚举
什么是枚举
把一个事物,所有可能的取值都一一列出来
怎样使用枚举
# include <stdio.h>
enum WeekDay { // 只定义了一个数据类型,并没有定义变量,该数据类型的名字是 enum WeekDay
MonDay, TuesDay, WednesDay = 5, ThursDay, FriDay, SaturDay, SunDay
};
int main(void)
{
// int day; // day定义成int类型不合适
enum WeekDay day = SunDay;
printf("%d\n", day);
return 0;
}
定义枚举类型要是有关键词enum,定义好一个枚举类型之后,它里面的元素与对应下标相绑定,即第一个元素MonDay = 0,我们也可以在定义的时候给里面的元素赋初值,赋了初值之后,他前面的元素保持不变,后面元素,在他初值的基础上加一,比如FriDay = 7.定义枚举类型的变量,不能给他赋int类型的值,比如day = 3,这是错误的,因为定义好枚举类型变量之后,他的值只能从,他的枚举类型中取值。
枚举的优缺点
1.代码更安全
2.书写麻烦
typedef 的使用
# include <stdio.h>
typedef struct Student {
int age;
char name[100];
char sex;
} *PSTU, STU;
// typedef 的作用就是取别名, PSTU 就等价于 struct Student *, STU 就等价于 struct Student
int main(void)
{
PSTU ps; // 等价于 struct Student * ps;
STU st; // 等价于 struct Student st;
ps = &st;
ps->age = 12;
st.sex = 'F';
printf("%d %c\n", st.age, ps->sex);
return 0;
}
补码
- 原码
也叫 符号-绝对值码,最高位0表示正数,1表示负数,其余二进制位是该数字的绝对值的二进制位,比如 5: 0101 ,-5:1101。
原码简单易懂,加减运算复杂,存在加减乘除四种运算,增加了CPU的复杂度,零的表示不唯一(0000或1000) - 反码
反码运算不便,也没有在计算机中应用 - 移码
移码表示数值的平移n位,n称为移码量
移码主要用于浮点数的阶码的存储 - 补码
- 已知十进制求二进制
- 求正整数的二进制
除2取余,直至商为零,余数倒序排序 - 求负整数的二进制
先求与该负数相对应的正整数的二进制代码,然后将所有未取反,末尾加1,不够位数时,左边补1 - 求零的二进制
全是零
- 求正整数的二进制
- 已知二进制求十进制
- 如果首位是0,则表明是正整数,按普通方式来求
- 如果首位是1,则表明是负整数
将所有位取反,末尾加1,所得数字就是该负数的绝对值 - 如果全是零,则对应十进制数字就是零
- 已知十进制求二进制
链表
算法:
通俗定义:解题的方法和步骤
狭义定义:对存储数据的操作;对不同的存储结构,要完成某一个功能所执行的操作是不一样的
比如:要输出数组中所有的元素的操作和要输出链表中所有元素的操作肯定是不一样的
这说明:算法是依附于存储结构的,不同的存储结构,所执行的算法肯定是不一样的
广义定义:广义的算法也叫泛型,无论数据是如何存储的,对该数据的操作都是一样的。
我们至少可以通过两种结构来存储数据
- 数组
优点:存取速度快
缺点:需要一个联系的很大的内存,插入和删除元素的效率很低 - 链表
优点:插入删除元素效率高,不需要一个连续的很大的内存
缺点:查找某个位置的元素效率低
专业术语:
首节点:存放第一个有效数据的节点
尾节点:存放最后一个有效数据的节点
头结点:头结点的数据类型和首节点的类型是一模一样的,头结点是首节点前面的那个节点,头结点并不存放有效数据,设置头结点的目的是为了方便对链表的操作
头指针:存放头节点地址的指针变量
位运算符
运算符 | 含义 |
---|---|
& | 按位与 |
竖线 | 按位或 |
~ | 按位非 |
^ | 按位异或 |
>> | 按位右移 |
<< | 按位左移 |
位运算符就是按数字的二进制位进行运算
i << 1表示把i的所有二进制位左移一位,左移n位相当于乘以2的n次方
i >> 3 表示把i的所有二进制位右移3位,左边一般补0,右移n位相对于除以2的n次方,前提是数据不能丢失。
位运算的现实意义:通过位运算我们可以对数据的操作精确到每一位
NULL的含义
二进制全部为零的含义 — 0000000000 的含义
- 数值0
- 字符串结束标记符 ‘\0’
- 空指针NULL
NULL本质也是零,而这个零不代表数字零,而表示的是内存单元的编号零
我们计算机规定了,以零为编号的存储单元的内容不可读,不可写
什么叫分配内存,什么叫释放内存
操作系统把某一块内存空间的使用权利分配给该程序叫内存分配
操作系统把分配给该程序的内存空间的使用权利收回,该程序就不能够再使用这一块内存空间叫释放内存。
附注:释放内存不是把该内存的内容清零。
变量为什么必须得初始化
不初始化,则变量通常就是垃圾值
详细说明系统是如何执行:int i = 5;这个语句的。
(1).Vc++6.0软件请求操作系统为 i 分配存储空间
(2)操作系统会在内存中寻找一块空闲的区域,把该区域当作 i 来使用
(3)Vc++6.0会把 i 和这块空闲区域关联起来,今后对字母 i 操作就是对这块空闲的区域操作
(4)把 5 存储到字母 i 关联的内存区域中
附注:所谓内存区域也就是内存的一块存储单元
详细列出C语言所有的基本类型
int long int short int char float double
在printf函数中 int 用 %d输出,请问:long int char double float 分别用什么输出?
%ld %c %lf %f
函数的优点是什么?
(1)避免重复性操作
(2)有利于程序的模块化
什么是指针,什么是地址,什么是指针变量,三者之间是什么关系?
地址是内存单元的编号 指针就是地址 指针和地址是同一个概念
指针变量是存放内存单元编号的变量 指针变量和指针是两个完全不同的概念,只不过人们通常把指针变量简称为指针
请写出静态变量和动态变量的异同
相同:都需要分配内存
不同点:
(1)静态变量是由系统自动分配,自动释放,程序员无法在程序运行的过程当中手动分配,也无法在程序运行的过程当中手动释放
静态变量是在栈中分配的
只要在函数终止之后,静态变量的存储空间才会被系统自动释放
(2)动态变量是由程序员手动分配,手动释放,程序员可以在程序运行的过程当中手动分配,也可以在程序运行的过程当中手动释放
动态变量是在堆中分配的
程序员可以在函数执行的过程中的任何一个时刻手动的释放动态变量的空间,不需要等到函数终止时才释放