C语言(变量的生命周期、作用域、默认值、内存区域、链接属性以及函数相关总结)

在C语言中,我们总是动不动就int a , int b , char c的,就像创造一个个小人一样,看似他们无拘无束,咱们造出来就管不着了。

实则,他们有着自己的寿命(生命周期),有着自己的活动范围(作用域),有着自己的国籍(链接属性),同时我们也能够通过移动变量位置和static、extern等关键字来管理他们。


总表

 在这里也是直接为大家提供参考的总表,接下来我们用一个个程序来验证他们。

内存区域 

在C语言所管理的内存中,我们大致可以抽象理解成为代码区、全局(静态)变量区、栈区、堆区。

代码区可以用以存储函数、全局(静态)变量区用以存储全局变量以及静态变量、栈区用以存储自定函数内部非静态的局部变量,堆区用以存储开发人员手动开辟的内存区域。

这里需要注意的全局(静态)变量区会将未初始化的变量全部自动赋值为0

实验测试

 普通局部变量与静态局部变量:

 一个非主函数的内部定义的变量可以称之为局部变量,未加static的局部变量为普通局部变量,反之为静态局部变量。

普通局部变量在函数结束时即释放,而静态变量则不会:

我们也必须注意到其中的一个细节:静态局部变量若未给出初值,将会自动赋0值

普通局部变量未给出初值会被赋随机值,因VS保护机制此实验略。

其实在静态局部变量这里也会有一个好玩的现象:

好的,你会发现我们多次进入函数func,但是在最初的static int s_part = 1;的语句并不会将s_part重新赋值为1,在这里,我们可以理解为已定义的静态局部变量进入函数后会直接忽视定义语句,直接执行下一语句。

但是,请注意,我们的局部函数是是无法被外部函数看到的:


  普通全局变量与静态全局变量:

全局变量在函数外部声明定义,不给出初值直接自动赋值为0。

普通全局变量加上static关键字会出现怎么样的变化呢?这其实需要两个文件来体现:

我们多添加一个temp.cpp文件,然后开干

在temp.cpp中加入两个全局变量的定义,然后我们到主函数程序中来尝试使用这两个全局变量。

 我们十分轻松的便使用到了另一个文件里的gloal,但若是加了static的s_gloal呢;

 VS直接干脆利落的报错。

 而若在声明位置加上static连编译也通不过了。

我们也不难理解,static 将普通全局变量的默认链接属性外部修改为了内部,仅限一个文件内部使用。


动态内存 :

我们手动开辟的内存能不能给其他的文件使用呢?

 答案是可以,但是我们不能说动态内存的链接属性是外部的,实际上我们是将动态内存地址给了一个全局指针,而我们在另一个文件中声明这个指针进行使用,是这个指针的链接属性是外部的,而并非动态内存能够外部链接,它不具备链接属性。


普通函数与静态函数 :

 与之前的普通转静态相似,静态函数只需直接将static加到函数返回值之前就实现了一个静态函数的声明。

接下来我们尝试在另一个文件里进行调用:

不加static编译器不报错,但运行时报错。

 添加了static则会在编译时报错。

编译与运行的结果与我们的普通全局变量和静态全局变量相同。

可见,static同样将默认链接属性为外部的普通函数修改为了内部。

实验调试代码(供以验证)

temp.cpp

#include<stdlib.h>
#include<stdio.h>

//int gloal=10;
//static int s_gloal=20;
//int* m_a = (int*)malloc(sizeof(int));
void func1()
{
	printf("this is a normal func\n");
}

static void func2()
{
	printf("this is a static func\n");
}

源.cpp 

#include<stdio.h>
#include<stdlib.h>

#if 0

void func()
{
	static int s_part = 1;
	int part = 0;

	printf("s_part=%d\n",s_part);
	s_part++;
}

int main()
{
	func();
	func();
	func();
	func();
	printf("part= %d , s_part = %d\n", part, s_part);

	return 0;
}
#endif

#if 0

extern int gloal;
extern /*static*/ int s_gloal;

void func()
{
	printf("gloal = %d, s_gloal = %d \n", gloal, s_gloal  );
}

int main()
{
	func();
	printf("gloal = %d, s_gloal = %d \n", gloal, s_gloal);

	return 0;
}

#endif

#if 0

extern int* m_a;

int main()
{
	*m_a = 1;
	printf("m_a = %d", *m_a);

	free(m_a);
	return 0;
}

#endif

#if 1

extern void func1();
extern static void func2();

int main()
{
	func1();
	func2();

	return 0;
}

#endif

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青锋杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值