[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: #做一些事情 ...
随机推荐
- 细说JDK日志组件
1. 概述 JDK自带的日志组件在包java.util.logging下,如图: 2. 架构如上图所示,JDK日志组件核心元素包括:Logger,Handler,Filter和Formatter,他们 ...
- Java集合操作精华总结
一.Set1.HashSet boolean add(E e) 添加 访问 boolean remove(E e) 删除 Iterator<E> iterator 遍历 int size( ...
- Java根类Object的方法说明
Java中的Object类是所有类的父类,它提供了以下11个方法: public final native Class<?> getClass() public native int ha ...
- Sql分页代码示例
select * from (select ROW_NUMBER()over( order by id) orderid,* from test) a where a.orderid between ...
- JS面向对象的程序设计之理解对象
一.对象定义 (1)ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同: (2)ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值.对象或者函数” 二. ...
- React 体验
https://github.com/facebook/create-react-app npm i -g create-react-app cd <your-folder> creat ...
- Andrew NG 机器学习编程作业2 Octave
问题描述:用逻辑回归根据学生的考试成绩来判断该学生是否可以入学 这里的训练数据(training instance)是学生的两次考试成绩,以及TA是否能够入学的决定(y=0表示成绩不合格,不予录取:y ...
- Ubuntu中安装python3.6(转)
因为TensorFlow只支持到python3.6,所以安装python3.6版本 Python3.6的使用越来越普遍.Ubuntu16.04的版本中默认胸自带python2和python3.5的版本 ...
- Coursera, Machine Learning, SVM
Support Vector Machine (large margin classifiers ) 1. cost function and hypothesis 下面那个紫色线就是SVM 的cos ...
- Hive思维导图之Hive优化