博客
关于我
C/C++函数与变量前面的标识符的作用
阅读量:415 次
发布时间:2019-03-06

本文共 2666 字,大约阅读时间需要 8 分钟。

C/C++ 中常用标识符解析

一、static 静态符号

概念介绍

static 是一个用来控制变量储存方式及可见性的关键字,常用于修饰变量和函数。它的使用位置决定了变量或函数的性质,包括静态函数、静态全局变量和静态局部变量。

具体使用区别

  • 静态函数

    • 屏蔽了函数外部的可见性,仅在定义文件中可用。
    • 内存中只保留一份函数拷贝,避免多个文件重复编译。
    static void fun(void) {
    ...
    }
    void fun(void) {
    ...
    }
  • 静态全局变量

    • 与普通全局变量不同,静态全局变量只能在定义文件中使用。
    • 初始化全局变量时,静态变量被初始化为全局区中的值。
    static Robot_t Robot;
    Robot_t Robot1;
  • 静态局部变量

    • 局部变量加上 static 之后,变量被存放在静态区。
    • 只初始化一次,程序结束时由系统释放。
    void fun(void) {
    static uint8_t robot;
    uint8_t robot1;
    }
  • 关键字对比表

    关键字 使用周期 作用域
    extern 编程执行 外部(整个程序)
    static 编程执行 内部(仅目标文件)
    auto、register 功能执行

    二、volatile 与 register 类型修饰符

    概念介绍

    • volatile:声明的变量可以被某些编译器未知的因素(如操作系统、硬件等)修改。
    • register:建议编译器将变量存放在寄存器中,以提高访问速度。

    两者的作用

    • volatile:确保每次访问变量时都从内存中读取,避免缓存优化带来的问题。
    • register:优化变量访问速度,但可能影响代码的可维护性。

    使用场景

    • volatile:多线程环境下的共享变量、硬件寄存器映射等。
    • register:用于频繁访问的变量,提升程序执行效率。

    示例

    volatile uint8_t robot;
    register uint8_t robot1;

    三、const extern

    概念介绍

    • const:修饰的变量为只读常量,不能修改。
    • extern:允许在其他文件中使用变量或函数。

    const 的使用场景

    • 数据为不可修改的常量。
    • 参数和返回类型也可以使用 const。

    示例

    const int a = 0;
    int const b = 0;

    const 修饰指针

    int const *a;
    const int *b;
    int *const c;
    const int *const d;

    const 修饰函数

    void test(const Class& Var); // 引用参数不可修改
    void test(const TYPE& Var); // 引用参数为常量

    四、__asm 汇编标识符

    概念介绍

    • __asm:用于嵌入汇编代码,支持在 C++ 中执行汇编指令。

    使用示例

    __asm volatile("BKPT #01");
    __asm void SystemReset(void) {
    MOV R0, #1
    MSR FAULTMASK, R0
    LDR R0, =0xE000ED0C
    LDR R1, =0x05FA0004
    STR R1, [R0]
    deadloop:
    B deadloop
    }

    五、attribute((at(address))) 指定地址

    概念介绍

    • 使用 attribute 修饰符可以指定变量的绝对地址。
    • 常用于将变量存放在特定内存区域。

    示例

    __align(32) volatile CPU_INT08U External_RamMemp[EXTERNAL_MEM_NUM][EXTERNAL_MEMBLOCK_SIZE] __attribute__((at(0x08004000)));

    变量存放位置

    • ROM 内存:使用 attribute((at(address))) 修饰。
    • RAM 内存:默认存放位置。

    六、__packed 与 attribute((packed))

    概念介绍

    • __packed:将结构体或联合体变量的成员对齐为 1 字节。
    • attribute((packed)):与 packed 等效。

    示例

    typedef __packed__ {
    uint8_t a : 1;
    uint8_t b : 1;
    uint8_t c : 1;
    uint8_t d : 1;
    uint8_t e : 1;
    uint8_t res : 3;
    } StructTypef;
    typedef struct __attribute__((__packed__)) {
    uint8_t a;
    char b;
    } StructTypef;

    七、inline 内联函数修饰符

    概念介绍

    • inline:建议编译器对函数进行内联展开,减少函数调用开销。

    使用示例

    inline Robot_t* Robot_Get_Base(void) {
    return &Robot;
    }

    优缺点

    • 优点:提高执行效率。
    • 缺点:函数复杂或含有循环时不建议使用。

    八、__irq 中断函数标志

    概念介绍

    • __irq:标记中断函数,确保编译器正确处理中断入口和退出。

    示例

    __irq void USART2_IRQHandler(void) {
    if (USART2->ISR_USART_ISR_RXNE) {
    USART2->ISR &= ~USART_ISR_RXNE;
    cyclic_buffer_push(&s_comm.s_cyclic_rx_, USART2->RDR);
    }
    }

    九、attribute((weak)) 弱符号标识

    概念介绍

    • 弱符号:在链接时优先于同名强符号。
    • 使用场景:定义未初始化的全局变量,避免因未定义符号导致错误。

    示例

    void __attribute__((weak)) f();
    int main(void) {
    if (f) {
    f();
    return 0;
    }
    }

    通过以上标识符的学习与应用,我们能够更好地理解 C/C++ 代码的特性,提升代码的安全性和性能。更多技术文章请关注 良知犹存的技术博客

    你可能感兴趣的文章
    node-static 任意文件读取漏洞复现(CVE-2023-26111)
    查看>>
    Node.js 8 中的 util.promisify的详解
    查看>>
    node.js debug在webstrom工具
    查看>>
    Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
    查看>>
    Node.js RESTful API如何使用?
    查看>>
    node.js url模块
    查看>>
    Node.js Web 模块的各种用法和常见场景
    查看>>
    Node.js 之 log4js 完全讲解
    查看>>
    Node.js 函数是什么样的?
    查看>>
    Node.js 函数计算如何突破启动瓶颈,优化启动速度
    查看>>
    Node.js 切近实战(七) 之Excel在线(文件&文件组)
    查看>>
    node.js 初体验
    查看>>
    Node.js 历史
    查看>>
    Node.js 在个推的微服务实践:基于容器的一站式命令行工具链
    查看>>
    Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
    查看>>
    Node.js 异步模式浅析
    查看>>
    node.js 怎么新建一个站点端口
    查看>>
    Node.js 文件系统的各种用法和常见场景
    查看>>
    Node.js 模块系统的原理、使用方式和一些常见的应用场景
    查看>>
    Node.js 的事件循环(Event Loop)详解
    查看>>