第06天C语言(00):笔记总结

01-进制转换-基本概念
如何输出十进制 %i %d, 以十进制的方式输出数据

 在编程中想表示二进制,需要在数字前面加上0b

 %o 就是以八进制的形式输出

 在编程中想表示八进制,需要在数字前面加上0 

 %x 就是以十六进制的形式输出

 在编程中想表示十六进制,需要在数字前面加上0x


 注意: 在C语言中没有以二进制输出的占位符
02-进制转换
1.十进制 转 二进制

 规律 : 用需要转换的十进制 除以2 取余数 , 然后倒数

     13 / 2 = 6 余 1

     6 / 2 = 3 余 0

     3 / 2 = 1 余 1

     1 / 2 = 0 余 1

     -------- = 1101

 

 2. 二进制 转 十进制

 规律 : 从低位数开始, 用低位 乘以 2的 多少次幂, 幂数从0开始,然后再相加

     二进制 : 1101

         1 * 2(0) = 1

         0 * 2(1) = 0

         1 * 2(0) = 4

         1 * 2(3) = 8

         1 + 0 + 4 + 8 = 13

     口诀

         1 1 1 1

         8 4 2 1

 

 3.  二进制 转 八进制

 规律 : 三个二进制位 代表一个八进制位, 只需要将3个二进制位 转换为十进制, 之后再将所有的结果连接起来

        1001 转换为  00 001 001

        0  1   1

        ------------------------

        011 == 0 * 8 + 1 * 8 + 3 = 11(十进制)

 

4. 二进制 转 十六进制

 规律 : 四个二进制位代表一个十六进制位, 只需要将4个二进制位转换成10进制, 之后再将所有的结果连接起来

     0001 1011

     --------

     1   b = 0x1b
03-原码补码反码
为什么要有 原码 / 反码 / 补码 ? 主要是为了方便计算机计算

 其实二进制的第一位 是二进制的符号位

 如果该位是0 代表这个数 是正数

 如果该位是1 代表这个数 是负数

 

 正数

 总之一句话, 正数的原码\补码\反码 都是一样的,三码合一

 负数

 反码 : 符号位不变, 其他位取反(0变1,1变0)

 补码 : 反码 + 1就是补码

 

 9的二进制

 正数

 0000 0000 0000 0000 0000 0000 0000 1001 (原码)/反码/补码

 负数

 1000 0000 0000 0000 0000 0000 0000 1001 (原码)

 1111 1111 1111 1111 1111 1111 1111 0110 (反码)

 1111 1111 1111 1111 1111 1111 1111 0111 (补码)

 

 

 // 补码的深入

 1 - 1 = 1 + (-1)

 原码 计算结果 = -2

 反码 计算结果 = -0

 补码 计算结果 = 0
04-位运算
位运算 (和二进制相关)

 

 1.& 按位与

 规律 : 一假则假, 1真 0假

 规律 : 任何数和 1 相& 得到的结果还是那个数

        1001 & 1111 = 1001

 

 2.| 按位或

 规律 : 一真则真

 

 3.^ 按位异或

 重点 : 异或的结果 和 参与运算的顺序没有关系

 规律1 : 不相同为1, 相同为0 (异或)

         1001 ^ 0101 = 1100

 规律2 : 相同的两个数 异或 等于0

        5 ^ 5 = 0101 ^ 0101 = 0

 规律3 : 任何数 和 0 异或上0 结果不变

        5 ^ 0 = 0101 ^ 0000 = 0101 = 5

 规律4 : 任何一个数 异或上 同一个数两次, 结果不变

        9 ^ 5 ^ 5 = ?  == 9 ^ 0 = 9

 ~ 取反

    计算机是以补码形式存在的

    1.先拿到数 的原码 [进行一个取反] 在 -1 变成反码 再将反码 转为原码

   一 . 9 原码 0000 0000 0000 0000 0000 0000 0000 1001

   二 . 取反的得到补码 -->

       1111 1111 1111 1111 1111 1111 1111 0110 的到的补码

   三 .  再将 补码 -1变成反码 -->

        1111 1111 1111 1111 1111 1111 1111 0101

   四 . 再将反码取反变回原码  --->

        1000 0000 0000 0000 0000 0000 0000 1010 == -10

  ~9 = -10

 

 

 原码 --> 反码(取反) -->(补码)+1

 补码 -->  反码(-1) --> 原码(取反)
05-左移右移
左移 <<

     规律 : 左移 就是左移的数乘以2的移动次幂

     例如

         9 << 1 = 9 * 2(1)  = 18

         9 << 2 = 9 * 2(2)  = 36

     注意点 :

     由于左移运算,被移动的数 最高位会被抛开(移除),所以左移有可能会改变一个数的正负性

 右移 >>

    规律 : 右移 就是右移的数除以2的移动次幂

        9 >> 1 = 9 / 2(1) = 4;

        9 >> 1 = 9 / 2(2) = 2;

     注意 : 负数的左移右移 是补码在移动,因为负数都是以补码的形式存储在内存中的

     应用场景 :  如果想让某一个数 乘以2的多少次幂,或者除以2的多少次幂,最高运算方式就是左移右移
06-位运算-练习1
     使用按位与 &

     任何数和 1 相& 得到的结果还是那个数

     

                                           0000 0000 0000 0000 0000 0000 0000 1001

    &0000 0000 0000 0000 0000 0000 0000 0001

     ----------------------------------------

     // 1.让9的二进制向右移31位,就可以获取到9的最高位的二进制,然后让9的二进制的最高位 和1相与,那么就可以获得9的最高位

     // 2.让9的二进制向右移动30位,就可以获取9二进制第二位

     // 3.以此类推,直到0位置

 

     技巧

     1.任何数 与 1相& 都是那个数

     2.利用位移 取出每一位
07-位运算-练习2
1001   9

 1010   10

 

 1011   11

 1100   12

 

 通过观察,

 我们发现如果是偶数,那么二进制的最后1位是0,

 如果是奇数,那么二进制的最后1位是1.

 if ((num & 1) == 1) {

 printf("奇数");

 }

 else

 {

 printf("偶数\n");

 }
08-位运算-练习3
    /*

     不相同为1, 相同为0 (异或)

     */

    

    /*

    a = a ^ b;

    b = a ^ b; // a ^ b ^ b = a ^ 0 = a

    a = a ^ b; // a ^ b ^ a = b ^ 0 = b

    */

#pragma 开发简单加密

    // 用户密码, 纯数字

    int pwd = 123;

    // 对用户密码 进行简单加密

    int result = pwd ^ 456;

    // 对用户密码进行解密

    result = result ^ 456;
09-变量内存分析
主要定义变量, 系统就会开辟一块存储空间 给我们的变量存储数据,内存寻址是从大到小

 越先定义的变量,内存地址越大

 

 注意 : 由于内存寻址是从大到小, 所以存储数据也是从大到小的存储(先存储二进制的高位,再存储低位)

    高位          --> 低位

 0000 0000 0000 0000 0000 0000 0000 1001
10-char类型-基本概念
计算机只能识别0和1 'a' 通过ASCII码表 获取一个值 转换成二进制

 在C语言中, 不看怎么存, 只看怎么取

 char类型 在某些情况下 可以当做整型来用

 如果对内容要求特别严格,而且需要存储的整数 不超过char类型的取值范围,那么就可以使用char类型来代替int类型

 -2(7)~2(7) - 1 = -128 ~ 127

 char c =128; // 打印出来 -128 因为超出了范围
11-char类型-练习
大写 ASCII码 65 - 90

小写 ASCII码 97 - 122

差值  ('a' - 'A')  97 - 65 = 32;
12-类型说明符
类型说明符:

  1.说明长度的 (它可以用于修改 类型 所占用的存储空间的大小)

 short; 

    输出 %hi hd          // 2个字节 == -2(15)~2(15)-1

 long;  

    输出 %li ld          // (64位占8个字节) 32 位long 占用4个字节 ,  long long 占用 8个字节 == -2(63) ~ 2(63)-1

 long long;

    输出 %lli %lld    // 8个字节 == -2(63) ~ 2(63)-1

 用于说明数据类型, 一般情况下 和 int 配合使用

 

 2.说明符号位 (它可以用于修改符号位)

 unsigned;  (无符号) 输出 %u  . 取值 整数 和 零

 

 signed;    (有符号的)          取值 正数 和 零 以及 负数

        如果给变量加上修饰符 signed 代表当前变量的取值可以是 正数 / 负数 /零

        如果给变量加上修饰符 signed 就代表把 二进制的最高位作为符号位

        而且默认情况下所有变量都是有符号的(signed)

 

 3.不同类型的说明符 可以混合使用

 unsigned short

 signed long

 注意 : 相同类型的 说明符 不能同时在一起使用
13-数组-基本概念
/*

 数组的定义格式 :

 数据类型 变量名称;

 数据类型 数组名称[数据的个数];

 元素类型 数组名称[元素个数];

 元素类型:就是数组中需要存储的数据类型 , 一旦确定, 数组中就只能存储该类型的数据

 元素个数:  就是数组中能够存储的数据(元素)的个数

 */
14-数组-初始化
数组的部分\完全初始化

    部分初始化 [1)默认从0开始初始化 -- 2)如果"在部分初始化中",对应的内存没有被初始化, 那么默认是0]

        int scores1[3] ={11,22};

    完全初始化 [1) 依次将{}中的每一个值 赋值给数组中的每一个元素 -- 2)并且从0开始赋值]

        int scores[5] = {99,88,77,66,100};

 

  注意1:如果没有对数据进行初始化(完全和部分),那么不要随便使用数组中的数据,可能是一堆垃圾数据(随机值)

        int scores2[3]; // 0 = 32767 1 = 0 2 = 0

  注意2: 定义数组的时候,数组的元素个数不能使用变量,如果使用变量,那么数组中 是一些随机值

        int num = 3; int scores3[num]; // 0 = 1606416240 1 = 32767 2 = 3611

  (报错)注意3: 不建议使用变量定义数组,如果使用了变量定义数组, 作为数组的元素个数,不初始化的情况下是随机值,如果初始化会直接报错

        int num1 = 3;int scores4[num1] = {11,12};

  注意4: 如果定义的同时进行初始化,那么元素的个数可以省略

        省略之后, 初始化赋值几个数据,那么数组的长度就是几,也就是说数组将来就能存储 几个数据

        int scores5[] = {1,3};

  (报错)注意5: 如果定义数组时没有进行初始化, 那么不能省略元素个数

        int scores6[];

  可通过[索引] = 的方式, 给指定索引的元素赋值

        int scores7[101] = {[99]=1,[100]=5};

  (报错)注意6: 只能在定义的同时 利用{}进行初始化,如果是先定义 那么就不能使用{}进行初始化

        如果先定义 那么就不能再进行整体赋值, 只能单个赋值

        int scores8[3];

        scores8 = {1,3,4};
15-数组-遍历
    // 注意 : 在遍历数组的时候, 尽量不要把遍历的次数写死

    // 遍历多少次应该 由数组来决定 , 也就是说遍历多少次 应该通过数组计算得出

    /*

    printf("scores = %lu\n",sizeof(scores)); // 计算出数组中占用的总字节数

    printf("socre[0] = %lu\n",sizeof(scores[0])); // 计算出数组中某一个元素占用的字节数

    printf("一个有多少个元素 : %lu\n",sizeof(scores) / sizeof(scores[0]));

    */

    // 动态计算数组的元素个数

    int length = sizeof(scores) / sizeof(scores[0]);

推荐阅读更多精彩内容

  • 1.编译程序(1)gcc xx.c,他会默认生成一个a.out的可执行文件,在a.out所在目录,执行./a.o...
    萌面大叔2阅读 155评论 0 1
  • 基础 .NET概述 参考:http://www.cnblogs.com/yplong/p/3279934.html...
    donite阅读 359评论 0 8
  • 1、标识符 什么事标识符呢?变量的名字就是标识符。不仅限于变量名,程序中各种元素的名字,都属于标识符。例如符号常量...
    滕王阁序阅读 227评论 0 0
  • Win7下如何打开DOS控制台? a:开始--所有程序--附件--命令提示符 b:开始--搜索程序和文件--cmd...
    逍遥叹6阅读 373评论 2 11
  • “不愿想起你,怪自己没勇气 心痛的无法呼吸,找不到你留下得痕迹 眼睁睁的看着你,却无能为力 任...
    大树与洞阅读 51评论 0 2