• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

progressive_bird

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

C语言系列之——(3)C语言中的变量

目录
  • 1.什么是变量
  • 2.变量的作用域和生命周期
  • 3.变量的定义与初始化
  • 4.变量分类
    • a.局部变量
    • b.全局变量
    • c.静态变量
      • c1.局部静态变量
      • c2.全局静态变量
  • 5.变量在内存中的存储区域

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.变量在内存中的存储区域

我们常关注内存中的三个区域:栈区,堆区,静态区
(其实内存区域的划分会更加细致,在后续操作系统部分的文章会说明)

image

栈区:用于存放程序运行中的临时数据,遵循 先进后出(LIFO) 的规则
当程序进入一个函数 / 代码块 {} 时,系统才会开辟栈空间,自动为栈变量分配内存(压栈)。当程序离开这个函数 / 代码块时,系统会自动释放栈内存(出栈),变量直接失效。
栈区的大小在程序启动时就固定了,不能动态扩展。因为栈的内存地址是连续的,且操作只有 “压栈 / 出栈” 两种,所以访问速度比堆区快得多。

局部变量存储在栈区
因为栈区的内存不会自动清零,新变量分配的空间里,可能残留着之前留下的旧数据,也就是 “脏数据”,所以在定义局部变量时,若没有初始化局部变量,局部变量的值就是随机的垃圾值

静态区:是操作系统在程序加载启动时,就直接划分好的一块独立内存区域,专门用来存放生命周期贯穿整个程序运行过程的数据,程序运行期间不会随意释放,直到程序彻底退出才统一回收

全局变量与静态变量放在静态区
因为静态区内存系统会自动清零,所以没有初始化的静态区变量,默认值固定为 0
(char → '\0',float/double → 0.0)

堆区用于动态内存管理,在后续文章中会说到

posted on 2026-10-19 10:21  progressive_bird  阅读(5)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3