本文属于如下两篇文章的提炼,非原创。
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)。