C语言系列之——(3)C语言中的变量
1.什么是变量
变量就是程序运行中可以变化的值,本质上是内存中一块被命名的存储空间,用来存放数据
(可以把变量想象成一个带名字的 “盒子”,盒子里可以放不同的东西【数据】,盒子本身的
位置【内存地址】是固定的。)
2.变量的作用域和生命周期
变量的作用域:变量能在哪段代码区域里使用(能用的范围)
变量的生命周期:变量在内存中存在多久(存在时间)
3.变量的定义与初始化
在 C 语言中,变量创建的本质,就是向内存申请一块连续的存储空间,用来存放对应类型的数据,而申请的空间大小,由变量的数据类型直接决定
变量的定义/创建的语法如下:
数据类型 变量名
(在定义变量时若没有赋初始值,变量中仍然会有值,在下面说明变量存储位置时会说)
或
数据类型 变量名 = 初始值
(在定义变量时赋了初始值,叫做变量的初始化)
注意:变量名的取法是有规范的
1.只能由字母、数字、下划线组成
2.不能以数字开头
3.不能和 C 语言的关键字重名(比如int、if、return等)
4.变量名区分大小写:age和Age是两个不同的变量
(如user_name、maxValue、_count等都是合法变量名)
4.变量分类
C语言中,变量可以分为 局部变量 、 全局变量 、静态变量。
a.局部变量
定义在大括号{}里的变量就叫做局部变量 (如函数体、main函数、循环体内部)
作用域:仅在定义它的代码块里(定义它的{}里)有效
生命周期:在进入代码块时创建,代码块运行结束离开代码块时销毁
请看下面的例子:
#include <stdio.h>
int num()
{
int a = 9;
return a;
}
int main()
{
num();
printf("%d\n",a);
return 0;
}
上面的代码在编译时会报错,因为a是定义在函数体中的变量,只在函数体内部(函数体的{}内部)有效,在main函数内部(main函数的{}内部)使用a变量时因为找不到a的定义所以会报错
b.全局变量
定义在函数外部({}外部,main函数也是函数)的变量叫做全局变量
作用域:不仅当前源文件可使用,整个程序都能使用(程序常常涉及到多文件,当要使用在其他文件内定义的全局变量时,要使用extern声明)
生命周期:程序运行期间一直存在
下面分别是test1.c与test2.c文件中的代码
//test1.c
#include <stdio.h>
int a = 10;
int main()
{
printf("%d\n",a);
return 0;
}
//test2.c
#include <stdio.h>
extern int a;
int main()
{
printf("%d\n",a);
return 0;
}
test1.c可以单独正常运行,而test2.c只是用extern声明了test1.c中的全局变量a,没有定义,所以不能单独运行;
必须把 test1.c 和test2.c 一起编译链接,这样test2.c才能找到test1.c中a的定义,才能运行
c.静态变量
在定义变量时,在变量类型前加上 static 关键字,就得到了静态变量
static 变量类型 变量名
c1.局部静态变量
定义在{}内部的静态变量叫做局部静态变量
#include <stdio.h>
int main()
{
static char character = 'j';//character就是一个静态全局变量
return 0;
}
static并不改变局部变量的作用域,但是会将局部变量的生命周期延长至整个程序
请看下面代码
下面实现了一个打印函数myprint,函数内定义了一个局部静态变量num,初始值为1
每次调用该打印函数,都会先打印num的数值,再给num加1,main函数里循环调用了myprint函数三次
打印结果是什么呢?
#include <stdio.h>
void myprint()
{
static int num = 1;
printf("%d\n",num);
num = num + 1;
}
int main()
{
for(int j = 0;j<3;j++) myprint();
return 0;
}
程序运行结束之后,打印结果为:
1
2
3
上面的结果说明,函数结束后,num变量并没有被销毁,而是仍然存在,并且随着函数调用,num的值在原来的基础上加1
这说明被static修饰的局部变量的生命周期确实被延长了
有人可能会问:为什么每次调用myprint时都定义了num的值为1,但是在这三次调用中,只第一次确实将num的值定义成了1,而后两次该定义并没有改变num的值,num依然保存着上一次函数执行结束的值并且在此基础上加1呢?
这是因为:静态变量只初始化一次,后续调用定义不再重新赋值,而是保留原值
c2.全局静态变量
用static修饰全局变量,并不会改变全局变量的生命周期,其生命周期依旧是整个程序
用static修饰全局变量,主要是为了限制全局变量的作用域,让其只在当前源文件中有效,而不是和之前一样在当前工程中的所有文件都有效,阻止其他文件对该变量的访问
5.变量在内存中的存储区域
我们常关注内存中的三个区域:栈区,堆区,静态区
(其实内存区域的划分会更加细致,在后续操作系统部分的文章会说明)

栈区:用于存放程序运行中的临时数据,遵循 先进后出(LIFO) 的规则
当程序进入一个函数 / 代码块 {} 时,系统才会开辟栈空间,自动为栈变量分配内存(压栈)。当程序离开这个函数 / 代码块时,系统会自动释放栈内存(出栈),变量直接失效。
栈区的大小在程序启动时就固定了,不能动态扩展。因为栈的内存地址是连续的,且操作只有 “压栈 / 出栈” 两种,所以访问速度比堆区快得多。
局部变量存储在栈区
因为栈区的内存不会自动清零,新变量分配的空间里,可能残留着之前留下的旧数据,也就是 “脏数据”,所以在定义局部变量时,若没有初始化局部变量,局部变量的值就是随机的垃圾值
静态区:是操作系统在程序加载启动时,就直接划分好的一块独立内存区域,专门用来存放生命周期贯穿整个程序运行过程的数据,程序运行期间不会随意释放,直到程序彻底退出才统一回收
全局变量与静态变量放在静态区
因为静态区内存系统会自动清零,所以没有初始化的静态区变量,默认值固定为 0
(char → '\0',float/double → 0.0)
堆区用于动态内存管理,在后续文章中会说到
posted on 2026-10-19 10:21 progressive_bird 阅读(5) 评论(0) 收藏 举报
浙公网安备 33010602011771号