irpas技术客

常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_沙漠下的胡杨_static跨文件

未知 1475

今天重点说下static关键字,但是说static之前就不得不说下多文件使用。

1.1 为什么要有多文件?

有时候写的代码很多,逻辑比较复杂,并且有多个函数的声明,定义,还有头文件,等等这一些东西,在一个文件里编辑太过于复杂,所以衍生出来了头文件。

1.2 多文件使用注意点。

一般来说会有一个头文件和一个main.c和一个或多个其他 .c文件。 头文件主要是 放全局变量的声明,函数的声明,define定的宏和所需要的头文件等等~。 其他 .c文件主要是实现函数的功能,要引用"自己创建的头文件"。 main.c主要是实现代码逻辑,也要引用"自己创建的头文件"。

今天也要努力学习呀

说完多文件啦,就进入今天的主题吧。 再进入主题之前,问各位读者大大一个问题。 变量和函数都必须跨文件使用吗?

2.1 static解释

不要误以为关键字 static 很安静,其实它一点也不安静。

2.2 生命周期和作用域问题。

生命周期和作用域在static中表现很突出,下面说一下他们区别。 生命周期是指一个变量在程序运行过程中存在多久。 作用域是指一个变量的作用的有效范围是多大。 两者概念不同不可混谈。

2.3 static修饰全局变量

static修饰全局变量,作用域仅限于变量被定义的文件中,其他文件即使用 extern 声明也没法使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些代码行也不能使用它。想要使用就得在前面再加 extern 。 简单说就是把全局变量只能本文件有效,其他文件不能访问,extern之后也不行。而且本文件在static定义之前使用的,还需要extern之后才可使用。 例1

void test1(int a) { if (a == 1) { printf("hello\n"); } } int main() { test1(a);//“a”: 未声明的标识符 } static int a = 1;

这样是不可以的,会报错,需要在开头加上extern声明。 例2

extern int a; void test1(int a) { if (a == 1) { printf("hello\n"); } } int main() { test1(a); } static int a = 1;

或者在开头定义static静态全局变量。 例3

static int a = 1; void test1(int a) { if (a == 1) { printf("hello\n"); } } int main() { test1(a); }

这是本文件内部的情况,那static跨文件呢?

看例4: 在test.c中定义的static int a不可以在main.c中使用哦(头文件,声明均正常写入)。

结论1:static修饰全局变量,使该变量只能在本文件使用,不可以在其他文件直接被使用。敏感的人都看见了,直接被使用。也就像const一样可以间接使用喽。答案是可以的。 例5: 各位看官大人是不是有些疑问呢? 为啥你说不可以使用,而现在又可以使用了呢? 这里有点像 const 修饰的东西不可以直接被修改一样。可以看下const对比下 const高频考点 同样的static也是类似的,不可以直接访问,但是可以间接访问,通过tset.c中接口实现,main函数通过接口来调用,形成间接调用。

2.4 static修饰函数

static修饰函数呢?跟修饰全局变量类似,也是只能在本文件内使用,不能在其他文件直接使用,话不多说看例子 例6: 这样调用,会有个错误叫 error LNK1120: 1 个无法解析的外部命令 这是叫链接错误,是程序在编译 链接 形成和执行程序,链接错误,就是找不到该函数,这也就证明了上述所说的。

同样,也是可以通过间接调用的方式调用。 例6 : 可以看出,间接调用函数是可以实现的。

2.5 static总结修饰函数,修饰全局变量

static修饰全局变量或者函数,本质都是改变了函数,全局变量的作用域,而生命周期没有变。

2.6 static修饰局部变量

static修饰局部变量会是什么结果呢? 还是像全局变量和函数一样吗? 答案是不一样的,static修饰局部变量,是改变了变量的生命周期而并非是作用域。举个栗子: 例 7:

static void fan() { int i = 0; i++; printf("%d\n", i); } int main() { for (int i = 0; i < 10; i++) { fan(); } return 0; }

这打印的是10个1,那么用static修饰fan函数中的i呢? 例 8:

static void fan() { static int i = 0; i++; printf("%d\n", i); } int main() { for (int i = 0; i < 10; i++) { fan(); } return 0; }

这样的话就是打印1~10了,为什么呢? 首先 i 是局部变量时,每次进去fan函数,都会重新进行赋值成0,因为,局部变量每次函数结束后就生命周期结束了,而static修饰 i 时,i的生命周期变长了,因为static把 i 放入了静态变量区,生命周期和全局变量一样了。 那么还有一个问题? static修饰的局部变量是全局变量吗?请看下列代码 例 9:

这里可以看出来,i 的生命周期离开了fan函数还没有结束。 下面对 i 进行使用呢?来判断下作用域。 例 10: 这可以看出 i 不能使用了,就是作用域不变还是fan函数,所以static修饰的局部变量不是全局变量。

2.7 总结引入static的目的

正常情况下,extern声明后,可以在项目中使用函数,全局变量等,但是总会有些情况不想被访问,这是就有了static引入,目的也是为了更安全了,如果项目中不想让更多人知道实现逻辑和细节,就用static,再使用间接调用的方式,增加安全性。

**

下期预告

** 下期讲struct结构体相关内容,下期更精彩哦!


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #static跨文件 #11 #12 #多文件使用注意点 #c文件