c语言第六天

进制转换:
1、为什么使用二进制、八进制、十六进制?
    因为目前的CPU只能识别高低两种电平,只能对二进制数据进行计算
    二进制虽然能够直接被计算机识别,但是不方便人去书写和记录,因此就把二进制数据转换成八进制,方便记录到文档中
    随着CPU的位数的不断增加,已经到目前的64位,所以八进制不再能够满足需求,因此发展出现在的十六进制,由于历史原因八进制还不能退出历史舞台

2、十进制转二进制(其它进制)
    求余法:
        用2不停地对数据求余,然后继续对商求余,直到商为0结束,在过程中得到的余数(逆序)就是该数据的二进制
        127 % 2     1
         63 % 2     1
         31 % 2     1
         15 % 2     1
         7  % 2     1
         3  % 2     1
         1  % 2     1
                    0  
        0111 1111
    求权法:
        让数据从高位n位开始,数据 - 2^(n-1) ,如果够减,那么第n位为1,否则为0,直到减完为止
    134
       128 64 32 16 8 4 2 1
        1   0  0 0  0 1 1 0
    手算:73 62 121 49

    练习1:输入一个正整数m,然后输入n(n>=2),显示m的n进制结果,超过10的位用字母表示
        10  A  11 B  12 C ...
        gcc xxx.c && ./a.out
   
3、二进制转十进制
    每位乘以权位2^(n-1),求和
    10011001  128+16+8+1

4、二进制转八进制
    从低位起,每三个二进制位对应一个八进制位
    二进制:10 101 110 111 100
    八进制:2   5   6   7   4

5、二进制转十六进制
    从低位起,每四个二进制位对应一个十六进制位
    二进制:  10 1011 1011 1100
    十六进制: 2  B    B    C

6、不同进制在程序的显示:
    在C代码中,以0开头的数据是八进制数据,以0x/0X开头的是十六进制数据
        %x  让数据以十六进制显示
        %o  让数据以八进制显示
        %#x %#o 显示出数据对应的进制前缀

7、原码、反码、补码
    原码:数据的二进制
    反码:
        正数的原码就是反码
        负数的反码是:它的原码符号位不变,其它位按位求反
    补码:
        所有数据在计算机中,都是以补码形式存储
        正数的原码就是补码
        负数的补码:
            1、转换成二进制,得到原码
            2、原码符号位不变,其余按位求反,得到反码
            3、反码+1,得到补码
    -127
    1111 1111   原码
    1000 0000   反码
    1000 0001   补码

8、补码如何转成数据:
    先确定是有符号还是无符号
        1、无符号\有符号且最高位为0,补码直接转成十进制
        2、有符号的且最高位为1
            a、补码-1,得到反码
            b、符号位不变,其余位按位求反,得到原码
            c、原码转十进制数
        1111 1111   补码
        1111 1110   反码
        1000 0001   原码
                    -1
        127+1 = -128
        0111 1111 + 1
        1000 0000 -128
        for(uint8_t i=0; i<256; i++)
        {
            printf("a");
        }

位运算符:
    &  |  ~   ^  <<  >>
    A & B   按位相与
        1010 1110   A   0xAE
        0111 1100   B   0x7C
        --------------
        0010 1100   C   0x2C
   
    A | B   按位相或
        1010 1110   A   0xAE
        0111 1100   B   0x7C
        --------------
        1111 1110   C
   
    ~A      按位求反
        1010 1110   A   0xAE
        -----------
        0101 0001
   
    A ^ B   按位异或    相同为零,相异为一
        1010 1110   A   0xAE
        0111 1100   B   0x7C
        --------------
        1101 0010
   
    A << n  按位左移n位,左边超出的丢弃,右边补0
        1010 1110   A << 3
        0111 0000  

    A >> n  按位右移n位,右边超出的丢弃,左边补符号位
        1010 1110   A >> 3
        1111 0101
   
    注意:只要式子中出现了位运算符,必须转换成二进制补码再进行运算
 
    练习2:输入一个整数,把它的4~7位设置为1010,其余位不变
        & | ~ << >>
    num:    10 1000 1011 1101   32  << 3
            00 0000 0000 1111 0xf
            00 0000 1111 0000 0xf<<4
            11 1111 0000 1111 ~(0xf<<4)
            10 1000 0000 1101 num & ~(0xf<<4)
            00 0000 1010 0000 0xA0
            10 1000 1010 1101 num & ~(0xf<<4) | 0xA0
            printf("%d\n",num & ~(0xf<<4) | 0xA0);
   
函数:Function
    一段具有某一项功能的代码集合,是C语言管理代码的最小单位
    把代码封装成一个个函数,方便管理和调用代码
1、函数分类:
    标准库函数:
        C语言标准委员会以函数形式提供的一些基础功能,都被封装在libc.so库中,并且分在了不同的文件中,需要使用时只要把对应的头文件导入即可(例如stdio.h...),然后通过具体的 函数名(参数) 即可完成调用
        #include <time.h>
        time_t time(time_t *tloc);
        功能:获取自1970-1-1 0:0:0 到调用时总共过了的秒数
        用法:time_t sec = time(NULL);

        #include <stdlib.h>
        int rand(void);
        功能:获取一个随机数
        注意:目前任何编程语言和系统都没有真正的随机数,C编译器是把从0~极大值范围的数值打乱后,存储到一块固定内存中,然后从里面取所谓的随机数

        void srand(unsigned int seed);
        功能:种随机种子,设置从随机数内存的某个位置开始取随机数,为了实现类似真随机的效果,seed位置一般使用time(NULL)来设置

        int system(const char *command);
        功能:执行系统命令command
        例如:system("clear");

    练习3:获取10个范围[100,1000]之间的随机数,获取次数不能超过10次
        rand()%901 + 100 [a,b]
        rand()%(b-a+1) +a
    练习4:双色球规则:6个红球范围1-33 1个蓝球范围1-16
    通过程序产生一组随机的中奖号码:红球不能重复
        rand()%33+1
        rand()%16+1

    系统函数:
        是操作系统以函数形式提供的一些功能接口
        但是系统函数不是真正的函数

    第三方库函数:
        一些开源或收费的第三方代码
        GitHub
        md5
        JSON 序列化和反序列化
        100   "100"  "100"  100
        glog  谷歌日志系统
        XML 配置文件解析程序

    自定义函数:
        为了更好地管理代码,减少代码冗余,把代码封装成自定义函数

        函数声明:
            函数声明的目的为了告诉其他的调用者,该函数的调用格式

    返回值类型 函数名(形参类型1 形参名,形参类型2 形参名,...);
        1、C语言中函数名一般全部小写,可以用下划线分隔
        2、如果不需要参数时,建议写void,不要空着
        3、如果没有返回值,就写void

        函数定义:
            函数的具体实现
    返回值类型 函数名(形参类型1 形参名,形参类型2 形参名,...)
    {
        //  函数体
        return [val];
    }
     
        函数调用:
            函数名(实参1,实参2);
            注意:返回值会放在调用函数语句这里,应该用变量接收或者直接显示,否则再也拿不到
   
    使用函数需要注意的问题:
        函数的隐式声明:
            在函数调用前没有任何该函数的声明或定义,那么就会产生隐式声明
            要避免产生隐式声明,那么就需要在函数调用前有函数声明或函数定义
    注意:如果在函数调用前完成了函数的定义,那么函数声明可以省略
    作业1:实现一个函数,判断一个整数是否是素数,调用它显示100~1000之间所有的素数
    作业2:输入两个日期(yyyy-mm-dd),计算两个日期间隔的天数,考虑代码冗余问题
    作业3:实现一个函数,判断一个整数是否需是回文数,调用该函数显示出1亿~10亿之间的所有回文数
    作业4:计算出100的阶乘
    93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
    char ret[200]
    作业5:输入一个整数,显示出它的补码
posted @   mrlinan  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
· 易语言 —— 开山篇
点击右上角即可分享
微信分享提示