【C语言入门教程】5.2 函数的作用域规则(auto, static)
作用域规则是指代码或数据的有效使用范围。C语言将函数作为独立的代码块,函数之间不能相互访问其内部的代码或数据。函数间数据的传递只能通过接口实现。但是,变量的定义方法可改变函数的作用域规则,可将变量分为 局部变量 和 全局变量 两种。
5.2.1 局部变量
在函数体内定义的变量称为 局部变量,局部变量的作用域仅限于该函数体内。声明局部变量的关键字为 auto,它的一般形式是:
auto 数据类型 变量名;
auto 关键字作为声明语句的默认值,所以通常省略。在函数中定义的局部变量,作用域在该函数体内,如:
void func()
{
int x = 1000;
printf("func()函数内的变量 x 值为:%d\n", x); // 输出为 func() 函数体内变量 x 的值
} int main()
{
int x = 2000;
func();
printf("main() 函数内的变量 x 值为:%d\n", x);
// 输出 main() 函数体内变量 x 的值
return 0;
}
func()函数 和 main() 函数各自定义了一个变量 x,在 func()函数中访问变量 x,则访问的是func()函数体内所定义的变量x。同理,main()函数只能访问其函数体内的变量x。这样,不同函数间的数据被独立起来,保证了数据的安全性。上例的输出为:
func()函数内的变量 x 值为:
main()函数内的变量 x 值为:
在独立的代码块内定义的局部变量,作用域在该代码块内,如下例所示:
int main()
{
int x = 100;
if (x < 150) // 这里引用的是main() 函数中定义的变量 x
{
int x = 200; // 在代码块中定义变量 x
printf("%d", x); // 这里引用的是代码块中定义的变量 x
}
return 0;
}
该程序输出的结果为 200,因为引用的是代码块中的变量x。如果去掉代码快中定义变量x的语句,那么输出的将是 main() 函数的变量x,输出结果为 100。假设在变量的一个作用域内,有同名的另一个变量的作用域,只有一个变量是有效的。如图 9.1 所示,作用域2被包含在作用域1内,2个作用域都定义了变量x。简单地说,定义位置与引用位置相近的变量是有效的,即作用域2内定义的变量x被引用。

5.2.2 全局变量
全局变量的作用域为整个源程序文件,文件中的所有函数或程序块都可以引用。当定义全局变量时,需将变量声明语句放置在所有函数外,如:
#include <stdio.h> int x = 1000;
void func(); int main()
{
printf("%d\n", x); // 引用全局变量 x
x = 2000; // 改变全局 x 的值
func(); // 调用函数 func() return 0;
} void func()
{
printf("%d\n", x); // 引用全局变量 x,此时全局变量 x 的值已被 main() 函数改变过
return;
}
5.2.3 动态存储变量
从变量的生存周期来分类,可将变量分为 动态存储变量 和 静态存储变量。动态存储变量在函数调用时存入内存,函数调用后从内存中删除。声明动态存储变量的关键字为 auto,与声明局部变量相同,它的一般形式是:
auto 数据类型 变量名;
auto 关键字作为声明语句的默认值,所以通常可省略。由于函数中的动态变量会在函数退出时删除,所以两次调用函数时,函数不会保存动态变量的数据。如下例所示:
#include <stdio.h> void func()
{
int x = 100;
printf("%d\n", x);
x += 100;
} int main ()
{
func();
func();
return 0;
}
此程序2次输出的值都是 100.因为即使func()函数第一次调用时改变了变量 x 的值,函数退出后变量x 被从内存中删除,第二次调用函数时又需要重新初始化 x ,所以2次输出的值相同。
还有一种动态存储变量称之为 寄存器变量,寄存器是位于 CPU 内部的存储单元,CPU读取寄存器内的数据极其快捷。因此,将程序中需要大量反复使用的变量设为寄存器变量可提高程序的运行速度。声明寄存器变量
的一般形式为:
register 数据类型 变量名;
寄存器资源非常有限,不同的操作系统 和 C 编译器对寄存器变量的使用有不同的限制。如 GCC 编译器通常限制寄存器变量的数量为 2个,将超过的寄存器变量当做普通动态变量处理。
5.2.4 静态存储变量
在编译时分配存储空间的变量称为静态存储变量。在函数退出时,静态存储变量依然被保留在内存中,再次执行同一函数会得到与上次退出时相同的数值。声明静态存储变量的关键字为 static,声明的一般形式为:
static 数据类型 变量名;
如下代码所示:
#include <stdio.h> void func()
{
static int x = 100; // 声明静态存储变量 x 并赋初值
printf("%d\n", x); // 输出 x 的值,此时变量 x 的值为 100
x += 100; // 改变 x 的值,此时变量 x 的值为 200
} int main ()
{
func(); // 第一次调用函数 func()
func(); // 第二次调用函数 func()
return 0;
}
第一次调用 func() 函数时,声明了静态存储变量 x,并为变量 x 赋初值 100,然后输出变量 x 的值,将变量 x 的值加上 100。func()函数退出后变量 x 仍然存在于内存中,所以第二次调用 func() 函数时,声明变量 x 并赋初值的语言不会被再次执行,因而第二次输出变量的值为 200。
【C语言入门教程】5.2 函数的作用域规则(auto, static)的更多相关文章
- Go语言入门教程(十)之函数
Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...
- 《Ruby语言入门教程v1.0》学习笔记-01
<Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...
- C语言入门教程-(5)格式化输入输出
1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...
- 《JavaScript语言入门教程》记录整理:入门和数据类型
目录 入门篇 js介绍 历史 基本语法 数据类型 概述 null 和 undefined 数值 字符串 对象 函数 数组 本系列基于阮一峰老师的<JavaScrip语言入门教程>或< ...
- 《JavaScript语言入门教程》记录整理:运算符、语法和标准库
目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...
- 《JavaScript语言入门教程》记录整理:面向对象
目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...
- 智能合约语言 Solidity 教程系列3 - 函数类型
Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...
- Linux pwn入门教程(10)——针对函数重定位流程的几种攻击
作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...
- c语言该怎么入门?C语言入门教程(非常详细)
C语言是一门面向过程的编译型语言,它的运行速度极快,仅次于汇编语言.C语言是计算机产业的核心语言,操作系统.硬件驱动.关键组件.数据库等都离不开C语言:不学习C语言,就不能了解计算机底层. 这套「C语 ...
随机推荐
- hihoCoder #1379 Emulator
hihoCoder Challenge 23, Prob. A 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 有一个\(n\)个点的无向正权图\(G\),这个图是连通的, ...
- .net数据库操作
刚接触到数据库时总是被数据库中的一些基本概念,比如Connection.Command.DataReader等,给整的糊里糊涂.如今,对数据库的基本操作有了一定的认识,特此做出总结,以便后续工作中查阅 ...
- Appium运行时,error: Logcat capture failed: spawn ENOENT的解决办法
目前发现有以下两种可能: 一:查看环境变量是否配置成功. ANDROIDSDK D:\my_2_softwares\JAVA\adt-bundle-windows-x86-20140702\sdkPA ...
- MySQL好用的数学函数
最近项目很忙,分给我的功能都比较复杂,还好能应付的下来.在工作的过程中,我发现使用mysql的自带函数能够极大的减少程序的复杂度.这是必然的,使用mysql的函数,能够在程序里面省却很多的循环遍历.但 ...
- JDBC编程的方式
JDBC编程的方式,我们以一个简单的查询为例,使用JDBC编程,如下: 从上面可以看出JDBC编程一般要如下步骤: 1. 加载数据库驱动 2. 创建并获取数据库连接 3. 创建jdbc stateme ...
- context.Request.Files为NULL问题 在实现图片上传功能的时候出现在ashx等处理页面出现context.Request.Files为NULL异常,有几点需要注意:
.在客户端可以将form用submit提交,如下: <%@ Page Language="C#" AutoEventWireup="true" CodeF ...
- dos命令复制当天生成的以日期为文件名的文件
1.利用SqlServer的自动备份功能,将数据自动备份,备份出的文件格式如下: db_backup_201001270930.bak 2.编辑bat脚本 ...
- RandomAccessFile类
File类只是针对文件本身进行操作,而如果要对文件内容进行操作,则可以使用RandomAccessFile类,此类属于随机读取类,可以随机地读取一个文件中指定位置的数据. //============ ...
- (转)HBase 的原理和设计
转自:HBase的原理和设计 HBase架构:
- Sky Box
http://www.keithlantz.net/2011/10/rendering-a-skybox-using-a-cube-map-with-opengl-and-glsl/ http://o ...