储存类别说明符extern和static的作用效果辨析

extern

extern 局部变量

        extern 局部变量使得局部变量的寻找范围扩大(通常到全局,成为外部变量),也可以理解成使得上一级的变量(通常为全局)的作用范围扩大到定义行之前进而能被函数所利用(全局变量作用域原本在定义行之后)。extern 表明该局部变量的定义将出现在接下来的编写代码过程中,这种声明称为提前引用声明。如果该变量本身就定义在函数之前,那函数当然可以直接用了。

#include <iostream>
using namespace std;

int main()
{
    extern int a, b;    // extern 使 a, b 可以被提前使用而不用先定义
                        // 也不能(因为只要加了extern就表示不在此处定义)先定义
                        // 可让a, b的寻找范围扩展到该函数体之外(此处为全局)
    cout << a << "\t" << b << endl;
    return 0;
}

int a = 5, b= 6;
// 运行结果
// 5       6

extern 全局变量

        extern 全局变量使得全局变量的寻找范围(找定义)进一步扩大,通常就是到链接的其他文件中去找了。比如在test1.cpp中定义了int a = 1, 为避免重复定义且不能重复定义,在test2.cpp中用test1.cpp中的a变量时,需要用extern声明extern a。

extern 函数 

        表明该函数的定义不在该文件中(如果在该文件中,直接先声明就可以了),但现在我要使用,要使用就要声明,虽然不在这里实现,这时候就用extern进行声明

// func.cpp
// 函数定义在此
void func(int a)
{
    cout << a;
}
// main.cpp
#include <iostream>
using namespace std;

extern void func( int );    // 表明函数并未定义在此文件中
int main()
{
    int a = 0;
    func(a);
}

// 输出结果 
// 0

static

static 局部变量

        static 局部变量,比如在函数体内,static关键字使得该变量若不显式赋值则默认初值为0,同时使该变量在函数执行完毕后仍然存在,不被销毁,下次调用时该变量存储的使上一次执行完毕的值(即使在执行func时又进行了声明并赋值)。

#include <iostream>
using namespace std;

void func()
{
    static int i;   // 默认初值为0, 写成static int i = 0; 也一样,i只通过定义赋值一次
    cout << ++i << "  ";
}

int main()
{
    for ( int j = 0; j < 10; j++)   func();
}

// 运行结果
// 1  2  3  4  5  6  7  8  9  10   

static 全局变量

        static 全局变量使得该全局变量只可在本文件中使用且仅从定义行后可用(即便加了extern),这和普通全局变量有所不同,普通全局变量在哪里进行全局声明都可以,加了extern后就可以引用。我个人比较倾向于将static英文静止之意引申为死板,显得它比全局变量又要呆一些,嘻嘻。这种static修饰的只能用于本文件的全局变量称为静态外部变量

        在程序设计中,当有若干人完成各个模块,各个人可以独立的在其设计的文件中使用相同的全局变量名而互不相干。只需在每个文件的全局变量前加上static,使之成为静态外部变量,以免被其他文件误用,因为一个地方改了,其他文件的该变量都会跟着变,但要注意这时就不能再使用提前引用声明了,也就是只能在用之前就定义,因为它比较死板啦~

        对于全局变量,用了static可以在之后用extern(虽然看似有点多余,但可以避免多人合作的冲突),但是用了extern就不能在之后用static。

#include <iostream>
using namespace std;

static int a = 5, b= 6;// static 使得该全局变量只能在该文件中且只能从定义行起始能被使用 
int main()
{
    extern int a, b;    // extern 使 a, b 可以被提前使用而不用先定义
                        // 也不能(因为只要加了extern就表示不在此处定义)先定义
                        // 可让a, b的寻找范围扩展到该函数体之外(此处为全局)
    cout << a << "\t" << b << endl;
    return 0;
}

// 运行结果
// 5       6

// static int a = 5, b= 6; // 若在在这里如此定义(定义晚了),即便前面声明了extern,也用不了
// int a = 5, b = 6;    // 去掉static又可正常运行

static函数

        static函数使得该函数仅能被本文件所使用,而其他文件不能通过引用该文件来使用这个函数(目前了解到这里)。

注意:储存类别说明符extern和static不能用于类中。

参考博客:

[1] extern和static的用法_一夜奈良山️的博客-CSDN博客_extern static

[2] C++之——变量的存储类别及static、register、extern用法_衣带渐宽人憔悴的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值