• 第4章 C语言高级的关键字


    文档配套视频讲解链接地址

    1. 腾讯课堂视频链接地址 : 18_关键字_static关键字
    2. 腾讯课堂视频链接地址 : 19_关键字_extern关键字
    3. 腾讯课堂视频链接地址 : 20_关键字_volatile关键字

    第04章 关键字

    4.1 static 关键字的深入理解

    1. static 关键字修饰局部变量
    • 延长局部变量的生存期, 由原来的动态生存期变为静态生存期, 这个变量的值只能被初始化一次 , 值可以继承 。
    • 实例35
    • static 修饰局部变量,延长生存期
    • 源文件
    linux@ubuntu:~/work/emb2207/03-chigh/35-static$ tree
    .
    ├── build
    ├── CMakeLists.txt
    ├── main.c
    └── src
        ├── beep.c
        ├── beep.h
        ├── led.c
        └── led.h
    
    2 directories, 6 files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 源代码
    linux@ubuntu:~/work/emb2207/03-chigh/35-static$ cat main.c 
    #include  
    
    #include "led.h"
    #include "beep.h"
    
    
    int main(int argc, char const *argv[])
    {
        led_on(); 
        led_off();
        char * p = beep_on();
        printf("*p=%s\n",p);
    
        p = beep_on();
        printf("*p=%s\n",p);
        
        p = beep_on();
        printf("*p=%s\n",p);
    
    
        return 0;
    }
    linux@ubuntu:~/work/emb2207/03-chigh/35-static$ cat src/beep.c 
    #include   
    
    char * beep_on(void)
    {
        
        static int a = 10 ; // static 修饰局部变量, 只能被初始化一次  , 值可以保持 
        static int b ; // static 修饰的局部变量 没有赋初始值, 初始值为0 
        static char buf[100]={"hello world!!"}; 
        a++; 
        b++;
        printf("beep_on:a=%d\n",a);
        printf("beep_on:b=%d\n",b);
        printf("beep_on\n");
    
        return  buf ; 
    }
    
    int beep_off(void) 
    {
        printf("beep_off\n");
    
        return 0; 
    }
    linux@ubuntu:~/work/emb2207/03-chigh/35-static$ cat src/beep.h
    #ifndef _BEEP_H
    #define _BEEP_H
    
    char * beep_on(void);   // 函数的声明 
    int beep_off(void) ; // 函数的声明 
    
    #endif  linux@ubuntu:~/work/emb2207/03-chigh/35-static$ cat CMakeLists.txt 
    cmake_minimum_required (VERSION 2.8)      
    
    project (main)
    
    include_directories(. src)    # 添加标准头文件的搜索路径 , 程序中可以使用 include <>
      
    aux_source_directory(.   SRC_LIST1)    # 获取目录下的源文件 
    aux_source_directory(src SRC_LIST2)    # 获取目录下的源文件 
    
    
    add_executable(main ${SRC_LIST1} ${SRC_LIST2}) 
    
    linux@ubuntu:~/work/emb2207/03-chigh/35-static$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 运行结果
    linux@ubuntu:~/work/emb2207/03-chigh/35-static/build$ cmake ..
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/linux/work/emb2207/03-chigh/35-static/build
    linux@ubuntu:~/work/emb2207/03-chigh/35-static/build$ make 
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/src/beep.c.o
    [ 50%] Linking C executable main
    [100%] Built target main
    linux@ubuntu:~/work/emb2207/03-chigh/35-static/build$ ./main 
    led_on
    led_off
    beep_on:a=11
    beep_on:b=1
    beep_on
    *p=hello world!!
    beep_on:a=12
    beep_on:b=2
    beep_on
    *p=hello world!!
    beep_on:a=13
    beep_on:b=3
    beep_on
    *p=hello world!!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    2. static 关键字修饰全局变量
    • static 修饰全局变量用来限定全局变量的作用域 , 让这个全局变量的作用域只能在本文件内, 不能超越本文件
    • 目的是为了在多文件的工程中, 是为了解决变量重名的问题
    • 例如 ,全局变量重名的问题
    linux@ubuntu:~/work/emb2207/03-chigh/36-static/build$ make 
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/main.c.o
    [ 50%] Building C object CMakeFiles/main.dir/src/beep.c.o
    [ 75%] Building C object CMakeFiles/main.dir/src/led.c.o
    [100%] Linking C executable main
    CMakeFiles/main.dir/src/led.c.o:(.data+0x0): `temp'被多次定义
    CMakeFiles/main.dir/src/beep.c.o:(.data+0x0):第一次在此定义
    collect2: error: ld returned 1 exit status
    CMakeFiles/main.dir/build.make:146: recipe for target 'main' failed
    make[2]: *** [main] Error 1
    CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed
    make[1]: *** [CMakeFiles/main.dir/all] Error 2
    Makefile:83: recipe for target 'all' failed
    make: *** [all] Error 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 解决变量重名的问题, 就需要使用static 限定全局变量的作用域, 限定在本文件内。
    • 实例36
    • 源文件
    linux@ubuntu:~/work/emb2207/03-chigh/36-static/build$ tree ..
    ..
    ├── build
    ├── CMakeLists.txt
    ├── main.c
    └── src
        ├── beep.c
        ├── beep.h
        ├── led.c
        └── led.h
    
    2 directories, 6 files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 源代码
    linux@ubuntu:~/work/emb2207/03-chigh/36-static$ cat src/beep.c 
    #include   
    
    // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    static int  temp = 100;  // temp 的作用域就是在文件内 , 不会超出本文件, 不会出现工程中变量重名了 
    char * beep_on(void)
    {
        
        static int a = 10 ; // static 修饰局部变量, 只能被初始化一次  , 值可以保持 
        static int b ; // static 修饰的局部变量 没有赋初始值, 初始值为0 
        static char buf[100]={"hello world!!"}; 
        a++; 
        b++;
        printf("beep_on:a=%d\n",a);
        printf("beep_on:b=%d\n",b);
        printf("beep_on\n");
    
        return  buf ; 
    }
    
    int beep_off(void) 
    {
        printf("beep_off\n");
    
        return 0; 
    }
    linux@ubuntu:~/work/emb2207/03-chigh/36-static$ cat src/led.c 
    #include   
    
    static int temp = 100; // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    int led_on(void)
    {
        printf("led_on\n");
        return 0 ; 
    }
    
    int led_off(void) 
    {
        printf("led_off\n");
        return 0; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 运行结果
    linux@ubuntu:~/work/emb2207/03-chigh/36-static/build$ make 
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/src/beep.c.o
    [ 50%] Building C object CMakeFiles/main.dir/src/led.c.o
    [ 75%] Linking C executable main
    [100%] Built target main
    linux@ubuntu:~/work/emb2207/03-chigh/36-static/build$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    3. static 关键字修饰函数
    • static 修饰函数用来限定函数的作用域 , 让这个函数的作用域只能在本文件内, 不能超越本文件
    • 目的是为了在多文件的工程中, 是为了解决函数重名的问题
    • 例如 ,函数重名的问题
    linux@ubuntu:~/work/emb2207/03-chigh/37-static/build$ make
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/main.c.o
    [ 50%] Building C object CMakeFiles/main.dir/src/beep.c.o
    [ 75%] Building C object CMakeFiles/main.dir/src/led.c.o
    [100%] Linking C executable main
    CMakeFiles/main.dir/src/led.c.o:在函数‘display’中:
    led.c:(.text+0x2e): `display'被多次定义
    CMakeFiles/main.dir/src/beep.c.o:beep.c:(.text+0x80):第一次在此定义
    collect2: error: ld returned 1 exit status
    CMakeFiles/main.dir/build.make:146: recipe for target 'main' failed
    make[2]: *** [main] Error 1
    CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed
    make[1]: *** [CMakeFiles/main.dir/all] Error 2
    Makefile:83: recipe for target 'all' failed
    make: *** [all] Error 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 解决函数重名的问题, 就需要使用static 限定函数的作用域, 限定在本文件内。
    • 实例37
    • 解决工程中函数重名的方法
    • 源文件
    linux@ubuntu:~/work/emb2207/03-chigh/37-static/build$ tree ..
    ..
    ├── build
    ├── CMakeLists.txt
    ├── main.c
    └── src
        ├── beep.c
        ├── beep.h
        ├── led.c
        └── led.h
    
    2 directories, 6 files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 源代码
    linux@ubuntu:~/work/emb2207/03-chigh/37-static$ cat src/beep.c 
    #include   
    
    // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    static int  temp = 100;  // temp 的作用域就是在文件内 , 不会超出本文件, 不会出现工程中变量重名了 
    char * beep_on(void)
    {
        
        static int a = 10 ; // static 修饰局部变量, 只能被初始化一次  , 值可以保持 
        static int b ; // static 修饰的局部变量 没有赋初始值, 初始值为0 
        static char buf[100]={"hello world!!"}; 
        a++; 
        b++;
        printf("beep_on:a=%d\n",a);
        printf("beep_on:b=%d\n",b);
        printf("beep_on\n");
    
        return  buf ; 
    }
    
    int beep_off(void) 
    {
        printf("beep_off\n");
    
        return 0; 
    }
    
    static int display(void)
    {
        printf("display\n");
        return 0;
    }
    linux@ubuntu:~/work/emb2207/03-chigh/37-static$ cat src/led.c 
    #include   
    
    static int temp = 100; // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    int led_on(void)
    {
        printf("led_on\n");
        return 0 ; 
    }
    
    int led_off(void) 
    {
        printf("led_off\n");
        return 0; 
    }
    
    static int display(void)
    {
        printf("display\n");
        return 0;
    }
    linux@ubuntu:~/work/emb2207/03-chigh/37-static$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 运行结果
    linux@ubuntu:~/work/emb2207/03-chigh/37-static/build$ make
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/main.c.o
    [ 50%] Building C object CMakeFiles/main.dir/src/beep.c.o
    [ 75%] Building C object CMakeFiles/main.dir/src/led.c.o
    [100%] Linking C executable main
    [100%] Built target main
    linux@ubuntu:~/work/emb2207/03-chigh/37-static/build$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    4. extern 关键字的深入理解
    • 主要的作用是声明函数或变量,告诉编译器在这用了这个变量或函数, 定义不在, 在别的文件, 不要报错
    • 类似理解为提前声明, 防止编译报错
    • 例如, 在程序中使用别的文件定义的全局变量, 会报错
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern/build$ make 
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/main.c.o
    /home/linux/work/emb2207/03-chigh/38-extern/main.c: In function ‘main’:
    /home/linux/work/emb2207/03-chigh/38-extern/main.c:20:5: error: ‘led_count’ undeclared (first use in this function); did you mean ‘led_on’?
         led_count++;
         ^~~~~~~~~
         led_on
    /home/linux/work/emb2207/03-chigh/38-extern/main.c:20:5: note: each undeclared identifier is reported only once for each function it appears in
    /home/linux/work/emb2207/03-chigh/38-extern/main.c:21:5: warning: implicit declaration of function ‘pirntf’; did you mean ‘printf’? [-Wimplicit-function-declaration]
         pirntf("led_count=%d\n",led_count);
         ^~~~~~
         printf
    CMakeFiles/main.dir/build.make:62: recipe for target 'CMakeFiles/main.dir/main.c.o' failed
    make[2]: *** [CMakeFiles/main.dir/main.c.o] Error 1
    CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed
    make[1]: *** [CMakeFiles/main.dir/all] Error 2
    Makefile:83: recipe for target 'all' failed
    make: *** [all] Error 2
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern/build$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 解决变量未定义的办法是使用extern 去声明这个全局变量
    • 声明可以放在头文件当中也可以放在main.c 中
    • 实例38
    • 原文件
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern/build$ tree ..
    ..
    ├── build
    ├── CMakeLists.txt
    ├── main.c
    └── src
        ├── beep.c
        ├── beep.h
        ├── led.c
        └── led.h
    
    2 directories, 6 files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 源代码
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern$ cat main.c 
    #include 
    
    #include "led.h"
    #include "beep.h"
    
    // 这里不是定义, 因此不能赋初始值, 只是声明, 告诉编译器这个变量在别的文件中定义了, 这里只是声明
    // 编译不要报未找到变量
    extern int led_count; // 不能赋初始值, 一旦赋值就变成定义变量了
    extern int display_beep(void); // 函数的声明, 可以不写在.h 文件中 
    int main(int argc, char const *argv[])
    {
        led_on();
        led_off();
        char *p = beep_on();
        printf("*p=%s\n", p);
    
        p = beep_on();
        printf("*p=%s\n", p);
    
        p = beep_on();
        printf("*p=%s\n", p);
    
        led_count++;
        printf("led_count=%d\n", led_count);
    
        display_beep();
    
        return 0;
    }
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern$ cat src/beep.c 
    #include 
    
    int led_count = 1; // 定义一个全局变量 , 这个全局变量想在main.c中使用
    
    // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    static int temp = 100; // temp 的作用域就是在文件内 , 不会超出本文件, 不会出现工程中变量重名了
    char *beep_on(void)
    {
    
        static int a = 10; // static 修饰局部变量, 只能被初始化一次  , 值可以保持
        static int b;      // static 修饰的局部变量 没有赋初始值, 初始值为0
        static char buf[100] = {"hello world!!"};
        a++;
        b++;
        printf("beep_on:a=%d\n", a);
        printf("beep_on:b=%d\n", b);
        printf("beep_on\n");
    
        return buf;
    }
    
    int beep_off(void)
    {
        printf("beep_off\n");
    
        return 0;
    }
    
    static int display(void)
    {
        printf("display\n");
        return 0;
    }
    
    int display_beep(void)
    {
        printf("display_beep\n");
        return 0;
    }
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern$ cat src/led.c 
    #include   
    
    static int temp = 100; // 全局变量在工程中是唯一的变量, 如果出现重名就报错
    int led_on(void)
    {
        printf("led_on\n");
        return 0 ; 
    }
    
    int led_off(void) 
    {
        printf("led_off\n");
        return 0; 
    }
    
    static int display(void)
    {
        printf("display\n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • extern 声明变量或函数去解决未定义的函数或变量
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern/build$ make 
    Scanning dependencies of target main
    [ 25%] Building C object CMakeFiles/main.dir/main.c.o
    [ 50%] Linking C executable main
    [100%] Built target main
    linux@ubuntu:~/work/emb2207/03-chigh/38-extern/build$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 总结 , 在有的时候extern 在声明函数或变量时可以省略不写, 也是起到了声明的作用。
    5. volatile 关键字的深入理解
    • 防止编译器优化代码, 出现逻辑问题, 加上这个关键字后, 编译器对volatile修饰的代码不再优化。
    • volatile 关键字(keywords)是一种类型修饰符,volatile 的英文翻译过来是 “易变的” 。用volatile 声明类型变量的时候,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问;如果不使用 volatile 进行声明,则编译器将对所声明的语句进行优化。即 volatile 关键字影响编译器编译的结果,用 volatile 声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错。
    • 例如 , 告诉compiler不能做任何优化
    // 比如要往某一地址送两指令:
    int *ip =...; //设备地址
    *ip = 1; //第一个指令
    *ip = 2; //第二个指令
    
    //以上程序被compiler可能做优化为:
    int *ip = ...;
    *ip = 1; //第一个指令 , 可能被编译器优化掉了 , 硬件上写两次是有意义的
    *ip = 2;
    
    //结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意:
    volatile int *ip = ...;
    *ip = 1;
    *ip = 2;
    //即使你要compiler做优化,它也不会把两次付值语句间化为一,它只能做其它的优化。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • volatile实际应用
    #define     __O     volatile             /*!< Defines 'write only' permissions */
    #define     __IO    volatile             /*!< Defines 'read / write' permissions */
    
    /* following defines should be used for structure members */
    #define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
    #define     __OM     volatile            /*! Defines 'write only' structure member permissions */
    #define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
    
    typedef __IO int32_t  vs32;
    typedef __IO int16_t  vs16;
    typedef __IO int8_t   vs8;
    
    typedef __I int32_t vsc32;  /*!< Read Only */
    typedef __I int16_t vsc16;  /*!< Read Only */
    typedef __I int8_t vsc8;   /*!< Read Only */
    
    
    typedef struct
    {
      __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
      __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
      __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
      __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
      __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
      __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
      __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
      __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
      __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
      __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
      __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
      __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
      __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
      __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
      __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
      __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
      __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
      __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
      __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
            uint32_t RESERVED0[5U];
      __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
    } SCB_Type;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 什么情况下使用volatile 这个关键字, 什么是易变变量
    • 多线程访问时, 要使用这个关键字修饰线程间共享的变量
    • 硬件的寄存器访问时, 因为硬件也是易变的, 也需要使用volatile这个关键字
    • 深入理解, 参考资料 volatile关键字的用法
  • 相关阅读:
    perf性能分析
    利用 Kubernetes 内置 PodTemplate 管理 Jenkins 构建节点
    让Python更优雅更易理解
    JVM 虚拟机 ----> Java 内存模型(JMM)
    计算机毕业设计django基于python爬虫系统(源码+系统+mysql数据库+Lw文档)
    2022Nginx入门教程,图文超详细
    2023年煤气证模拟考试题库及煤气理论考试试题
    java 类和对象 属性和行为
    数据结构与算法:概述
    json-server环境搭建
  • 原文地址:https://blog.csdn.net/shengli001842/article/details/127835398