c语言static和extern区别难搞?实例对比+原理分析一看就明白

admin C语言 5


是不是很多新手学 C 语言时,都被 static 和 extern 这俩关键字搞懵了?明明都是修饰变量和函数的,可用法差太远,有时候写代码随便用,结果要么编译报错,要么逻辑出问题,对着错误提示半天摸不着头脑。其实啊,static 和 extern 就像两个性格完全不同的人,一个喜欢 “圈地自萌”,一个擅长 “广交朋友”,今天兔子哥就用实例对比和大白话原理,帮你把这俩的区别搞明白,一起往下看吧!

先说说 extern,它是 “牵线搭桥” 的高手


extern 这东西,说白了就是 “声明” 用的,告诉编译器:“这个变量 / 函数在别的地方定义了,你到时候去那边找就行”。它自己不定义东西,只负责牵线搭桥。
比如咱们在 a.c 里定义个全局变量:
int total = 100; // 定义全局变量
然后想在 b.c 里用这个 total,直接用肯定不行,编译器会说 “没见过这个变量”。这时候 extern 就派上用场了,在 b.c 里写:
extern int total; // 声明一下,告诉编译器 total 在别处
printf ("total 的值是:% d", total); // 这时候就能用了
这样编译就能通过,是不是很方便?函数也是一样,在 a.c 里定义个函数,在 b.c 里用 extern 声明一下就能调用,不用重新定义。
那要是不声明直接用呢?肯定报错啊,编译器又不是神仙,不知道你要用的东西在哪儿。我当初第一次用多文件编程时,就忘了写 extern,结果报了一堆 “未定义” 的错,后来才知道是少了这个 “牵线的”。

再看 static,它是 “圈地自萌” 的代表


static 跟 extern 正好相反,它不喜欢 “外人”,总把自己修饰的东西圈起来,不让别的文件访问。
就说全局变量吧,在 a.c 里用 static 定义:
static int score = 90; //static 修饰全局变量
这时候就算在 b.c 里用 extern 声明:
extern int score; // 声明也没用
printf ("% d", score);
编译照样报错,因为 static 已经把 score 圈在 a.c 里了,外人进不来。函数也是一样,用 static 修饰的函数,只能在自己的文件里被调用,别的文件想调用,门儿都没有。
为啥要这么设计呢?主要是为了避免重名。大项目里文件多,很容易定义同名的变量或函数,用 static 圈起来,各自在自己的地盘里用,就不会打架了。

一张表格看清两者的核心区别,再也不混


对比点staticextern
主要作用限制作用范围,让变量 / 函数只在当前文件可用声明变量 / 函数在别处定义,方便跨文件使用
对变量的影响修饰的全局变量只能在当前文件用声明别处的全局变量,让当前文件能用
对函数的影响修饰的函数只能在当前文件被调用声明别处的函数,让当前文件能调用
是否分配内存会(它不仅声明,还可能定义变量)不会(它只声明,不定义)

用实例对比,看两者个场景下该用谁


场景一:多个文件共用同一个变量。这时候就得用 extern,比如项目里的配置信息,在一个文件里定义,其他文件用 extern 声明就能共用。要是不用 extern,每个文件都定义一个,值不一样就乱套了。
场景二:变量只在当前文件用。这时候用 static,比如某个文件里的临时计算数据,没必要让别的文件知道,用 static 圈起来,安全又省心。
场景三:函数只想在当前文件被调用。比如文件里的辅助计算函数,外面用不到,用 static 修饰,别人想调用都调不了,能避免误用。
不过话说回来,extern 也不是万能的,它只能声明全局的东西,局部变量可声明不了也没用,这点点新手要记牢。之前有个朋友想在函数里用 extern 声明另一个函数里的局部变量,结果怎么都调不通,就是没搞懂这个理儿。

新手常踩的坑,提前给你指出来


  1. 以为 extern 能定义变量。不行啊,extern 只是声明,定义还得在别的地方,比如 “extern int a = 10;” 这样写是错的,定义不能带 extern。
  2. 给局部变量用 static 后,想用 extern 在别的函数里调用。这根本行不通,static 局部变量再怎么特殊,也是局部的,extern 也帮不了你跨函数调用。
  3. 觉得 static 和 extern 是对立的,不能一起用。其实它们本来就没啥直接关系,一个管限制,一个管声明,各干各的活儿。

至于不同编译器对 extern 声明的处理细节,比如有些编译器可能会对未找到定义的 extern 变量给出警告而非错误,具体机制我还没深入研究过,可能得查更多编译器文档才能说清。

兔子哥的一点小看法


其实 static 和 extern 不难分,记住一句话就行:想跨文件共用,找 extern 牵线;想限制在自己文件里,用 static 圈地。刚开始用的时候,多写几个多文件的小程序试试,比如一个文件定义变量,一个文件用 extern 调用,再试试用 static 把变量圈起来会发生啥,对比着学,印象特别深。
我当初学的时候,就是把这俩关键字在不同场景下都试了一遍,报错了就改,改着改着就明白了。编程这东西,光看不动手,永远都是似懂非懂。或许多动手实践,才是搞懂这些关键字的最快方式。
希望这些能帮到你,要是还有啥不清楚的,随时来问兔子哥,看到都会回的。

标签: 摸不着头脑 有时候

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~