详解static和extern

static

  1. 静态局部变量:用于函数体内部修饰变量,这种变量的生存期长于该函数
  • 该变量是在全局数据区分配内存(局部变量在栈区分配内存,函数结束立即释放内存)
  • 只进行一次初始化,以后的函数调用不再初始化(局部变量每次调用都会初始化)
  • 一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0,即声明和定义是同时给出的(局部变量不会被自动初始化)
  • 其作用域为局部作用域,不能在函数外使用它
  1. 静态全局变量和静态函数
  • static修饰的全局是内部链接性,内部链接性在编译单元间不共享,即static的全局作用域只是自身编译单元。(编译单元:产生单一目标文件的那些源码,基本上它是单一源码加上其所含的头文件)
//a.h
#ifndef A_H
#define A_H
#include<iostream>
using namespace std;
static char str[] = "hello";
namespace sextern {
void Fun1();
void print1();
}
#endif // A_H//a.cpp
#include "a.h"
namespace sextern {
void Fun1(){
    str[0] = 'l';
}
void print1(){
      cout << "value  " << str << endl;
      cout << "address  " << &str <<endl;
}
}//c.h
#ifndef C_H
#define C_H
#include<iostream>
using  namespace std;
namespace sextern {
void Fun3();
void print3();
}
#endif // C_H//c.cpp
#include "c.h"
#include "a.h"
namespace sextern {
void Fun3(){
    str[0] = 'o';
}
void print3(){
    cout << "value  " << str <<endl;
    cout << "address  " << &str <<endl;
}
}
​
​
#include "a.h"
#include "c.h"
using namespace sextern;
int main(int argc, char *argv[])
{
    sextern::Fun1();
    print1();
    sextern::Fun3();
    print3();
    print1();
    return 0;
}

//结果如下
/*
 *  value  lello
 *  address  0x602064
 *  value  oello
 *  address  0x60205e
 *  value  lello
 *  address  0x602064
 *  按 <RETURN> 来关闭窗口...
 */

在a.h的头文件中定义了一个静态的全局变量x,不同文件的函数fun1和fun3会为每个包含该头文件的cpp都创建一个全局变量,但他们都是独立的,只在该cpp文件共享该变量。所以一般定义static全局变量时,都把它放在原文件中而不是头文件,从而避免多个源文件共享,就不会给其他模块造成不必要的信息污染。如果想要在不同文件共享同一个全局变量,这个时候就要用到extern。

  1. 类中的静态数据成员
  • 每个类有一份,由该类型的所有对象共享访问,存储在全局数据区。
  • private,public都可以定义
  • static关键字只出现在类内部的声明语句中
  • 只有静态常量成员可以在类的内部初始化(即使在内部初始化了,通常情况下也应该在类外定义一下该成员)。不初始化静态成员会报错。
  • 静态数据成员的类型可以是它所属类的类型
  • 可以使用静态成员作为成员函数的默认实参
  1. 静态成员函数
  • 静态成员可以相互访问,非静态可以访问静态,静态不能访问非静态。
  • 调用静态成员函数,对象可以用 . ,指针可以用 -> ,也可用 类名::函数名 调用。

extern

  1. extern的作用范围是整个工程,是共享性的
  2. 置于变量或者函数前,以标示变量或者函数的定义在别的文件中(也可能是本文件),可以有多个声明,但只能有一个定义。因此我们最好遵照下面的规则:
//.h文件
extern string str;

//.cpp文件
string str="hello";

//在其它文件中包含.h头文件即可使用此变量
  1. 与"C"连用,如extern “C” void fun();告诉编译器按C的规则去翻译。
  2. 注意:extern就是专门用来声明全局变量的,函数内定义的对象不能被extern声明。
//下面这个会报重定义错误,即使你没有添加任何其他头文件,因为声明的这个a它只会在全局域找
int main() {
	extern int a;
	int a = 1;
	cout << a << endl;
	return 0;
}

static与extern区别

  1. static修饰的全局是内部链接性,内部链接性在编译单元间不共享;而extern是整个工程全局共享的。
  2. static修饰全局变量时,声明和定义是同时给出的;extern则是在一处定义,其他地方都是声明。
  3. 注意:它们不能同时修饰一个变量。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值