学习标准C语言day6

函数传参

    1、函数中定义的变量属于该函数,出了该函数就不能再被别的函数直接使用

    2、实参与形参之间是以赋值的方式进行传递数据的,并且是单向值传递//实给形

    3、return语句其实是把返回值数据放入公共区域内存中(调用者和被调用者都可以访问),调用者会从该区域获取返回值;如果不写return语句,该区域会是一个随机的垃圾数据,调用者也能拿到返回值但是无意义。

    4、数组作为函数的参数传递时,数组的长度会丢失,需要额外增加一个变量把数组的长度传递过去

        void func(int arr[],int len);

        int arr[10];

        func(arr,10) 此时的arr是指针

    5、数组作为参数传递时,是"址传递",相当于调用者与函数共享数组,没有重新申请一个内存来放数组

设计函数的准则:

    1、一般一个函数最好不要超过50行,确保一个函数只负责完成一项功能,降低出错概率,提高可读性

    2、数据一般要由调用者提供,只把结果返回给调用者,确保函数的通用性

    3、考虑调用者提供的非法数据,可以先判断后使用,也可以通过注释或说明来写明情况,提高函数的健壮性

 

进程映像:

    程序:存储在磁盘上的可执行文件(二进制文件、脚本文件)

    进程:正在系统中运行的程序  //程序可以开多个进程

    进程映像:进程的内存分布情况

        text    代码段:(代码段+只读段)

            存储的是二进制指令、常量,权限是只读,如果强制修改会产生段错误

        data    数据段:

            初始化的全局变量、初始化过的静态局部变量

        bss     静态数据段:

            未初始化的全局变量、未初始化的静态局部变量

            在该段内存中的数据在程序开始前会自动清理为0

           特殊情况:初始化为0相当于未初始化

heap    堆:(理论上 内存有多大 堆就有多大)

            该段内存由程序员手动管理,使用麻烦,足够大//不清理 可能会发生内存泄漏

        stack   栈:

            局部变量和块变量,会随着程序的运行不断地申请、释放,由操作系统管理,使用方便,内存小//不需要手动申请

局部变量和全局变量:

    全局变量:定义在函数外的变量

        存储位置: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;

        #define num int

        num n1;           使用上没区别  本质上有区别:前者类型重定义,后者替换

        typedef int* num;

        num  p1,p2,p3;   3个都是指针

        #define num int*

        num p1,p2,p3;   只有第一个是指针

函数递归:

    函数自己调用自己的行为,叫做函数递归

    递归是分治思想的一种具体实现,就是把一个复杂而庞大的问题,分解成若干个相似的小问题,解决所有小问题,最终大问题得到解决

    如果函数递归缺少出口设置,容易出现类似死循环的效果,且很快内存耗光程序异常结束

    注意:如果能用循环解决的问题,不要用递归,因为递归比循环更耗时耗内存

    1、出口 *

    2、解决一个小问题

    3、调用自己

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值