参考原文地址(static):https://blog.csdn.net/keyeagle/article/details/6708077

参考原文地址(extern):https://www.cnblogs.com/Lunais/p/5991135.html

C语言中的static与extern是C语言32个关键字中的比较重要的两个内容,也是我近期在学习C++过程中理解较为晦涩的部分,为此,参考了一些优质资料,在此做个总结。

C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错。伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系,产生了extern和static关键字。

修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。

一、static修饰全局变量
一个程序在内存中的布局:栈(局部变量,动态分配)、堆(用户自行申请、释放,通过指针访问)、bss段(存放进程中未初始化的全局变量)、data段(存放进程中初始化的全局变量)、text段(存放程序执行的二进制文件)、其他段(未知)。

静态全局变量:当进程中一个全局变量被static修饰后(被声明为static),则该全局变量被称为静态全局变量。

静态全局变量的存储位置不变,在bss段(未初始化)或者data段(初始化),但它的作用域是仅在它的源文件内,其它源文件都无法访问它。所以,当全局变量被static修饰后,就会限定在当前源文件(.c)内使用。

全局变量:隐式被static修饰的全局变量,作用域也是仅在它的源文件内,不能被其它源文件访问。但与静态全局变量(显式被static修饰的全局变量)不同的是全局变量在其它源文件中可以通过extern声明后访问,而静态全局变量则无法访问。

file1.h文件,声明printer函数


//file1.hvoid printer(void);

file1.c文件,定义了 静态全局变量name、全局变量address,以及printer函数

//file1.c
#include <stdio.h>
#include "file1.h"static char* name = "keke";
char* address = "jiangxi";void printer(void)
{printf("%s\n",name);printf("%s\n",address);
}

file2.c文件,可以成功调用printer函数,也可以通过extern声明访问全局变量address,但是无法访问name(即使被extern声明)

//file2.c
#include <stdio.h>
#include "file1.h"//extern char* name;
extern char* address;int main()
{printer();printf("%s\n",name);printf("%s\n",address);
}

二、static修饰局部变量
局部变量可以被存放在栈(动态分配,每次调用,位置都可能不同,作用域是局部)、堆(申请内存,要记得释放,作用域可以是整个源文件)当中。
静态局部变量:局部变量被static修饰后,则称为静态局部变量。静态局部变量则被存放在data段内(定义时,如果用户没有初始化,编译器会自动将其初始化为0),而且整个进程周期中,只定义和初始化一次,每次调用局部函数时,静态局部变量都会维持最后一次修改的值,作用域是局部代码段。
file3.c文件,在函数printer内分别定义了普通局部变量(i)和静态局部变量(j)。


//file3.c
#include <stdio.h>void printer(void)
{int i;static int j;printf("i:%d j:%d\n",i++,j++);
}int main()
{printer();printer();printer();printer();printer();
}

file.c文件执行结果如下:

i:-1218204059 j:0
i:-1218204058 j:1
i:-1218204057 j:2
i:-1218204056 j:3
i:-1218204055 j:4

可见,普通局部变量(i)每次调用函数的访问的值都不一样,而且随机;静态局部变量,定义初始化为0,并每次访问都是上一次函数调用修改的值。

三、static修饰函数
static函数:被关键字static修饰的函数。static函数作用域是源文件,即其他源文件无法调用该函数,类似C++中的private函数。而对于普通函数而言,其他源文件只要添加了该函数的头文件(.h),其他源文件就可以调用该函数。
当你的程序中有很多个源文件的时候,你肯定会让某个源文件只提供一些外界需要的接口,其他的函数可能是为了实现这些接口而编写,这些其他的函数你可能并不希望被外界(非本源文件)所看到,这时候就可以用static修饰这些“其他的函数”。
file4.h文件,声明了普通函数(func1)和静态函数(func2)

/file4.h
void func1(void);
static void func2(void);

file4.c文件,定义了普通函数(func1)和静态函数(func2)

/file4.c
#include <stdio.h>
#include "file4.h"void func1(void)
{printf("普通函数\n");func2();
}
static void func2(void)
{printf("静态函数\n");
}

file5.c文件,通过添加file4.h,可以调用func1(),但无法调用func2()。但是,func1()可以调用func2()。

//file5.c
#include "file4.h"int main()
{func1();//func2();
}

可见,静态函数只能被它的源文件调用,而无法被其它源文件调用(即使添加了对应的头文件)。

而且,static函数可以很好地解决不同源文件中函数同名的问题,因为一个源文件对于其他源文件中的static函数是不可见的。

四、extern修饰变量的声明
extern声明变量:表明该变量在其他源文件里已经被定义,此处需要使用。extern声明的变量必须是在其他源文件内的非静态的全局变量(保证作用域不受限制,可以声明)。
举例在file1.h/file1.c/file2.c中。
五、extern修饰函数的声明
extern声明函数:表明该函数在其他源文件里已经被定义,此处需要使用。extern声明的变量必须是在其他源文件内的非静态的函数(保证作用域不受限制)。
那么我们有两种方式可以其他源文件内的非静态函数,一种是添加该函数声明头文件(加载该头文件的全部函数,编译较慢),另一种是使用extern修饰(调用哪个函数,就声明哪个函数,编译较快,效率较高)。
举例在file4.h/file4.c/file5.c中。

C语言关键字static与extern的详细解释相关推荐

  1. c 函数多次声明_【C语言】- static和extern关键字 - 对函数的作用!

    不同类型的变量有不同的存储类型.不同的生命周期.不同的作用域.这篇小文介绍2个比较重要的关键字:static和extern. static和extern不仅可以用在变量上,还可以用在函数上.这讲先介绍 ...

  2. c语言extern_【零基础C语言】- static和extern关键字 - 对变量的作用!

    上一篇文章介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量 ...

  3. static在c语言中的作用_C语言关键字 static 的用法

    接上文:C语言的32个关键字 C语言 static 关键字的常见用法有三种: 用于局部变量的修饰符: 用于全局变量的修饰符: 用于函数的修饰符. 1.用于局部变量的修饰符 当 static 用于修饰局 ...

  4. wc linux c语言,linux的wc命令的详细解释

    Linux中的wc命令主要是用来计算指定文件的字节数等信息.下面由学习啦小编为大家整理了Linux的wc命令的详细解释的相关知识,希望对大家有帮助! linux的wc命令的详细解释 wc命令的功能为统 ...

  5. c语言关键字-static

    一.static关键字三个作用 定义全局静态变量,定义局部静态变量,定义静态函数 二.c语言中static作用 在修身变量的时候,static修饰的静态局部变量只执行一次,而且延长了局部变量的生命周期 ...

  6. [深度解剖C语言] --关键字 static

    static ---最名不副实的关键字 目录 1.static修饰全局变量 2.static修饰函数 3.static修饰局部变量 static的作用: 1.static修饰全局变量 我们创建两个源文 ...

  7. (c语言详解)07-图6 旅游规划(详细解释)

    本博文源于浙江大学<数据结构>,为了更好地解释程序,先放题目 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条 ...

  8. 【濡白的C语言】初学者-从零开始-4(欢喜冤家static与extern)

    前言 本次主要介绍两个关键字static.extern,主要与函数.变量的作用域与生命周期有关. 目录 extern C语言函数隐式存储方式 全局变量 函数 static 局部变量 全局变量 函数 总 ...

  9. C语言 —— 关键字(C语言标准定义的32个关键字:auto、register、static、sizeof、signed、unsigned 、break 、 continue 、void)

    C语言标准定义的32个关键字:(列出每个关键字的意义) 关键字 意 义 auto 声明自动变量,缺省时编译器一般默认为 auto int 声明整型变量 double 声明双精度变量 long 声明长整 ...

最新文章

  1. 清华 CVer 对自监督学习的一些思考
  2. opcua客户端实现断线重连_干货:通过OPC UA协议访问西门子1500数据
  3. SQL SERVER 2008安全配置
  4. Spark Streaming的窗口操作
  5. 一家可能永远无法赚钱的公司,把自己卖了400亿
  6. 更自由的阿里云API工具JCLI
  7. 除了下拉框/下拉联想词优化推广,还可以做那些网络推广?
  8. ASP.NET ZERO 学习 JTable的使用
  9. matlab带通滤波器介绍,基于MATLAB的带通滤波器设计
  10. 上传新文件项目到svn上
  11. 投标是个技术活,不这样做要么苟且,要么狗带
  12. 马尔可夫随机场 MRF
  13. 计算机系统与itunes不兼容,解决XP系统安装iTunes的要求更改更高版本的不兼容情况...
  14. Linux搭建Elasticsearch集群
  15. 苹果退款_苹果App Store竟然还可以退款?App Store退款教程
  16. html边框波浪,波浪的边框css怎么实现
  17. H3C防火墙开启web流量监控命令
  18. OPEN(SAP) UI5 学习入门系列之二: 最佳实践练习(下)
  19. .wine/drive_c/users/Public/Application Data/Source Insight/4.0
  20. 线搜索(line search)方法

热门文章

  1. liunx学习笔记1
  2. php basic publish,RabbitMQ入门(PHP语言描述)
  3. iOS之仿QQ好友列表展开收缩效果的实现
  4. 459. Repeated Substring Pattern 重复的子字符串
  5. 112. Path Sum 路径总和
  6. G6 图可视化引擎——入门教程——绘制 Tutorial 案例
  7. ping github超时问题
  8. 2010年第一届蓝桥杯省赛 —— 第二题
  9. 【MFC】MFC工程文件详解
  10. 【STM32】 keil软件工具--菜单详解