进制

 函数

        代码的打包

    

  函数的语法

        1)  void func() { ... }

        2)  void func(int min, int max) { ... }

        3)  int func() { ... }

        4)  int func(int min, int max) { ... }

  函数的一个调用

        func();

        int num = func();

   return 

        1) 无返回值函数  遇到 return 结束函数

        2) 有返回值函数  结束函数, 同时将值返回

            int func() {

                return 10;

            }

            int func() {

                return (10);

            }

   函数的嵌套使用

        在函数 func1 中调用函数 func2

        那么可以利用 func1 去调用 func2

    

        同时可以利用 func1 实现对 func2 函数的补充

 

    7, 递归函数

        1) 找到递推关系 -> 得到递归体

        2) 找到临界条件 -> 跳出递归

 */

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

    // 数位

    // 基数

    // 权值

    

    // 111

    // 需要指明某一个数字在第几位上(从右往左, 0 开始数)

    

    // 基数是指组成这个进制数字的所有的数字符号

    // 10进制: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

    // 8: 0, 1, 2, 3, 4, 5, 6, 7

    // 2: 0, 1

    // 16: 0, 1, 2, 3 ,4 ,5 ,6 ,7, 8, 9, a, b, c, d, e, f

    

    // 所谓的进制只是计数的方式

    // 10:   10

    // 2:    1010

    // 16:   0xa

    // 8:    012

    

    

    // 权值,表示这个 数码 * 基数个数 ^ 数位

    // 123

    // 1 * 10^2   100

    // 2 * 10^1   20

    // 3 * 10^0   3



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

 // 十进制的表示就是与平常书写一样

    

    int num1 = 123;

    

    // 八进制的表示是使用 数字0 和一个数字表示,这个数字就是八进制的

    

    int num2 = 07; // => 7

    int num3 = 011; // => 9

    // printf("%d\n%d\n", num2, num3);

    

    // 十六进制表示使用 0x 开头,然后紧跟一个十六进制数字

    int num4 = 0x9; // => 9

    int num5 = 0x11; // => 17;

    int num6 = 0xc; // => 12;

    // printf("%d\n%d\n%d\n", num4, num5, num6);

    

    // 二进制的表示使用 0b 开头,然后跟上一个二进制数字

    int num7 = 0b11111111; // 255

    char ch = 0b11111111; // ? -128 -1



---------------------------------------进制 转换-------------------------------------------------------------


 // 二进制数转八进制数

    // 1) 将二进制数从右往左三个分组,左边不够的补零

    // 2) 查表,将每组的二进制数表示成八进制数

    // 3) 从左往右取八进制数即可

    

    int num1 = 0b1111000000001111;

    // (001)(111)(000)(000)(001)(111)

    //   1    7    0    0   1     7

    // 0170017

    

    // 八进制转二进制

    // 1) 每一个八进制数都查表转换成二进制数即可

    // 2) 不要写错

    int num2 = 0123;

    // 123

    // (001)(010)(011)

    // 0101 0011

    

    

    

    // 二进制转十六进制

    // 1) 将二进制数从右往左四个分组,左边不够的补零

    // 2) 查表,将每组的二进制数表示成十六进制数

    // 3) 从左往右取十六进制数即可

    

    int num3 = 0b1111000000001111;

    // (1111)(0000)(0000)(1111)

    // 0xf00f

    

    // (1111)(0000)(0011)(1111)

    //  f       0     3     f

    // 0xf03f

    

    

    // 十六进制转二进制

    // 每一个十六进制数都转换成4个二进制数

    int num4 = 0x123;

    // 0001 0010 0011

    

    

    

    for (int i = 0; i < 16; i++) {

        printf("%d\t%o\t%x\n", i ,i, i);

    }

    

    


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

// 二进制转十进制

    // 按权展开

    // 123 = 100 + 20 + 3

    // 11011011

    // 2^7 + 2^6 + 2^4 + 2^3 + 2^1 + 2^0

    // 128 + 64 + 16 + 8 + 2 + 1

    // 219

    

    // 推导出一个结论,任意进制的数据,转换成 10 进制数,都是按权展开

    // 0x123

    // 1*16^2 + 2*16^1 + 3

    // 256 + 32 + 3

    // 291

    

    

    

    // 十进制数转二进制数

    // 除以2倒取余数法

    // 12 -> 二进制

    

    // 133 -> 1000 0101

    

    // 基数   原数

    // 基数    试商      余数

    // 基数    试商      余数

    // 基数    试商      余数

    //         0

    

    

    

    

    // 133 -> 十六进制

    // 得到一个结论:十进制数转换成其他进制数,只需要除以基数个数倒取余数法即可

    

    

    

    

    

    

    // 2, 8, 10, 16

    // 2,8      三合一查表

    // 2,16     四合一查表

    // 2,10     按权展开

    // 8,10     按权展开

    // 8,16     先二后十六

    // 10,16    除以16倒取余数

    // 8,2      一拆三

    // 16,2     一拆四

    // 10,2     除以2倒取余数

    // 10,8     除以8倒取余数

    // 16,10    按权展开

    


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

 // 机器码与真值

    

    // 什么是真值, 就是我们刚刚计算的进制数

    // 在计算机中表示一个数字: 1, -1, 0

    // 转换成二进制: 1, 0, -1?

    // 二进制数从左往右数的第0为表示符号位,如果符号为0表示正数,如果符号为1表示负数

    // 1 -> 0000 0001

    // 0 -> 0000 0000

    // -1 -> 1000 0001

    // 真值就是最高位表示符号位,将数字以二进制表示的数据显示结果

    

    

    // 数据的真值可以说是一个理论值,而计算机硬件中不会这么表示

    // 计算机硬件中表示数据的方式称为机器值,或机器码

    

    // 一般也将真值叫做原码

    

    // 计算机中存储的是数据的补码




    原码就是数字理论计算的值

        最高位为符号位, 数字以二进制表示

    反码是为了计算补码而提出来的

        反码就是原码除了最高位符号位以外,所有位上的数据01互换

        原码:1001001

        反码:1110110

    补码是计算机中数据的真实表示结果

        正数的补码与原码相同

        负数的补码是反码 + 1

 

    数字:-3

    原码: 1000 0011

    反码: 1111 1100

    补码: 1111 1101

 

 

    1111 1101 + 1 => 1111 1110 + 1 => 1111 1111 + 1 = 0000 0000

 

    给你一个数字,你要会算出原码,反码和补码

 

    -123

    原码: 1111 1011

    反码: 1000 0100

    补码: 1000 0101


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


    在函数中,声明的局部变量,存储在栈内存中

    1)函数中的变量,默认的存储形式是从高地址向低地址存储

    2)内存会因为计算机的结构会对杂乱的内存进行优化(内存的分配不再一般化)

    3)数据存储大端对齐与小端对齐概念

 

 

    // 写一个数字:

    // 十进制: 1234

    // 二进制: 110110

    // 左边是大数,右边是小数

    

    // 内存结构(内存可以看做是从 0 开始编号的一()列盒子)

    // 这里每一个盒子都可以放置一个二进制位 

    //                                            

    //      [][][1][1][0][1][1][0][][][][][][][][]

    //      [][][0][1][1][0][1][1][][][][][][][][]

 

 

 

    // 打印变量的地址,使用 &变量名 获得变量的地址, 使用 %p 打印地址

 

    // 一个int类型的数据, 4 个字节

    // &获得的地址是哪一个?

    // 获得的是首地址(低地址)

 

 

    // C语言中支持指针数据类型,用来表示内存的地址

    // 使用指针类型的变量,有一个算术运算需要注意

    // p = 0x12345678; (伪代码)

    // 指针变量 + 1 实际含义是指针的地址按照类型进行偏移

    // p(char) p+1 => 0x12345679

    // p(int)  p+1 => 0x1234567c

 

    // 有一个运算符 * 叫做取值运算符(寻址运算符)

    // 可以得到地址所表示的值

    // *p   p表示的这个地址中的数据,按照p的数据类型读取出来

 

    // p 地址指向一个内存  内存中存储的是 97

    // p(char)   *p   'a'

    // p(int)    *p   97

 

 */


-------------------------------位运算---------------------------------------------------------------------

位运算,都是将变量的数据取出来运算,得到一个新的数据,不会修改原来的数据


void  _0按位与() {


    // 按位与

    // &

    /*

     0 & 0 == 0

     1 & 0 == 0

     0 & 1 == 0

     1 & 1 == 1

     */

    int num1 = 2;

    int num2 = 3;

    

    int res1 = num1 & num2;

    // 0000 0010

    // 0000 0011

    // 按位与就是将每一个二进制位上的数据进行运算

    // 0000 0010

    printf("%d\n", res1);

    

    // num & 0001 0000 == 0001 0000  0000 0000

    

    // 使用按位与运算,可以得到某个数字的某一个二进制位上的值

    

    

}




void _0按位或() {


    /*

        按位或就是将每一个二进制位上的数据进行或运算

     

        0 | 0 == 0

        1 | 1 == 1

        1 | 0 == 1

        0 | 1 == 1

     

     */

    

    int num1 = 2;

    int num2 = 3;

    

    // 0000 0010

    // 0000 0011

    // =>

    // 0000 0011

    printf("%d\n", num1 | num2);


}





void _0按位异或() {


    /*

        按位异或

        ^ 如果某一位上的两个数字是相同的,那么值为0,如果不同则为1

        1 ^ 1 == 0

        0 ^ 0 == 0

        1 ^ 0 == 1

        0 ^ 1 == 1

     */

    

    int num1 = 2;

    int num2 = 3;

    

    // 0000 0010

    // 0000 0011

    // 0000 0001

    

    printf("%d\n", num1 ^ num2);

}



void _0按位取反() {


    printf("%d\n", ~1);

    

    // -2

    // 1000 000...0000 0010

    // 1111 111...1111 1101

    // 1111 111...1111 1110

    

    

    

    // 1

    // 0000 0000 ... 0000 0001

}



void _0左移与右移() {


    /*

        << 左移运算符

     

        二进制位上数字,每一个向左边移动n个二进制位

     */

    

//    int num1 = 2;

//    // 0000 0010

//    // int num2 = num1 << 1;   // num1 * 2^1   // << 3     num1 * 2^3

//    //

//    for(int  i = 0; i < 10; i++) {

//        printf("%d\n", num1 << i);

//    }

    

    

    /*

        右移运算符,是将每一个二进制位的数字向右边移动n

     

        *不同的平台实现不一样

        *下面只介绍苹果的平台

        

        右移以后超出的数据丢失,左边补符号位

        1000 0010

        1100 0001

        0100 0001

     */

}



------------------------------------偶数----------------------------------------------------------------

 int num = 2;

    

    // 计算 num * 8;

//    printf("%d\n", num * 8);

//    printf("%d\n", num << 3);  // 推荐使用这个方法

    

    // 2   10

    // 4   100

    // 6   110

    // 8   1000

    

    // 判断一个数字是否为偶数

    // num & 1 != 1

    while(1) {

        int num1 ;

        scanf("%d", &num1);

        if((num1 & 1) == 1) {

            printf("是奇数\n");

        } else {

            printf("是偶数\n");

        }

    }



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

void test() {

    //    int num = 123;

    

    // 0:  num & 1

    // 100101010010101000

    // 000000000000000001

    // 000000000000000000 => 0 1

    // 1:  num & 2  == 2     0

    // (num & 2)) != 0 就是1

    

    // (num & (1 << 31)) >> 31

    

    //    for(int i= 0; i< 31; i++) {

    //        if(i % 4 == 0) printf(" ");

    //        // printf("%d", (num & (1 << i)) >> i);

    //        printf("%d", (num & (1 << i)) == 0 ? 0 : 1  );

    //    }

    

    //    printf("\n");

    

  

    // 数字:   1001 1001

    // (num >> 7) & 1  => 最高位的结果

    // (num >> 6) & 1  =>

    // ...

    // (num >> 0) & 1  => 0位的结果

    


}



void test1() {

    // 打印一个数字的二进制数,就是要获得每一个二进制位的 0 还是 1

    // 123

    // 000... 0000 0111 1011

    // 得到第0

    //      000... 0000 0111 1011 & 1  ==> 1

    //                              1 << 0

    // 得到第1

    //      000... 0000 0111 1011 & 10 ==> 0000...00 0010  ==> 10 ---> 10 >> 1 == 1

    //                              1 << 1

    // 得到第2

    //      000... 0000 0111 1011 & 100 ==> 0 ==  0>>2 == 0

    //                              1 << 2

    

    // 得到第3

    //      000... 0000 0111 1011 & 1000 ==> 1000 ----> 1000 >> 3 == 1

    //                              1 << 3

    

    

    // 获得 32 个位

    // 0 -> 31

    

    //  == 0 ? 0 : 1

    //  >> 次数位

    

    // (num & (1 << i)) >> i

    // (num & (1 << i)) == 0 ? 0 : 1

}



void printBinaryWithInt(int num) {

    for(int i = 31; i >=0; i--) {

        printf("%d", num >> i & 1);

    }

    

    printf("\n");

}


int main(int argc, const char * argv[]) {

    

    // 打印一个数字的二进制数,就是要获得每一个二进制位的 0 还是 1

    // 123

    // 000... 0000 0111 1011

    // 这个数字先右移31

    // ... 30

    // ... 29

    // ...

    // 1

    // 0

    

//    int num = 123;

//    

//    for(int i = 31; i >=0; i--) {

//        printf("%d", num >> i & 1);

//    }

//    

//    printf("\n");

    

    // 1010 1010

    // >> 7

    // 1111 1111 & 1 ==> 1    7

    //

    // >> 6

    // 1111 1110 & 1 ==> 0    6

    //

    // >> 5

    // 1111 1101 & 1 ==> 1     5

    // ...

    // >> 1

    // 1101 0101 & 1 ==> 1     1

    //

    // >> 0

    // 1010 1010 & 1  ==> 0     0

    

    

    printf("请输入一个数字\n");

    int num;

    scanf("%d", &num);

    

    printBinaryWithInt(num);

    

    

    

    

    

    

    

    

    

    

    

    

    int num1 = 10;

    int num2 = 5;

    

    // ...

    

    printf("num1 = %d, num2 = %d\n", num1, num2); // 5 10

    

    

    return 0;

}


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



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



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


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值