黑马程序员——ios开发基础之C语言之进制转换、位运算与内存管理

时间:2021-02-28 00:27:37
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

第一讲  进制转换

1、计算机中的进制

           2进制:逢二进1 0 1
           8进制:逢八进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>
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;
}
           2)交换两个变量的值,不使用其他变量
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是一个野指针
               如果不释放,造成内存的泄露