网站首页 > 技术文章 正文
不知道大家如何,反正我最开始接触 C 语言编程时,最让我觉得神奇的就是变量的使用了,“a=1”之后又可以“a=0”。事实上,不仅仅是 C 语言,无论哪一门编程语言,变量都是基石,离开变量啥都做不了。
变量和赋值
请看下面的例子,很容易明白,变量只是一个容器,真正具有使用意义的是它装载的数据。C 语言中的“=”可以改变变量装载的数值,程序员常常称这一过程为“赋值”。
#include <stdio.h> int main() { int a = 3; printf("the variable is %d\n", a); return 0; } // 程序输出 the variable is 3
变量就好像鞋柜一样,它可以装很多不同的鞋子。里面装了布鞋,你可以从中拿出布鞋穿。里面装了皮鞋,你可以从中拿出皮鞋穿。“=”就相当于往鞋柜放鞋子。
局部变量和全局变量
局部变量
我们把函数中定义的变量称为局部变量,因此函数的形参也属于局部变量,这里的局部变量有两个含义:
1、某个函数中定义的变量,不能被另一个函数使用。请看下面的例子,我们在 print_int 函数中定义了变量 b,它是不能在 print_again 里使用的。所以下面这样写,就会报语法错误。关于语法错误可参考我之前的文章。《程序员在测试没发现bug时,内心其实慌的一批,有bug反而踏实》
void print_int(int a) { int b = 3; printf("%d, %d\n", a, b); } void print_again() { printf("%d\n", b); }
2、每次调用函数时,局部变量都表示不同的存储空间。局部变量实在每次函数调用时,才分配的存储空间,被调用函数返回时,这部分存储空间就被释放了。例如上面这个程序,调用 print_int(2) 时,分配给 a 的存储空间里存放的是 2。下一次调用 print_int(3) 时,分配给 a 的存储空间存放的就是 3 了。
全局变量
与局部变量相对应的就是全局变量了,全局变量在整个程序的所有函数中,都能访问。我们将上面的代码做一点点修改,即将 b 变为全局变量,请看如下代码:
int b = 1;
void print_int(int a)
{
b = 3;
printf("%d, %d\n", a, b);
}
void print_again()
{
printf("%d\n", b);
}
这时再编译,就不会出现语法错误了。那执行 print_again 函数,会输出多少呢?答案是取决于函数的执行顺序。b 被初始化为 1,如果之前没有调用 print_int ,那调用 print_again 打印出的 b 的值就是 1。如果先调用 print_int,再调用 print_again,那打印出的就是 3。因为在 print_int 中,b 被修改为 3 了。
源代码的书写顺序并不代表函数的执行顺序。
可以看出,全局变量使用起来虽然方便,但是一定要慎用。因为任意位置都可能会修改它,而对于大型规模的开发,理清调用顺序也是一件体力活,出现了 bug 可能就是因为某个不起眼的地方对全局变量的读写造成的。
全局变量的初始化只能用常量表达式初始化,例如,对 pi 全局变量初始化时合法的:
double pi = 3.14 + 0.0016;
但这样初始化是不合法的:
double pi = acos(-1.0);
下面这样的初始化也是不合法的:
int minute = 360; int hour = minute / 60;
全局变量和局部变量同名
则第一次调用print_time打印的是全局变量的值,第二次直接调用printf打印的则是main函数的局部变量的值。在C语言中,每个标识符都有特定的作用域(Scope),全局变量是定义在所有函数体之外的标识符,它的作用域从定义的位置开始直到源文件结束,而main函数局部变量的作用域仅限于main函数之中。如上图所示,设想整个源文件是一张大纸,也就是全局变量的作用域,而main函数是贴在这张大纸上的一张小纸,也就是main函数局部变量的作用域。在小纸上用到标识符hour和minute时应该参考小纸上的定义,因为大纸(全局变量的作用域)被盖住了,如果在小纸上用到某个标识符却没有找到它的定义,那么再去翻看下面的大纸,例如上图中的变量x。
猜你喜欢
- 2024-10-26 C语言、嵌入式项目中一些常用知识及技巧第一弹
- 2024-10-26 C语言编程:最常见 7 道C语言面试题,还是有不少人弄不明白?
- 2024-10-26 初识C语言:简介、环境搭建、第一个HelloWorld
- 2024-10-26 C|volatile关键字使用细节及适用场合
- 2024-10-26 C语言干货:函数知识详解(变量的作用域,全局变量,静态变量)
- 2024-10-26 小白入门C语言20问20答2(新手c语言)
- 2024-10-26 C语言的简单了解及学习2(c语言的入门知识)
- 2024-10-26 C 语言基本语法(c语言的基础语法)
- 2024-10-26 C语言数据怎么描述?最全面解析,C语言基础教学档案!编号零零五
- 2024-10-26 C语言void关键字的高级玩法,6个样例代码告诉你
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 506℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 485℃MySQL service启动脚本浅析(r12笔记第59天)
- 465℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 463℃启用MySQL查询缓存(mysql8.0查询缓存)
- 443℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 422℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
-
- netty系列之:搭建HTTP上传文件服务器
- 让deepseek教我将deepseek接入word
- 前端大文件分片上传断点续传(前端大文件分片上传断点续传怎么操作)
- POST 为什么会发送两次请求?(post+为什么会发送两次请求?怎么回答)
- Jmeter之HTTP请求与响应(jmeter运行http请求没反应)
- WAF-Bypass之SQL注入绕过思路总结
- 用户疯狂点击上传按钮,如何确保只有一个上传任务在执行?
- 二 计算机网络 前端学习 物理层 链路层 网络层 传输层 应用层 HTTP
- HTTP请求的完全过程(http请求的基本过程)
- dart系列之:浏览器中的舞者,用dart发送HTTP请求
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)