zoukankan      html  css  js  c++  java
  • C语言中static关键字的用法

      C记得还是大一时学的,现在觉得好久没用了,又捧起来看看。今天刚看到有关static关键字,仔细地看了一遍《C和指针》这本书中的解释,现在觉得清楚多了。

      首先,我们将static关键字,修饰分为两类,一类是修饰变量,另一类则是修饰函数。下面我就分这两类来阐述下我个人的理解。

      一 、修饰变量

      static修饰变量我们也分为两类,一类是修饰全局变量,另一类则是修饰局部变量。

      (1)修饰全局变量

        全局变量是不再任何代码块中声明的变量(说直白点就是全局变量时在{}外面声明的变量)。

        例如:   

    #include <stdio.h>
    int a;     //a就是一个全局变量
    
    int main()
    {
        int b;    //b则是一个局部变量
        ...        
    }

      OK,一个全局变量它被声明后,它就像富二代一样,一生下来就就具有某种特殊的属性。

      全局变量具有静态的存储属性(它存在于静态内存中,在程序运行前就被建立了,一直存在于程序的整个生命周期当中),而且它还具有external的链接属性(注意:是external而不是extern,它表示该变量可以被其他文件所引用)。

      而当你在上面的int a前面加个关键字static修饰时,他的第二个属性就改变了,变成了internal,它只能在所在文件中被使用,其他文件中则不能够使用它。

      下面我就举个具体的例子:

      extern_definition.c

      我在该文件定义了一个全局变量int a

    #include <stdio.h>
    
    int a = 1;

      extern_usage.c

    #include <stdio.h>
    
    extern int a;
    
    int main() {
        
         printf("a comes from extern_definition.c is %d
    ",a);
         return 0;      
    }

      编译,运行输出的结果是:

      

       当我把extern_definition.c文件中的int a = 1;改为static int a = 1;后的结果是:

      

      这时gcc编译器就报错啦,说是在文件extern_usuage.c中无法引用到变量a,这就验证了我们上述的说法。

      (2)修饰局部变量

       上面我们说了下,全局变量像是富二代拥有了许多“高贵”的属性,这里我们页也说说局部变量“屌丝”属性吧。

       局部变量,首先是“寿命“短(它具有的存储类型是自动存储类型,存储在堆栈中,作用域也就是在{}之中,出了{}它就没有了作用,就被销毁了),它的链接属性是none(无),在一个文件中的不同代码块内,它可以被重复定义,而且其他文件也访问不到它。

       当我们向局部变量前面添加static关键字之后,它就瞬间变得高大上了,它的存储类型就有自动类型变成了静态类型(它就会一直存在于程序运行的整个周期,而且程序中的任何地方都可以调用这个局部变量了)。

       下面我也继续举个例子来说明吧:

       static_func.c

    #include <stdio.h>
    
    int func()
    {
         int counter = 1;      
        return ++counter;
    }
    
    int main() {
    
         int answer;
         answer = func() - func() * func();
         printf("answer is : %d
    ",answer);
         return 0;                
    }

      接下来我们编译运行,结果是

      这个结果,跟我想的结果是一致的,相当与这个函数func()每次返回的结果都是2,于是2-2*2=-2

      现在,我们将函数func中的int counter = 1;改为static int counter = 1;

      我们线猜下这次运行的结果会是多少,我的思路是,在整个程序运行过程中由于counter被声明为static类型,所以它一直存在于整个程序运行周期当中。

      所以结果是:2-3*4 = -10;(注意:还要提醒下,static 修饰过的变量它只初始化一次)。

     

      不出所料,结果就是这样的。

      

      二、static修饰函数

      static 修饰变量感觉理解起来比较轻松的话,那么static修饰函数又是什么意思呢?

      其实static修饰的函数就有点类似与我们学过面向对象语言(C++/Java)中的函数修饰符private,它只允许本文件中可以访问该函数,其他文件则不能够访问到函数。

      假如真要阐述清楚这个原理的话,这还是得用链接属性来说明。

      例如:

    int a;
    static int b;
    
    int function(void ) 
    {
       ......    
    }
    
    ....

      在上面我们举了个函数名叫function的函数,它页不存在于任何的代码块内(也就是没被包括在{}当中),所以他就具有了external的链接属性,其他文件就可以访问该函数了,如果我们在该函数前面加上static修饰后,一切就会变得不一样了,function函数的链接属性就会由external变为了internal了,只能在本文件中被使用了。(其实这样做的好处就相当与C语言中的封装了,向外屏蔽了函数实现的具体细节了)。

      这里,我们也举个例子吧

      main.c  

    1 #include <stdio.h>
    2 
    3 int main() 
    4 {
    5     function();
    6     return 0;
    7 }

      function.c

    #include <stdio.h>
    
    void function()
    {
        printf("This is in the function.c function function
    ");
    }

      没加static的运行的结果是:

      加了static的运行结果:

     

          同样编译器报错说找不到函数function,这就成功验证了我们上述的说法。

      我想如果大家能看到这儿,C语言中的static关键字我们应该就能掌握地比较透彻了。

      

      转载请注明出处:http://www.cnblogs.com/woshijpf/  谢谢!

      

  • 相关阅读:
    论文赏析[EMNLP19]如何在Transformer中融入句法树信息?这里给出了一种解决方案
    论文赏析[TACL19]生成模型还在用自左向右的顺序?这篇论文教你如何自动推测最佳生成顺序
    论文赏析[ACL18]一个句子向量表示究竟可以塞进多少语言性质?
    论文赏析[EMNLP19]用控制任务来设计并解释探测任务
    [TACL18]隐式句法树模型真的能学到句子中有意义的结构吗?
    成分句法分析综述
    关于性能指标体系
    关于性能分析框架和性能监控平台
    关于Node.js安装及环境配置之Windows篇
    关于IntelliJ:idea取消启动时的默认工作空间,打开欢迎页面
  • 原文地址:https://www.cnblogs.com/woshijpf/p/3854335.html
Copyright © 2011-2022 走看看