• C语言 static extern 关键字详解


     


     

    在C语言中主要是用来修饰变量和函数

    1 全局变量

    全局变量的作用域十分的广,只要在一个源文件中定义后,应用中所有的所有源文件、对象以及函数都可以调用,生命周期更是贯穿整个程序

    代码说明

    文件 global_test.cpp

    int g_num = 100;//定义全局变量
    
    • 1

    文件 main.cpp

    extern int g_num;//声明全局变量 不需要包含头文件 也可以引用 使用extern关键字
    
    int32 get_g_num();
    
    int main()
    {
        get_g_num();
        return 0;
    }
    
    int32 get_g_num()
    {
        return g_num;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

     


    2 static 修饰全局变量

     

    1. static 修饰全局变量其作用域会被限制在当前文件中

    文件 global_test.cpp

    #include "global_test.h"
    // 如果全局变量被static修饰
    // 那这个外部链接属性就会被修改成内部链接属性,
    // 此时这个全局变量就只能在自己的源文件中使用;
    static int g_num = 100;//static 修饰全局变量 变量的作用域会被限制在当前文件中
    
    • 1
    • 2
    • 3
    • 4
    • 5

    文件 main.cpp

    #include "keyword.h"
    extern int g_num;//声明全局变量 不需要包含头文件 也可以引用 使用extern关键字
    int main()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    此时编译会发现没有定义变量 g_num 说明 g_num被限制在了 global_test.cpp

    其本质是

    全局变量本身是具有外部链接属性的,在A文件中定义的全局变量,在B文件中可以通过【链接】来使用;
    但如果全局变量被static修饰,那这个外部链接属性就会被修改成内部链接属性,此时这个全局变量就只能在自己的源文件中使用

    1. 对static全局变量的修改对其他文件不可见

    在另一个头文件中包含定义有静态全局变量头文件,此静态全局变量可以被引用

    文件 global_test.h

    static int g_num = 100;
    
    • 1

    文件 test.h

    #ifndef KEYWORD_H
    #define KEYWORD_H
    #include "ctest.h"
    #include "global_test.h" 
    int32 print_g_num();
    #endif // KEYWORD_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    文件 test.cpp

    #include "keyword.h"
    
    int32 print_g_num()
    {
        // 在 global_test.h 头文件中定义的静态全局变量在文件被包含之后可以被正常访问
        printf("g_num = %d",g_num);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    文件 main.c

    #include 
    #include "test.h"
    int main()
    {
        print_g_num();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    静态全局变量被多次包含会出现重复定义错误么? 答案是不会 接下来验证

    test_2.cpp中包含头文件 global_test.h

    #include "global_test.h"
    #include "stdio.h"
    int print_g_num_1()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    文件 main.c

    #include 
    #include "test.h"
    extern int print_g_num_1();//函数声明
    int main()
    {
        print_g_num();// 正常访问 g_num
        print_g_num_1();// 正常访问 g_num
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果将 global_test.h 中的 static 关键字去掉,则上述代码编译之后会出现重复定义错误

    在一个文件中对静态全局变量进行修改对其他文件不可见

    global.h

    #ifndef GLOBAL_TEST_H
    #define GLOBAL_TEST_H
    static int g_num = 100;//定义静态全局变量
    int set_num_3(int num);
    int print_num_3();
    #endif // GLOBAL_TEST_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    global.c

    #include "global_test.h"
    int set_num_3(int num)
    {
        printf("set_num_1 modi befor g_num = %d\n",g_num);
        g_num  = num;
    }
    
    int print_num_3()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    test.c

    int print_num_1()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    int set_num_1(int num)
    {
        printf("set_num_1 modi befor g_num = %d\n",g_num);
        g_num  = num;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #include "global_test.h"
    #include "stdio.h"
    int print_g_num_1()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    int set_num_2(int num)
    {
        printf("set_num_1 modi befor g_num = %d\n",g_num);
        g_num  = num;
    }
    
    int print_num_2()
    {
        printf("g_num = %d\n",g_num);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    main.c

    #include 
    #include "test.h"
    #include "global_test.h"
    //函数声明
    extern int print_g_num_1();
    extern int set_num_1(int);
    extern int set_num_2(int);
    extern int print_num_1();
    extern int print_num_2();
    
    int main()
    {
         set_num_3(3);
         print_num_3();
    
         set_num_2(2);
         print_num_2();
    
         set_num_1(1);
         print_num_1();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    输出结果

    从输出结果可以得出结论 :
    对静态全局变量的修改对其他文件是不可见的,相当于每个文件中都有一份初始的值,都一样,各自修改各自的,互不影响

     


    3 static 修饰局部变量

     

    coding
    test.c

    int  local_var_test()
    {
        /**
           * 局部变量只是在第一次调用时会被初始化一次 数据是存储在全局区
           */
        static int index = 0;
        index ++;
        printf("index =  %d \n",index);
        return 0;
    }
    
    int  test()
    {
        for (int i = 0;i < 10;++i){
             local_var_test();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    main.c

    extern int  test();
    int main()
    {
        test();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    output

    index = 1
    index = 2
    index = 3
    index = 4
    index = 5
    index = 6
    index = 7
    index = 8
    index = 9
    index = 10

     


    4 static 修饰函数

     

    在上面的代码中 我们只需要在 main.c中 声明 函数,即可完成对函数的调用

    现在我们把函数声明为静态函数,即使用 static修饰,则此函数将会被限制在所在文件中,使用extern关键字也无法调用该函数

    test.c

    static int static_func_test()
    {
        printf("static_func_test \n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    extern static_func_test();
    int main()
    {
        static_func_test();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时编译报错,没有定义引用 static_func_test

    函数本身也是有外部链接属性的;
    被static修饰后,函数的外部链接属性被修改成内部链接属性,使得这个函数只能在自己的源文件内被使用,因此函数的作用域就变小了。

     


    5 extern 关键字

     

    extern 是一种外部声明的关键字,字面意思就是在此处声明某种变量或函数,在外部定义。

     
    1 修饰变量

    在其它文件中定义变量

    int extern_val = 100;//定义变量 并进行初始化
    
    • 1

    在当前文件中引用变量

    #include 
    extern int extern_val;//声明变量 表示此处要进行引用
    int main()
    {
        printf("extern_val = %d\n",extern_val);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

     

    2 修饰函数
     

    在其它头文件中定义函数
     

    // 函数的定义
    int printArr(int* pIntArr,int ilen){
        if (pIntArr == NULL || ilen == 0)
        {
            return 0;
        }
        for (int index = 0; index < ilen; index++){
            printf("%d ",pIntArr[index]);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

     

    声明并引用函数
     

    extern int printArr(int* pIntArr,int ilen);//函数的声明
    int main()
    {
        int intArr[] = {1,20,7,3,12};
        printArr(intArr,sizeof(intArr) / sizeof(int));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    【新手入门】Github与Git使用教程
    【解救ROS】ros小车机器人雷达跟随的实现步骤
    SublimeText3 安装、配置项、包管理、常用必备插件、常用快捷键以及修改
    图的应用2.0-----最短通路问题(Dijkstra和Floyd算法)
    Discuz论坛帖子标题随机高亮颜色,拒绝千篇一律!
    建造者模式
    基于51单片机的八路电压表采集Proteus仿真
    [Druid-1.2.11源码系列]-9-Druid销毁线程
    ACE JET NPOI
    Log4j发布2.17.0,解决2.16.0存在的DOS攻击风险
  • 原文地址:https://blog.csdn.net/qq_43606976/article/details/133869938