道阻且长,行则将至。埋头苦干,不鸣则已,一鸣惊人!加油,骚年!
前言
我是看到一篇介绍 C 语言全局变量的文章时,深有感触,细细一想,我貌似对于这些变量的理解也是一知半解,因此就有了这篇笔记。
参考资料
参考文章:C语言中,全局变量滥用的后果竟如此严重?《https://mp.weixin.qq.com/s/cijGikfwy4XfRqfvufmUIA》
基本理解
- 『局部变量』:定义在函数内部,只有在函数内部才有效;特点:进来创建,出去销毁;
- 『静态局部变量』:定义在函数内部,只有在函数内部才有效;但是只会在开始分配一次内存,不会消失;特点:进来创建,一直保留;
- 『全局变量』:定义在所有函数之外,整个工程都可以使用;其他文件使用要加 extern 关键字;且需要注意,改动一处全局变量的值会影响所有相同全局变量;特点:开始创建,一直保留;
- 『静态全局变量』:定义在所有函数之外,和全局变量一样,但是只有定义的文件才能使用;特点:开始创建,一直保留,自己可用;
总结了一个图表,协助加深理解。
局部变量 | 局部静态变量 | 全局变量 | 全局静态变量 | |
---|---|---|---|---|
作用域 | 局部 | 局部 | 全局 | 全局 |
内存空间 | 栈 | 静态存储区 | 静态存储区 | 静态存储区 |
生命期 | 临时 | 长期 | 长期 | 长期 |
总结特点 | 临时创建,出去销毁。 | 临时创建,一直保留。 | 开始创建,一直保留。 | 开始创建,一直保留,自己可用。 |
各个击破
局部变量
局部变量,就是在函数内部定义的变量,只在函数内部有效。
简单测试代码如下:
#include <stdio.h>
int main()
{
int iTemp = 10; // 这是一个局部变量
printf("iTemp = %d\n", iTemp);
}
上述代码测试结果如下:
pi@raspberrypi:~/08-Programming/10-test/12-variableTest $ gcc jubu.c -o jubu.out
pi@raspberrypi:~/08-Programming/10-test/12-variableTest $ ./jubu.out
iTemp = 10
静态局部变量
顾名思义,还是一个局部变量,同样是在函数内部定义,只不过是 静态 的,也就是存储方式和生存周期不一样。
简单测试代码如下,在主函数中,循环调用 5 次子函数 TempAdd() ,打印出来。
#include <stdio.h>
int TempAdd()
{
static int iTemp = 0; // 这是一个静态局部变量
iTemp++;
return iTemp;
}
int main()
{
for(int i = 0; i < 5; i++)
{
printf("Temp = %d\n", TempAdd());
}
}
可以猜一下程序运行结果,如下:
pi@raspberrypi:~/08-Programming/10-test/12-variableTest $ gcc jubujingtai.c -o jubujingtai.out
pi@raspberrypi:~/08-Programming/10-test/12-variableTest $ ./jubujingtai.out
Temp = 1
Temp = 2
Temp = 3
Temp = 4
Temp = 5
由上述运行结果可以看到,在主函数中第一次调用子函数时,创建静态局部变量 iTemp ,之后每次调用,不会重新赋初始值,而是直接使用原有值。
体现了原则:临时创建,一直保留;
全局变量
全局变量,定义在所有函数之外的变量,对整个工程文件有效。当前文件可直接使用,如果不是当前文件,则需在调用文件开头加上关键字 extern 。
简单测试代码如下:
#include <stdio.h>
int iTemp = 0; // 这是一个全局变量
int main()
{
for(int i = 0; i < 5; i++)
{
printf("iTemp = %d\n", iTemp++);
}
}
测试结果如下:
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/13-quanju $ gcc quanju.c -o quanju.out
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/13-quanju $ ./quanju.out
iTemp = 0
iTemp = 1
iTemp = 2
iTemp = 3
iTemp = 4
为了更明显的体现出来是全局变量,我再写一个子函数调用,代码如下:
#include <stdio.h>
int iTemp = 0; // 这是一个全局变量
void TempAdd()
{
iTemp++;
}
int main()
{
for(int i = 0; i < 5; i++)
{
printf("iTemp = %d\n", iTemp++);
}
printf("----------This is a Dividing line!---------\n");
TempAdd();
printf("iTemp = %d\n", iTemp);
}
运行结果如下,可以稍稍思考一下为什么最后一次 iTemp 的值为 6 ?
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/13-quanju $ gcc quanjuV2.c -o quanjuV2.out
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/13-quanju $ ./quanjuV2.out
iTemp = 0
iTemp = 1
iTemp = 2
iTemp = 3
iTemp = 4
----------This is a Dividing line!---------
iTemp = 6
静态全局变量
静态全局变量,也是一个全局变量,不过加上 静态 之后,就限定了此变量的作用范围。
为了测试验证静态全局变量,我做了个简单的实验,但是结果却不是尽如人意,但还是先整理一下思路,在后续学习的过程中,还需再次加深理解。
我定义了三个文件:main.c
、static.c
、static.h
,其中静态全局变量定义在 static.h
中,具体代码如下:
// main.c
#include <stdio.h>
#include "static.h"
int main()
{
iTemp = 10;
printf("iTemp = %d\n", iTemp);
}
// static.c
#include <stdio.h>
#include "static.h"
void TempTest()
{
for(int i = 0; i < 5; i++)
{
iTemp++;
printf("iTemp = %d\n", iTemp);
}
}
// static.h
#ifndef _STATIC_H_
#define _STATIC_H_
static int iTemp = 0; // 这是一个静态全局变量
#endif
上述代码,编译运行的结果如下:
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/14-quanjujingtai $ gcc main.c static.c static.h -o a.out
pi@raspberrypi:~/08-Programming/10-test/12-variableTest/14-quanjujingtai $ ./a.out
iTemp = 10
至于为什么会出现这样的结果,我思考了一下,可能有如下几方面的原因:
- 主函数中包含了定义 静态全局变量 的头文件;
- 这样的代码结构不太规范,达不到测试 静态全局变量 的标准;
- 其他可能原因暂时还没想到;
总结
- 只是对这四种变量类型,有一个基础的了解,后续还要继续深入;
- 在总结过程中,发现了一些其他更深入的资料,但是我感觉较好的方法是:在一个阶段时,总结输出一个阶段的东西;然后步入下一个阶段,再总结;等到几个阶段过后,回顾总结一下已经学过的几个阶段的知识,输出一个较为深刻的笔记总结。
- 在学习的过程中,一定要让自己多加思考,不能说自己学习的东西,过一眼就完了,如果不自己思考,就不会形成自己的见解,也就不会融入到自己的知识体系中!
如果文章内容有误,麻烦评论/私信多多指教,谢谢!如果觉得文章内容还不错,记得一键三连哦(点赞、收藏、留言),您的支持就是对我最大的鼓励,谢谢您嘞!