c/c++中的static与extern

本文属于如下两篇文章的提炼,非原创。
http://www.xumenger.com/c-cpp-static-extern-20180412/
https://www.runoob.com/w3cnote/extern-head-h-different.html

static 关键字

在C语言中static可以用来修饰局部变量、全局变量以及函数。c++中,static还可以修饰类成员。

c中static修饰局部变量

一般局部变量是存储在栈区的,局部变量的生命周期在其所在的语句块执行结束时便结束了。但如果用static修饰局部变量,那么这个变量就不会存储在栈区而是放在静态数据区,其生命周期会一直持续到整个程序结束。

  • 虽然static局部变量的生命周期变长了,但其作用域依然仅限于其所在的语句块。
  • static修饰局部变量后,该变量只在初次运行时进行初始化,且只进行一次。

c中static修饰全局变量

static修饰的全局变量只能在当前源文件中访问,在工程其他源文件中不可访问。

c中static修饰函数

与修饰全局变量类似,限制了函数的作用域。

c++中static

c++兼容c中的static特性,除此之外还有如下特性:

  • 如果类中的某个函数用static修饰,表示该函数属于一个类而不是属于任何特定对象,可以由类名或者对象访问。
  • 如果类中的某个变量用static修饰,表示该变量为类以及其所有对象所有。它们在存储空间中只有一个副本,可通过类或对象去调用。
  • 静态成员函数不接受隐式this指针,只能访问静态成员函数和静态成员变量!

extern关键字

在C语言中,extern用在变量或函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。C++中的extern还有一个作用!就是用来指示C或C++函数的调用规范,比如在C++中调用C库函数,就需要在C++程序中使用extern "C"声明要引用的函数。这是给链接器使用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规范不同,用此来解决名字匹配问题。

下面略过略过extern “C”,只讲c和c++中使用外部变量或函数的extern。

  • 对变量而言,如果你想在本源文件(例如文件名A)中使用另一个源文件(例如文件名B)的变量,方法有2种:(1)在A文件中必须用extern声明在B文件中定义的变量(当然是全局变量);(2)在A文件中添加B文件对应的头文件,当然这个头文件包含B文件中的变量声明,也即在这个头文件中必须用extern声明该变量,否则,该变量被重定义。(其实这种方法同(1),只不过换了种编码方式)
    注意声明和定义的区别:
extern int a; // 声明一个全局变量 a
int a; // 定义一个全局变量 a
extern int a =0 ; // 定义一个全局变量 a 并给初值。
int a =0;    // 定义一个全局变量 a, 并给初值,
  • 对函数而言,如果你想在本源文件(例如文件名A)中使用另一个源文件(例如文件名B)的函数,方法有2种:(1)在A文件中用extern声明在B文件中定义的函数(也可省略extern,只需在A文件中出现B文件定义函数原型即可);(2)在A文件中添加B文件对应的头文件,当然这个头文件包含B文件中的函数原型,在头文件中函数可以不用加extern。(其实这种方法同(1),只不过换了种编码方式)

实例

开发过程中希望在某个工程下的多个cpp文件中都访问全局变量Global

1

Head.hpp

#ifndef HEAD_H
#define HEAD_H

int Global;

int Func();

#endif

Head.cpp

#include <stdio.h>
#include "Head.hpp"

int Func()
{
    Global = 10;
    printf("Head Func, %d, %x\n", Global, &Global);
}

Main.cpp

#include <stdio.h>
#include "Head.hpp"

int main()
{
    Global = 100;
    Func();
    printf("Main main, %d, %x\n", Global, &Global);

}

报错,Global重定义。

2

Head.hpp

#ifndef HEAD_H
#define HEAD_H

static int Global;

int Func();

#endif

Head.cpp

#include <stdio.h>
#include "Head.hpp"

int Func()
{
    Global = 10;
    printf("Head Func, %d, %x\n", Global, &Global);
}

Main.cpp

#include <stdio.h>
#include "Head.hpp"

int main()
{
    Global = 100;
    Func();
    printf("Main main, %d, %x\n", Global, &Global);

}

与期望不符,两个源文件中的Global不是同一个变量。原因是static限制了变量的作用范围。

3

Head.hpp

#ifndef HEAD_H
#define HEAD_H

int Func();

#endif

Head.cpp

#include <stdio.h>
#include "Head.hpp"
int Glogal;//定义
int Func()
{
    Global = 10;
    printf("Head Func, %d, %x\n", Global, &Global);
}

Main.cpp

#include <stdio.h>
#include "Head.hpp"
extern int Global;
int main()
{
    Global = 100;
    Func();
    printf("Main main, %d, %x\n", Global, &Global);

}

正确。对应方法(1)

4

Head.hpp

#ifndef HEAD_H
#define HEAD_H

extern int Global;

int Func();

#endif

Head.cpp

#include <stdio.h>
#include "Head.hpp"

int Func()
{
    Global = 10;
    printf("Head Func, %d, %x\n", Global, &Global);
}

Main.cpp

#include <stdio.h>
#include "Head.hpp"

int main()
{
    Global = 100;
    Func();
    printf("Main main, %d, %x\n", Global, &Global);

}

正确,对应方法(2)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值