[C]变量作用域
函数环境变量作用域
C语言栈环境变量作用域跟JS是类似的。
就是内部函数可以访问外部函数的执行(栈)环境变量。
当访问一个变量时,程序将会查询当前栈环境是否存在这个变量,如果没有,将会往上层栈环境继续查找,直到找到该变量为止。
#include <stdio.h>
#include <stdlib.h>
#include <string.h> void test_1(void);
void test_2(void);
void test_3(void); int main(void)
{
int count = ; void test_1(void)
{
int count = ;
printf("%d\n", ++count);
}
void test_2(void)
{
printf("%d\n", ++count);
void test_3(void)
{
printf("%d\n", ++count);
}
test_3();
}
test_1();
test_2();
return ;
}
示例代码中,
函数test_1由于栈环境内部声明了变量count,所以输出了当前变量++count,即等于5,不再往上查找。
函数test_2在第一句中访问了变量count,由于在它自身栈环境中不存在变量count,所以它将会往上一层查找main函数中是否存在count,因为main确实存在变量count,所以给它递增了1,此时count变成了3。
函数test_3的查找方式也是类似的,由于自身栈环境找不到count,所以它将会往上一层查找test_2函数中是否存在count,发觉test_2也不存在count,再往上一层查找,直到找到count为止,最终在main找到了count,此时函数给它再递增1,count的值变成了4。
static关键字
C语言static关键字跟PHP是类似的。
栈环境退出后,static关键字的变量不会被销毁。
如果是初次进入栈环境,这个变量将会被初始化为声明语句赋予的值。
如果是再次进入栈环境,则采用上一次运行后产生的值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h> void test_1(void); int main(void)
{
int i = ;
for (; i < ; ++i)
{
test_1();
}
return ;
} void test_1(void)
{
static int count = ;
printf("%d\n", ++count);
}
示例代码中:
函数test_1被执行了3次。
第一次执行时,静态变量count被初始化为2,在下一句中被递增1,然后退出环境,但此时count并不会被销毁。
第二次执行时,由于上一次执行的时候count已经初始化了,所以此时count使用的是上一次栈环境退出时保存下来的值。
第三次执行过程雷同。
结果三次依次输出了3,4,5;
总结示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h> void test_1(void);
void test_2(void); int count = ; int main(void)
{
int count = ;
int i = ;
for (; i < ; ++i)
{
test_1();
test_2();
}
printf("%d\n", ++count);
return ;
} void test_1(void)
{
static int count = ;
printf("%d\n", ++count);
} void test_2(void)
{
printf("%d\n", ++count);
}
示例代码中:
main访问了栈内部定义的count。
test_1访问了栈内部定义的静态变量count。
test_2访问了栈外部(这里是全局变量)的count。
最终输出结果是21,1,22,2,23,3,11。
误区
当函数f内部访问另外一个函数c,函数c的外部栈环境不一定是f哦。
栈环境是谁,取决于函数编写在哪个位置。
例如上述示例代码,test_1,test_2的栈环境是全局环境,并不是main哦,main只是调用了它们而已。
块作用域
C语言有块作用域。
在{}区域下声明的变量,只有在这个区域下才可以访问。
#include <stdio.h>
#include <string.h> int count = ; int main(void)
{
int i = ;
if(i == ){
int test = ;
}
printf("%d\n", test);
}
示例代码中:
printf("%d\n", test);会抛出一个错误,因为test声明在if块作用域下,外层访问不到。
[C]变量作用域的更多相关文章
- javascript中的变量作用域以及变量提升
在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解. 变量作用域 “一个变量的作用域表示这个变量存在的上 ...
- [转]深入理解JavaScript的变量作用域
1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...
- Java基础知识笔记(七:接口、变量作用域和参数传递)
一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...
- PHP常量、变量作用域详解(一)
PHP 中的每个变量都有一个针对它的作用域,它是指可以在其中访问变量(从而访问它的值)的一个领域.对于初学者来说,变量的作用域是它们所驻留的页面.因此, 如果你定义了 $var,页面余下部分就可以访问 ...
- PHP变量作用域详解(二)
学过C的人用PHP的时候一般会相当顺手,而且感到PHP太方便太轻松.但在变量作用域这方面却与C有不同的地方,搞不好会相当郁闷,就找不到错误所在.昨晚就与到这么一个问题,是全局变量在函数中的问题.今天搜 ...
- JavaScript函数定义和调用 变量作用域
本文是笔者在看廖雪峰老师JavaScript教程时的个人总结 JavaScript中函数定义可以是这样的格式 function 函数名(参数) { 函数体 } 也可以是这样的格式 ...
- JavaScript 变量作用域
一. 变量声明 变量用var关键字来声明,如下所示: 变量在未声明的情况下被初始化,会被添加到全局环境. JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境.每个函数在被 ...
- 变量作用域&函数作用域
一. 变量作用域 1)全局变量 在全局环境下声明的变量被视为全局变量. 在没有使用var进行声明的时候,变量就被定义为全局变量.在ES5的严格模式下,如果变量没有使用var来声明是会报错的. 2)局部 ...
- OC点语法和变量作用域
OC点语法和变量作用域 一.点语法 (一)认识点语法 声明一个Person类: #import <Foundation/Foundation.h> @interface Person : ...
- python的变量作用域问题
偶然掉进了一个坑里.仔细分析了下原因.原来是变量作用域的问题.简单抽象如下: id=1 #许多行代码 [id for id in range(10)] #许多行代码 if id!=1: #做一些事情 ...
随机推荐
- shutdown函数
#include <sys/socket.h> int shutdown(int sockfd, int howto); 返回:若成功则为0,若出错则为- (1)该函数的行为依赖于howt ...
- 新浪某站CRLF Injection导致的安全问题
CRLF攻击的一篇科普:新浪某站CRLF Injection导致的安全问题(转) 转:https://www.leavesongs.com/PENETRATION/Sina-CRLF-Injectio ...
- postfix 邮箱接收限制
Postfix 限制 QQ 邮箱发送到 我的 test.com 域下邮箱. 1.编辑 main.cf 添加限制: smtpd_sender_restrictions = check_sender_a ...
- 线段树模板(hdu1166)
#include <set> #include <map> #include <queue> #include <stack> #include < ...
- mui卡片视图的制作
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- websocket和socketio的总结
1.WebSocket是什么? WebScoket是一种让客户端和服务器之间能进行双向实时通信的技术.它是HTML最新标准HTML5的一个协议规范,本质上是个基于TCP的协议,它通过HTTP/HTTP ...
- Leetcode#867. Transpose Matrix(转置矩阵)
题目描述 给定一个矩阵 A, 返回 A 的转置矩阵. 矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引. 示例 1: 输入:[[1,2,3],[4,5,6],[7,8,9]] 输出:[[1 ...
- 使用WebView时软键盘遮挡H5页面解决办法
简单解决办法:在清单文件中添加 android:windowSoftInputMode="adjustResize" 此举可在软键盘弹出时,重新测量布局,保证不遮挡光标的所在位置. ...
- python - beautifulsoup4模块
# beautifulsoup4学习 # 是一个python模块 用于接受一个HTML 或 XML 字符串,然后将其进行格式化,之后便可以使用模块提供的方法进行快速查找指定元素, # 从而是的在HTM ...
- 20165337岳源 第四次实验 Android开发
1.实验要求: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)>第二十四章 参考http://www.cnblogs.com ...