C基础复习纪要

C基础复习纪要

基本概念

  • 程序编译、链接过程:

    • 编译器 -> 将各个源代码.c文件生成各个.o文件
    • 链接器 -> 将各个.o文件进行链接,生成可执行文件;
  • 执行:程序载入内存 -> rom:

    • 运行时堆栈:保存函数的局部变量和返回地址
    • 静态内存:保存程序整个运行过程中的静态(static)变量
  • static关键字:修饰链接属性为external的变量,改变其链接属性为internal;但是对属性不是external的变量无效

  • extern关键字:修饰链接属性为none的变量,使其链接属性为external;但是对已经修饰为static 的变量无效

  • 变量存储类型:

    • 静态变量:在任何代码块之外声明的变量,不属于堆栈内存,在程序整个运行过程中均存在;
    • 自动变量:代码块内部声明的变量(特例:将代码块内部声明的变量声明为static,将转为静态变量);
    • 寄存器变量:用register关键字声明的变量,提示用于访问硬件寄存器中的地址,而不是rom,建议不要自行命名register变量,现代编译器会替我们做此类工作,手动分配若超出硬件寄存器大小反而会降低程序执行的效率;
    • 函数的形参不能转为静态变量:由于函数的传参在堆栈中进行,用于支持递归;
  • 指针:

    • 非初始化和非法指针:

      /* 未初始化的指针,a的初始值不可预知,将造成段错误或者内存错误 */
      int *a;
      *a = 10;
      
  • ADT和黑盒:抽象数据类型和函数接口 -> 用户只关心接口功能,不用关心具体实现

结构和联合

  • 结构的自引用:

    /* 非法自引用,_SELF_REF b成员是另一个完整结构,递归下去时编译器将无法知道结构体大小 */
    struct _SELF_REF {
    	int a;
    	_SELF_REF b;
    };
    
    /* 非法自引用,SELF_REF b直到 } 最后才被定义 */
    typedef struct  {
    	int a;
    	SELF_REF *b;
    } SELF_REF;
    
    /* 合法自引用,_SELF_REF *b成员是另一个完整结构的指针, 大小可被编译器获知 */
    struct _SELF_REF {
    	int a;
    	_SELF_REF *b;
    };
    
  • 联合:不同成员引用相同的***内存中的位置***,联合变量的初始化值,类型需与该联合的第一个成员变量的类型相匹配

动态内存的释放

  • 常见内存释放的错误原因:
  1. 试图解构NULL指针;
  2. 试图释放非动态内存分配的内存;
  3. 试图释放动态分配的内存的一部分;
  4. 试图访问已经被释放的内存;
  • 关于传递给其他函数的用于内存释放的形参,为什么需要传递指针的指针,原因是基于第3点,传递指针的指针,再进行解构时,位置将是动态内存分配的起点地址,而直接传递指针进行释放,有可能造成第3点错误,因为指针位置可能已经不位于先前进行动态内存分配的初始地址;

高级指针特性

  • 函数指针

    • 作用

      1. 可实现回调函数指针,作为形参传入其他模块调用,相当于copy了一份函数的地址给其他模块进行调用;

        // main.c:
        typedef int (*work_status_change_handle)(status_e status);
        
        int work_status_change_handle(status_e status)
        {
            ret = ST_SUCCESS;
            ... ...
            return ret;
        }
        
        int main(void)
        {
            work_handler_regist(work_status_change_handle);
        }
        
        //----------------------------------------------------------------------------------------------------------------------------------------------//
        
        // work_handler.c:
        void work_handler_regist(work_status_change_handle status_change_callback_func)
        {
            ... ...
            return;
        }  
        
        
      2. 可实现转移表,简化swtich语句走不同的函数处理逻辑,用一张转移表即可实现;

        /* 不同网络类型的网络的状态查询实现,利用转移表代替繁琐的switch语句 */
        network_state_e network_state_get(net_type_e net_type)
        {
            st_int32_t ret = NET_CONNECTED;
        
            network_state_e (*state_func_list[])(void) = {
                [NET_E1] lan_e1_state_get,
                [NET_LTE] lte_state_get,
                [NET_ETH] lan_eth_state_get,
                [NET_PON] lan_pon_state_get
            };
        
            ret = state_func_list[net_type];
            
            return ret;
        }
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值