【C语言】static关键字的使用

static关键字大家肯定都不陌生,只要你写过c++,java,c#,或者是js,通常情况下,你肯定要使用到static关键字

一般情况下,我们使用它都是用在类中的函数上,或者是函数内的变量,或者类的全局变量,在面向对象的语言当中,使用static无非就为了以下几点

内部变量保存、方法的静态调用、变量的静态调用

比如我们写C++的时候


class abc {
  public:
    static int c;
    static void aaa()
{
      static int tt = 1;
      cout <<tt << endl;
      tt++;
    }
};
int abc::c = 12;
int main()
{
    abc::aaa();
    cout << abc::c << endl;
    abc::aaa();
}

这个一看一目了然,静态调用abc类中方法aaa、变量c的时候,都是直接用类名调用,并没有声明对象

变量tt的使用方式,是static最常用的方法,保存变量

上述代码输出

在这里插入图片描述
但在没有类概念的C中,static变量有什么用呢?

一、C语言中static的作用

  • 保存局部变量

这一点上,C和C++还有其他语言基本是一样的

如果在函数内部使用static 修饰变量,则这个变量,就好像全局变量一样,每次调用到这个函数时候,这个变量还能保持上一次的值。但是又和全局变量不一样,本函数外部函数又不能调用它,例如

#include <stdio.h>
void abc() {
  static int a = 0;
  printf("%d\n", a);

}
int main()
{
  abc();
  abc();
}

如上例,如果没有static 的修饰a的话,则调用两次abc(),就会输出两次0

因为变量脱离作用域,就失效了,第二次调用等于重新给a赋值,但是用了static就不一样了,static可以保存局部变量,让局部变量不失效,所以,上例输出为

  • static修饰的变量和函数,表示这个变量、函数只能被当前文件所链接

以上这个性质的意思是说,如果你的变量、函数被static修饰的话,这个函数或者变量还在其他文件当中,那么在编译链接时,链接将无法实现,举个例子说明,就把上例改一改,把函数abc移动到一个新的文件b.c中

#include <stdio.h>
int xxx = 999;
void abc() {
  static int a = 0;
  printf("%d\n", a);
  a++;
}

然后在c.c中调用他

#include <stdio.h>
int main()
{
  extern int xxx;
  printf("%d\n", xxx);
  abc();
  abc();
}

你要是按上面代码编译的话,没问题,可以成功。

但是b.c中的abc函数、变量xxx,如果用static修饰的话


#include <stdio.h>
static int xxx = 999;
static void abc() {
  static int a = 0;
  printf("%d\n", a);
  a++;
}

再编译,就会报错了

error LNK2019: 无法解析的外部符号 abc,该符号在函数 main 中被引用
error LNK2001: 无法解析的外部符号 xxx

不过,如果你把b.c排除在编译外,把他当成引用文件在,c.c中include他


#include <stdio.h>
#include "b.c"
int main()
{
  extern int xxx;
  printf("%d\n", xxx);
  abc();
  abc();
}

这就没问题了,因为最终他们就合成一个文件了,编译就成内部链接了

二、 static的本质

先看一个例子

#include <stdio.h>
char* a = "aaaaaa";
int main()
{
  char* b = "bbbbbb";
  printf("%s\n",b);

  static char* c = "cccccc";
  printf("%s\n", a);
  printf("%s\n", c);
}

上述代码输出

aaaaaa
bbbbbb
cccccc

这不是重点,重点在汇编里
在这里插入图片描述

从上面可以看到,函数中的局部b,静态变量c,和全局变量a,在读取方式上并无区别

所以说,static变量,只不过,他只是在编译期间有效,在编译后,它将以全局变量方式存在,但在编译时,编译器对变量作用域判断时,它又和局部变量一样只能存在于函数作用域内

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值