函数环境变量作用域

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]变量作用域的更多相关文章

  1. javascript中的变量作用域以及变量提升

    在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解. 变量作用域 “一个变量的作用域表示这个变量存在的上 ...

  2. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  3. Java基础知识笔记(七:接口、变量作用域和参数传递)

    一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...

  4. PHP常量、变量作用域详解(一)

    PHP 中的每个变量都有一个针对它的作用域,它是指可以在其中访问变量(从而访问它的值)的一个领域.对于初学者来说,变量的作用域是它们所驻留的页面.因此, 如果你定义了 $var,页面余下部分就可以访问 ...

  5. PHP变量作用域详解(二)

    学过C的人用PHP的时候一般会相当顺手,而且感到PHP太方便太轻松.但在变量作用域这方面却与C有不同的地方,搞不好会相当郁闷,就找不到错误所在.昨晚就与到这么一个问题,是全局变量在函数中的问题.今天搜 ...

  6. JavaScript函数定义和调用 变量作用域

     本文是笔者在看廖雪峰老师JavaScript教程时的个人总结   JavaScript中函数定义可以是这样的格式 function 函数名(参数) {     函数体 } 也可以是这样的格式     ...

  7. JavaScript 变量作用域

    一. 变量声明 变量用var关键字来声明,如下所示: 变量在未声明的情况下被初始化,会被添加到全局环境. JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境.每个函数在被 ...

  8. 变量作用域&函数作用域

    一. 变量作用域 1)全局变量 在全局环境下声明的变量被视为全局变量. 在没有使用var进行声明的时候,变量就被定义为全局变量.在ES5的严格模式下,如果变量没有使用var来声明是会报错的. 2)局部 ...

  9. OC点语法和变量作用域

    OC点语法和变量作用域 一.点语法 (一)认识点语法 声明一个Person类: #import <Foundation/Foundation.h> @interface Person : ...

  10. python的变量作用域问题

    偶然掉进了一个坑里.仔细分析了下原因.原来是变量作用域的问题.简单抽象如下: id=1 #许多行代码 [id for id in range(10)] #许多行代码 if id!=1: #做一些事情 ...

随机推荐

  1. [Android] Android 的singleLine废弃解决

    之前写代码时,都没有注意singleLine已经废弃,每次想让TextView或Edittext单行显示都是直接使用,但是这样其实不好,因为废弃的函数可能在有的手机上出现问题,所以需要自己去找到替换的 ...

  2. 开源ETL工具之Kettle介绍

    What 起源 Kettle是一个Java编写的ETL工具,主作者是Matt Casters,2003年就开始了这个项目,最新稳定版为7.1. 2005年12月,Kettle从2.1版本开始进入了开源 ...

  3. java操作数据库:分页查询

    直接上.... 还是用之前的goods表,增加了一些数据 1.实体类Goods // 封装数据 public class Goods { private int gid; private String ...

  4. java mongoTemplate的group统计

    @Service public class MongoCountServiceImpl implements MongoCountService { @Autowired private MongoT ...

  5. MySQL安装 8.0.15版本

    windows下MySQL 8.0.15的安装和设置 MySQL下载地址:https://dev.mysql.com/downloads/mysql/ 我的百度网盘下载(win64位):链接:http ...

  6. wordpress网站分类目录怎么排序

    1.插件实现分类目录排序.安装插件My Category Order 启用插件,在控制面板的文章菜单下就出现如下图所示的目录调整选项,可以用鼠标随意拖曳调整目录排列顺序. 2.修改代码完成wordpr ...

  7. cpp typename关键字

    泛型编程关键字,C#内也有这个概念. 从属名称(dependent names):模板(template)内出现的名称, 相依于某个模板(template)参数, 如T t; 嵌套从属名称(neste ...

  8. TensorFlow从入门到理解(五):你的第一个循环神经网络RNN(回归例子)

    运行代码: import tensorflow as tf import numpy as np import matplotlib.pyplot as plt BATCH_START = 0 TIM ...

  9. 在已有的Java项目中使用Kotlin

    需要配置两个地方首先在项目点gradle文件中引入Kotlin插件 然后在module的build.gradle文件中应用插件

  10. react-踩坑记录——页面底部多出一倍高度的空白

    挂载slider组件后页面底部多出一倍高度的空白,如下: slider组件内容⬇️: class Slider extends Component{ constructor(){ super(); } ...