#include<stdio.h>
void sort(int *a,int len)
{
int i, j, t;
for (i = 0; i < len - 1; ++i) {
for (j = 0; j < len - 1 - i; ++j) {
if (a[j] > a[j + 1]) {
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
}
int main(void) {
int a[6] = { 10,2,8,-8,11,0 };
int i = 0;
sort(a,6);
for (i = 0; i < 6; i++) {
printf("%d\n", a[i]);
}
return 0;
}
枚举
什么是枚举
把一个事物所有可能的取值一一列举出来
怎么样使用枚举
枚举的优缺点
- 代码更加安全
- 书写比较麻烦
进制问题
N进制就是逢N进一
十进制转R进制
除R取余直至商0
余数倒序排列
%#X
%X
编码
人为规定
原码
- 也叫 符号-绝对值码
- 最高位0表示正 1表示负
- 其余二进制位是该数字的绝对值的二进制
- 原码简单易懂 加减运算复杂
- 存在加减乘除四种运算,增加了CPU的复杂度
- 零的表示不唯一
反码
- 反码运算不便,也没有在计算机中运用
移码
- 移码表示数值平移n位,n成为移码量
- 移码主要用于浮点数的阶码的存储
补码
-
十进制转二进制
求 正整数的二进制
除2取余,直至商为0,余数倒序排序
求负整数的二进制
先求与该负数相对应的正整数的补码,然后将
所有位取反,末尾+1,不够位数时,左边补1(-3) 3 011 100 + 1 101 int 29+3 short int 13+3
看容器大小
int i = -3;
printf("%#X", i);
运行结果:
0XFFFFFFFD
--------------------------
int i = -1;
printf("%#X", i);
01
取反 10
加一 +1
11
运行结果:
0XFFFFFFFF
求零的二进制
全是零
- 已知二进制求十进制
若首位是0,则表明是正整数, 按普通方法来求
若首位是1,则表明是负整数
将所有位取反,末尾加1,所得数字就是该负数的绝对值
若全是0,则对应的整数时零
0000 0000
0000 0001
0000 0010
0111 1111
//7*16+15=112+15=127
//7F
1000 0000
//0111 1111
//1000 0000
//80
//-8*16=-128
1000 0001
//0111 1110
//0111 1111
//-7*16-15=127
1111 1111
//0000 0000
//0000 0001
//-1
在VC++6.0中一个int类型的变量所能存储的数字的范围是多少
int类型变量所能存储的最大正数用十六进制表示是: 7FFF FFFF
int类型变量存储的绝对值最大的负整数用十六进制表示是:8000 0000
链表
算法:
- 通俗定义:
解题的方案和步骤 - 狭义定义:
对存储数据的操作
对不同的存储结构,要完成某一个功能所执行的操作是不一样的
例如:要输出数组中所有的元素的操作和
要输出链表中所有元素的操作肯定是不一样的
这说明:算法是依附于存储结构的
不同的存储结构,所执行的算法是不一样的 - 广义定义
广义的算法也叫泛型
无论数据是如何存储的,对改数据的操作都是一样的
我们至少可以通过两种结构来存储数据
-
数组
优点:
存取速度快
缺点:
需要一个连续的很大的内存
插入和删除元素的效率很低 -
链表
优点:
插入删除元素效率高
不需要一个连续的很大的内存
缺点:
查找某个位置的元素效率很低
专业术语:
头结点
- 头结点的数据类型和首节点的类型是一模一样的
- 头结点是首节点前面那个节点
- 头结点并不存放有效数据
- 设置头结点的目的是为了方便对链表的操作
头指针
- 存放头结点地址的指针变量
首节点
- 存放第一个有效数据的节点
尾节点
- 存放最后一个有效数据的节点
确定一个链表需要的参数:
一个 头指针
位运算符
&
– 按位与
&& 逻辑与、并且
&& 与 & 的含义完全不同
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
int i = 5;
int j = 7;
int k;
k = i & j;
//0101
//0111
//0101
printf("%d\n", k);
k = i && j;
//逻辑运算符的结果TRUE OR FALSE
printf("%d\n", k);
应用:
- 让某一位或某些位为0: x & 0xFE
1111 1110 FE
& 1010 0101
1010 0100
- 取一个数中的一段: x & 0xFF
一个int是32位
XX XX XX XX
& 00 00 00 FF
00 00 00 XX
|
– 按位或
| 逻辑与、并且
|| 与 | 的含义完全不同
1 | 0 = 1
1 | 1 = 1
0 | 1 = 1
0 | 0 = 0
int i = 3;
int j = 5;
int k;
//0011
//0101
//0111
k = i | j;
printf("%d\n", k);
k=7
应用:
- 让某一位或某几位为1: x | 0x01
0000 1111 01
& 1010 0101
1010 1111
- 把两个数拼起来: 0x00FF | 0xFF00
~
– 按位取反
~i
就是把i变量所有的二进制位取反
int i = 3;
//0000 0011
//1111 1100 算负数的十进制值
//0000 0011 取反
//0000 0100 加一
k = ~i;
printf("%d\n", k);
k=-4
~
– 按位取反
把1位变0,0位变1
^
– 按位异或
相同为0
不同为1
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
0 ^ 0 = 0
- 对一个变量用一个值异或两次,等于什么也没有做
x^ y ^ y = x
(加密)
<<
– 按位左移
i>>1
表示把i的所有二进制位左移一位
左移n位相当于乘以 2^n
可以类比于十进制,只不过这里是二进制
>>
– 按位右移
i>>3
表示把i的所有二进制位右移3位,左边一般是0.当然也可以补1 // 逻辑右移和算数右移
左移n位相当于除以 2^n,前提是数据不能丢失
引用意义:
A i = i * 8;
B i = i << 3;
B 语句执行的速度快
通过位运算符
我们可以对数据的操作精确到每一位
输出一个数的二进制
int main()
{
int number;
scanf_s("%d", &number);
unsigned int mask = 1u << 31;
/*1u 等价于 1 unsigned int
通常来说,1个int4个字节
1个字节8个bit 也就是4*8=32
即 00000000 00000000 00000000 00000001
左移31位后
10000000 00000000 00000000 00000000
*/
for (; mask; mask >>= 1) {
printf("%d", number & mask ? 1 : 0);
/*mask逐一地去看number每一个bit是0还是1
若求与结果是1,则说明那个bit上也是1
通过mask的逐一排查可以实现二进制的输出*/
}
printf("\n");
return 0;
}