c语言第七天

复习:
    进制转换:
        十进制转二进制:
            求余:对2求余,直到商为0,余数结果逆序就是二进制
            求权:数据 - 2^(n-1) 能减为1,否则0
        二进制转十进制:
            2^(n-1) 求和
        二进制转八进制:
            从低位开始,每三个二进制对应一个八进制位
        二进制转十六进制:
            从低位开始,每四个二进制对应一个十六进制位
        以0开头的数据是八进制数据,以0x\0X开头是十六进制
        %o %x %#o %#x
   
    原码、反码、补码:
        正数、无符号数的原码就是补码、反码
        负数:先得到原码,符号位不变,其余按位求反得到反码,反码+1得到补码

        无符号的补码直接转数据
        有符号的最高位是0,也直接转数据
        有符号且最高位是1,先-1得到反码,符号位不变,其余按位求反得到原码,原码转数据
   
    位运算符:
        单目 算术 位 关系 逻辑 三目 赋值

        在位运算符中 ~ 优先级最高
        ^   异或
        >>  左边补符号位
        int num = 40;
        printf("%d\n",num >> 1 + 2); // num>>3
        printf("%d\n",num); // 40
   
    自定义函数:
        函数声明:
            返回值类型 函数名(类型1 变量名1,类型2 变量名2,...);
            1、如果函数不需要参数,要写void
            2、如果函数没有返回值,也要写void
            3、如果参数类型相同,不能省略后面的类型名
        隐式声明:
            在函数调用前没有出现函数声明或定义,那么编译器会猜测函数的返回值为int类型,如果猜对了会产生隐式声明的警告,如果没猜对会报错

        函数定义:
            返回值类型 函数名(类型1 变量名1,类型2 变量名2,...)
            {
                //函数体
                return [val];
            }
        函数调用:
            函数名(实参变量1,实参变量2,...);

---------------------------
函数传参
    1、函数中定义的变量属于该函数,出了该函数就不能再被别的函数直接使用
    2、实参与形参之间是以赋值的方式进行传递数据的,并且是单向值传递
    3、return语句其实是把返回值数据放入公共区域内存中(调用者和被调用者都可以访问),调用者会从该区域获取返回值;如果不写return语句,该区域会是一个随机的垃圾数据,调用者也能拿到返回值但是无意义。
    4、数组作为函数的参数传递时,数组的长度会丢失,需要额外增加一个变量把数组的长度传递过去
        void func(int arr[],int len);
        int arr[10];
        func(arr,10)
    5、数组作为参数传递时,是"址传递",相当于调用者与函数共享数组
    练习1:实现一个函数,找出数组中的最大值
    练习2:实现一个函数,对数组进行排序
    练习3:实现一个函数,查找数组中是否存在某个值,如果存在返回该数值在数组中的下标

设计函数的准则:
    1、一般一个函数最好不要超过50行,确保一个函数只负责完成一项功能,降低出错概率,提高可读性
    2、数据一般要由调用者提供,只把结果返回给调用者,确保函数的通用性
    3、考虑调用者提供的非法数据,可以先判断后使用,也可以通过注释或说明来写明情况,提高函数的健壮性

进程映像:
    程序:存储在磁盘上的可执行文件(二进制文件、脚本文件)
    进程:正在系统中运行的程序
    进程映像:进程的内存分布情况
        text    代码段:(代码段+只读段)
            存储的是二进制指令、常量,权限是只读,如果强制修改会产生段错误
        data    数据段:
            初始化的全局变量、初始化过的静态局部变量
        bss     静态数据段:
            未初始化的全局变量、未初始化的静态局部变量
            在该段内存中的数据在程序开始前会自动清理为0
        stack   栈:
            局部变量和块变量,会随着程序的运行不断地申请、释放,由操作系统管理,使用方便,内存小
        heap    堆:
            该段内存由程序员手动管理,使用麻烦,足够大

局部变量和全局变量:
    全局变量:定义在函数外的变量
        存储位置:data(初始化) 或者 bss(未初始化)
        生命周期:程序开始到程序结束
        使用范围:程序的任意位置都可以使用
    局部变量:定义在函数内的变量
        存储位置:stack 栈内存
        生命周期:从函数开始到函数结束
        使用范围:只能在该函数内使用
    块变量:定义在if/for/while等语句块内的变量
        存储位置:stack 栈内存
        生命周期:从语句块开始到语句块结束
        使用范围:只能在语句内使用
   
    注意:同名的局部变量会屏蔽同名的全局变量
        同名的块变量会屏蔽同名的全局、局部变量
        因此建议全局变量首字母大写,局部变量全部小写

类型限定符:
    auto
        用于定义自动申请、自动释放的变量(局部变量),不加就代表加了
        注意:在C11语法标准中用于自动类型识别
            auto num = 10;  //int
            auto num = 3.13;//double
        注意:不用用它修饰全局变量
    extern
        用于声明外部变量,意思是告诉编译器此变量在程序的其他地方已经定义了,先让程序通过编译,如果在链接时找不到该变量依然会报错
        不建议在extern时赋值,它只是声明

    static
       改变存储位置:
            改变局部变量的存储位置,由stack改为data(初始化)或者bss(未初始化)
       延长生命周期:
            延长局部变量的生命周期,直到程序结束才释放
       限制作用范围:
            限制全局变量的使用范围,限制只能在本文件内使用
            注意:使用static修饰全局变量,可以防止该变量被别的文件使用,以及防止命名冲突

    const
        "保护"变量的值不被显式地修改
        注意:如果通过内存进行修改,还是可以改的
        注意:使用const修饰data段数据,那么该数据会存储到text段中,如果强制修改会段错误
   
    volatile
        C编译器会对普通变量的取值进行"取值优化",只要在使用变量过程中该变量没有显式改变,那么编译器会直接使用上一次的结果,而不会每次都去内存读取数据
        加上volatile修饰,让编译器不要对该变量进行"取值优化"
        一般在驱动编程、硬件编程、多线程编程时使用
        volatile int num = 10;
        if(num == num)
        {
            //  可能为假
        }

    register
        存储介质:
            硬盘->内存->高级缓存->寄存器->CPU
        申请把变量的存储介质由内存改为寄存器,但是由于寄存器数量有限,不一定百分百成功
        注意:寄存器变量不能取地址

    typedef
        类型重定义
        在定义变量前,加上typedef,那么原本的变量名就变成了这种数据类型,可以像数据类型一样定义变量
        typedef int num;
        num n1;



       
posted @   mrlinan  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示