常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助

今天重点说下static关键字,但是说static之前就不得不说下多文件使用。常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第1张图片

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:
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第2张图片
在test.c中定义的static int a不可以在main.c中使用哦(头文件,声明均正常写入)。

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

2.4 static修饰函数

static修饰函数呢?跟修饰全局变量类似,也是只能在本文件内使用,不能在其他文件直接使用,话不多说看例子
例6:
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第4张图片
这样调用,会有个错误叫 error LNK1120: 1 个无法解析的外部命令
这是叫链接错误,是程序在编译 链接 形成和执行程序,链接错误,就是找不到该函数,这也就证明了上述所说的。

同样,也是可以通过间接调用的方式调用。
例6 :
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第5张图片
可以看出,间接调用函数是可以实现的。

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:
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第6张图片

这里可以看出来,i 的生命周期离开了fan函数还没有结束。
下面对 i 进行使用呢?来判断下作用域。
例 10:
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第7张图片
这可以看出 i 不能使用了,就是作用域不变还是fan函数,所以static修饰的局部变量不是全局变量。

2.7 总结引入static的目的

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

**

下期预告

**
下期讲struct结构体相关内容,下期更精彩哦!
常考点 static关键字详解 4个小时的码字希望对 各位读者 有帮助_第8张图片

你可能感兴趣的