第一讲 进制转换
1、计算机中的进制
2进制:逢二进1 0 18进制:逢八进1 0 1 2 3 4 5 6 7
10进制:逢十进1 默认的进制 0 - 9
16进制:逢十六进1 0 - 9 A B C D E F (内存的地址格式)
2、进制的转换问题
数码(每一位是0还是1)三个要素:
1)数位:数位是指数码在一个数中所处的位置( 0-7)
2)基数(每一位能取值的个数)、
3)位权(数码*基数^数位)、 101 = 1*2^0+0*2^1+1*2^2
转换:有得时候转换为人能识别的数制,要操作计算机写计算机能够识别的语言(二进制)
10 -> 2 : 除2取余法,把10进制数除以2,然后取得余数的序列,再倒序
2 -> 10 : 所有位的位权相加 101 = 1*2^0+0*2^1+1*2^2
2 --> 16 : 4合1法, 整数部分从右向左 4位结合成一位,小数部分从左向右4位结合1位,不足部分补0
16 -->2 : 1拆4法, 16进制的1位拆成二进制的4位
2 --> 8 : 3合1
8 --> 2 : 1拆3
8 --> 10 : 8--> 2 --> 10
16 --> 10: 16 -->2 -->10
3、原码、反码和补码
1)机器码、真值一个数的二进制的表示 机器码
把一个数的二进制转换为10进值得值 真值
2)计算数据的存储
存储的是数的补码
数是有正负性
正数:最高位 用0表示符号位
负数:最高位 用1表示符号位
3)原码、反码、补码:
原码: 正数:就是其二进制表示 +1 00000001
负数:二进制的最高位是1 -1 10000001
反码:
正数:就是其二进制表示 +1 00000001
负数:符号位不变,其他位逐位取反 -1 11111110
补码:
正数:就是其二进制表示 +1 00000001
负数: 反码+1 -1 11111111
注意:补码的真值不等于原码的真值的
补码主要是位了优化计算机中的减法
数据在计算机中都是以其补码的形式储存的
第二讲 位运算
1、位运算符
二进制数码之间的运算6个运算符号
1)& 按位与:逐位运算,有0则为0,同1则为1
2)| 按位或:有1为1
3)^ 按位异或:相同为0,不同为1
4)~ 按位的取反: 0变1, 1变0
5)>> 按位右移:把一个数的所有的二进制位全部向右移动指定位数 10>>2;
注意:移出的位舍弃,高位补符号位,可能让一个数为0
6)<< 按位左移把一个数的所有的二进制位全部向左移动指定位数
注意:移出的位舍弃,低位补0,可能会改变一个数的正负性
例:11&2
1011
& 0010
--------------
0010
技巧:
任何数和1按位&操作,得到这个数的最低位 //0000 0000 0000 0000 0000 0000 0000 1101 13
13&1 //0000 0000 0000 0000 0000 0000 0000 0001 1
偶数的最低位 0
奇数的最低位 1
2、应用举例:
1)编程实现10进制转其它进制#include <stdio.h>2)交换两个变量的值,不使用其他变量
void b1(int num){
int len = sizeof(int)*8;
int temp;
for (int i=0; i<len; i++) {
temp = num; //每次都在原数的基础上进行移位运算
temp = temp>>(31-i); //每次移动的位数
int t = temp&1; //取出最后一位
if(i!=0&&i%4==0)printf(" ");
printf("%d",t);
}
printf("\n");
}
int main(int argc, const char * argv[]) {
int a;
printf("请输入要转换的数:\n");
scanf("%d",&a);
//按二进制输出
b1(a);
//按八进制输出
printf("%o\n",a);
//按16进制输出
printf("%x\n",a);
return 0;
}
int temp; // 原来使用其他变量
temp = a;
a =b;
b = temp;
// 1、加减法
a = b - a;
b = b - a;// b - (b - a) = b - b + a = a
a = b + a;// a + b - a = b
printf("a = %d,b = %d\n",a,b);
// 2、按位异或
a = a ^ b;
b = a ^ b; // a ^ b ^ b = a
a = a ^ b; // a ^ b ^ a = a ^ a ^ b = b
printf("a = %d,b = %d\n",a,b);
第三讲 内存管理
1、概念及分配方式
内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收 内存资源。内存分配方式 内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量, static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算 内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多个的内存,程序员自己负责在何时用free或delete释放内 存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多
2、变量在内存中存储的细节
内存分配给变量的存储空间是从高到低一个变量低位低地址
高位存放高地址
3、C语言中的内存管理
内存分为5大区域栈区 -- 存放局部变量
堆区 -- 程序运行过程中,动态分配的内存
BSS区 -- 未初始化的全局变量和静态变量
数据段 -- 已经初始化的全局变量和静态变量
代码段 -- 程序编译产生的二进制的数据
4、动态内存管理
1) malloc(void *)malloc(size) //动态的向内存申请连续的size个字节
返回的是新申请的内存空间的首地址
int *p = (int *)malloc(100);
//p是在栈区 malloc(100) 在堆区
malloc不会把新申请的空间初始化
memset(p,0,100); //全部初始化为0
2) calloc
calloc 可以向堆区连续申请多个少 长度为指定长度的空间
int *p = (int *)calloc(5,4); //申请5个长度为4的空间
calloc可以把新申请的空间初始化0
注意:判断一个空间是否申请成功
if(p!=NULL){
//只有申请成功了,才能操作
}else{ //打印失败信息 }
3) realloc
重新改变一块内存空间的大小
p = (int *)realloc(p,size);
4) free
释放我们指定的内存空间
free(p); //p是我们新申请的内存单元
free后,p是一个野指针
如果不释放,造成内存的泄露