文档库 最新最全的文档下载
当前位置:文档库 › VFP-04-06-变量作用域、自定义函数汇总

VFP-04-06-变量作用域、自定义函数汇总

VFP-04-06-变量作用域、自定义函数汇总
VFP-04-06-变量作用域、自定义函数汇总

变量作用域、自定义函数

4.5.3 内存变量的作用域

变量的作用域:变量的作范围。程序由模块(主、子程序)组成,模块中有内存变量,内存变量有作用范围。变量的作用域,从定义变量处开始,一直向下。

1.定义全局内存变量

全局变量既可以是单个变量,也可以是数组。分别以下列格式定义。

格式1:Public <内存变量表>

格式2:Public <数组名1>(上界1[,上界2[, ...])[,…]

功能:定义全局变量。

①<内存变量表>中既可含普通变量,也可含数组。

②全局变量不会自动释放。只能用release命令显式释放,或退出VFP。

③VFP命令窗口中定义的变量,默认为全局变量。

④全局数组的每个元素都是全局的。

第116页,例 4.35主程序中使用子程序中定义的全局变量。

*文件名Main.prg

set talk off

clear

clear memory &&清除所有内存变量

I=2 &&默认是私有的

Do ABC

?"主程序中的输出结果:"

?"I="+str(I,2)+" J="+str(J,2)

set talk on

return

*---------------------

Procedure ABC

public J

J=I*8

J=J+5

?"过程中的输出结果:"

?"I="+str(I,2)+" J="+str(J,2)

return

小提示:要检测全局变量,请先clear memory以排除干扰。

2.定义局部内存变量

(1)什么叫局部?

更小的范围就是局部。对于一个模块,更后的部分是局部。对于主程序,子程序是局部。

(2)Private定义局部变量

格式1:Private <内存变量表>

格式2:Private <数组名1>(上界1[,上界2[, ...])[,…]

功能:定义局部变量。

①未经定义的变量,默认是局部(Private)的。

③无论全局还是局部变量,无初值的,一律自动赋初值.F.。

③局部变量作用域的子模块扩展规则

Private变量的作用域,通过调用子模块而扩展到子模块中。

图4-20 Private变量作用域子模块扩展规则

第117页,例 4.36子程序中的局部变量,在主程序中找不到。

R=100 &&默认为Private变量

Do Sub1 &&调用子程序

?P &&主程序中找不到这个变量

Return

*-------------------

procedure Sub1

P=2*3.14*R &&主程序中的Private变量,子程序中可用

return

3.Private隐藏内存变量的功能

(1)同名变量就近使用规则(原理)

程序中,对于同名的变量,默认使用最近的。因此,

①字段变量(因为在当前工作区内)优先于(即隐藏)同名内存变量;注:什么叫隐藏?就是被遮住,看不见,用不上。

图4-22 字段变量隐藏同名内存变量

例如 use student.dbf

use student.dbf

?学号 &&结果是字段变量“学号”值,如“960106”

学号="abcd" &&“=”号赋值,只给内存变量赋值

?学号 &&结果还是优先使用字段变量

?m.学号 &&特别用“m.”指明内存变量,结果才是“abcd”

②同一模块内,小局部存变量优先于(即隐藏)大局部同名内存变量;

图4-23 Private变量隐藏同模块同名变量

③不同模块中,子模块局部内存变量优先于(即隐藏)主模块同名内存变量。

图4-26 用Private隐隐藏变量

小提示:主程序中的private变量,子程序同样可以用private屏蔽。

(3)为什么大范围定义的局部变量,小范围中再定义为全局变量会出错?

因为那样,与Private的隐藏功能相矛盾。

第118页,例 4.37子程序中的同名局部变量隐藏主程序中同名变量。

R=100 &&默认为Private变量

P=10 &&默认为Private变量

Do Sub2 &&调用子程序

?P &&仍是主程序中的值

Return

*-------------------

procedure Sub2

Private P &&局部变量,主程序中的同名变量被屏蔽

P=2*3.14*R &&主程序中的Private变量,子程序中可用

Return

*(5)有没有不通过子程序扩展作用域的变量?

有,Local变量,即本地变量。如:Local x,y,z。

小提示:采用Local变量,是向C语言靠拢。

4.调用过程时的数据传递

教学提示:VFP的参数传递,过程中默认传址,函数中默认传值。

向过程传递数据,有两种方法。

(1)利用Private变量的作用域扩展规则,不传而传

过程中,可以直接使用主程序中的Private变量,不必传。

第118页,例 4.38计算矩形面积。

G=8 &&长

K=6 &&宽

mj=0 &&面积

do sub3

?Mj

return

*--------------

procedure sub3

mj=G*K

return

(2)在过程第一句用Parameters接收参数

主程序中传出参数格式:Do <过程名> With <实际参数表>

子程序中接收参数格式: Parameters <内存变量表>

说明:

①子程序中,Parameters必须是第一句。Parameters变量是Private变量。

②传值:Parameters后的变量与主程序中对应的实际参数无关。

③传引用:Parameters后的变量与主程序中对应的实际参数是同一个变量,名称可能不同而已,同时变化。

④引用隐藏实参规则

子模块中,引用参数隐藏实际参数,是因为引用参数与实际参数是同一个变量,只是在子模块中另取了一个名字(别名)而已。因此,原来的实际参数被隐藏,才不会混乱,包括实际参数是Public变量的情况。

⑤如何决定传值、传地址?由实际参数决定。过程的实际参数默认引用。要传值须实际参数加“()”,或者写成表达式。

图4-27 传值与传引用

第119页,例 4.39写程序运行结果。

set talk off

x=1

y=3

do sub4 with x,(y),5

?x,y

return

*----------------

Procedure sub4

parameters a,b,c

a=a+b+c

b=a+b-c

return

&&答: 9, 3

第120页,例 4.40利用一个过程计算矩形面积,要求在主程序输出该面积值。

set talk off

clear

input "矩形长:" to L

input "矩形宽:" to W

S=0

do Area with L,W,S

?"矩形面积:",S

return

*--------------

Procedure Area

Parameters C,K,M

M=C*K

return

4.5.4 自定义函数

1.自定义函数的结构

自定义函数实际上是一个过程,只不过其Return语句后带有表达式,能向主函数返回值。

格式:

Function <函数名>

[Parameters <形式参数表>]

<语句序列>

Return [<表达式>]

说明:

①缺省[<表达式>]返回.T.。

②与过程一样,自定义函数,可以单独以同名程序文件存储,也可以存入过程文件中。

2.自定义函数的调用

小提示:过程中叫实际参数的,函数中叫自变量。

格式:[[因变量]=] <函数名>(自变量表)

说明:

函数查找规则

调用函数时,先在内部函数中找;找不到再到打开的过程文件中找;再找不到,在当前文件夹中找;再找不到,出错。

①若自定义函数与内部函数同名,将不被找到,用不到。

②参数表要与自变量表相对应,包括类型和个数。

③自变量表中,可以是变量,也可以是表达式。自变量默认传值。要传引用,须在自变量前面加“@”,或SET UDFPARMS TO REFERENCE设置默认为传引用。

④函数可以当过程用,调用格式为“do <函数名> with 自变量表”。但要注意,当过程用时,默认传引用,因为过程默认传引用;且放弃返回值。

小提示:自变量默认传值,是向C语言靠拢。

小提示:过程默认传引用,函数默认传值。

第122页,例 4.41定义一个函数,将day()日期转成“公元年月日”格式。

Y=DA()

?Y

return

*-------------

Function DA

D="公元"+LTRIM(STR(YEAR(DATE())))+"年"

D=D+LTRIM(STR(MONTH(DATE())))+"月"

D=D+LTRIM(STR(DAY(DATE())))+"日"

Return D

第122页,例 4.42用自定义函数计算组合数。

)!

(!!),(n m n m n m C -=

y=c(5,3)

?y

return

*-------------------

Function FAC &&阶乘factor

parameters x

f=1

for k=1 to x

f=f*k

endfor

return f

*-------------------

Function C &&组合数conbination

parameters m,n

y=int(FAC(m)/(FAC(n)*FAC(m-n)))

return y *附加 4.5.5 自定义函数的括号参数格式

“()”在VFP 中是间接引用符,有传值之意。

1.自函数的“()式”结构

格式:

Function <函数名>([<参数表>])

<语句序列>

Return [<表达式>]

说明:这是自定义函数的另一种格式。它只是将Function 行和Parameter 行合并成一行,其它并无差别;其调用方式也没有区别。

小提示:表单自定义函数不能用括号参数格式,故一般不学、不用。 例 自定义函数fun1(x,y,z),分别将其当过程和“()式”函数调用。 A=123

B=234

C="abc"

clear

do fun1 with A, (B),C &&当过程用,默认传引用,但B 传值

?"A=",A,"B=",B,"C=",C

D=fun1(A,@B,@C) &&当函数用,默认传值,但B 和C 传引用

?"D=",D

Return

*-------------------

Function fun1(X,Y,Z) x=x+10000

y=y+10000

z=z+"12345"

return X+Y

变量的作用域与存储类别&&变量的生存期——天擎国际

变量的作用域与存储类别(变量的作用域——变量的生存期) 变量的作用域 ——局部变量和全局变量 变量的生存期 ——静态存储类别和动态存储类别(注意区别存储类型和函数类型) 变量的作用域 一、局部变量 定义:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效。 二、全局变量 定义:在函数之外定义的变量称为外部变量,或全局变量。它可为本文件中其他函数所共用。有效范围为从定义变量的位置开始到本源文件结束。 注意: 全局变量在程序的全部执行过程中都占有存储单元,而不是仅在需要时才开辟单元。 它使函数的通用性降低,因函数在执行时要依赖于其所在的外部变量。 降低了程序的清晰性。 在同名局部变量作用的范围内,外部变量被“屏蔽”。 变量的生存期

一、动态存储方式与静态存储方式 静态存储:在程序运行期间分配固定的存储空间的方式。 动态存储:在程序运行期间根据需要进行动态的分配存储空间的方式。 静态存储区:存储空间的分配在编译阶段进行,且存于其中的数据对象相对于程序的执行是永久的。 动态存储区:存储空间的分配是在程序的运行过程中进行的。 二、auto变量 调用函数时系统自动分配存储空间,在函数调用结束时自动释放这些存储空间,称这类局部变量为自动变量。 用关键字auto作存储类别的声明。它也可省。 三、用static声明局部变量 静态的 局部的 说明: 静态局部变量属于静态存储类别,在静态存储区内分配单元。在程序整个运行期都不释放。 自动变量属于动态存储类别,在动态存储区内分配单元,函数调用结束后即释放。 静态局部变量在编译时赋初值,以后每次函数调用时不再重新赋初值 ... .......而只是保留上次函 数调用结束时 ......的值。 自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值。 静态局部变量,如不赋初值,编译时自动赋初值0 或空字符。 自动变量,如不赋初值,它的值是一个不确定的值。 虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用。 一般在下列情况时,使用局部静态变量: 1、需要保留函数上一次调用结束时的值时; 2、如果初始化后,变量只被引用而不改变其值时。 四、register变量 说明: 1、只有局部自动变量和形参可作为register变量。 2、不能定义任意多个寄存器变量。 3、局部静态变量不能定义为寄存器变量。 五、用extern声明外部变量 在一个文件内声明外部变量 例:main( ) { extern A; /*外部变量声明*/ printf(“%d”,A); }

web前端面试100问

面试造火箭,工作拧螺丝! 在技术圈毕竟只有百分之一的人能进入BAT,百分之九九的小伙伴只能在普通公司做这普通的事情,厌烦哪些标题党,我们抛开那些高大上的台词,回归到面试的本质。 本课程帮助小伙伴们快速梳理知识,不会设计到具体的很细节的知识点,关注面试本身。 公司一般会从以下5个方面考察一个人的能力,本课程的100问是总结了最近2-3年常问的面试题,适合初中级前端工程师。 1、HTML(5)和CSS3方面 1.前端与后端数据交互的格式有哪些,为什么大部分现在都用json而不用xml。 答:XML:知了堂3岁 JSON:{ name:”知了堂”,age:3} JSON书写方便节省字节,更轻量,前后台都有直接解析JSON的方法(JSON.stringfity/parse)使用方便。 2.Flex布局熟悉吗,说几个常用的属性。 答:这个几乎每天都在用,还是挺熟悉的。 display:flex align-items 多个 align-content:单个 justify-content justify-items flex-direction flex-wrap: flex-basic:初始盒子宽度flex flex-grow:增长因子200 4*40=160 1,1,1,2 1/5*40 flex flex-shrink :缩减因子200 60*4=240 3.说一下CSS盒模型 答:CSS的盒模型包含了一下几个内容margin,padding,border,content。 在计算盒子宽高的时候,IE和Chrome会有一些区别,IE算到border,Chrome的宽度只包含content区域,因此CSS3提供了box-sizing这个属性来修改。

内部函数和外部函数解读

8.10 内部函数与外部函数 函数本质上是全局的,但可以限定函数能否被别的文件所引用。当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。 8.10.1 内部函数 如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。 定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示: static 函数类型函数名(函数参数表) {……} 关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。 8.10.2 外部函数 外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数: [extern] 函数类型函数名(函数参数表) {……} 调用外部函数时,需要对其进行说明: [extern] 函数类型函数名(参数类型表)[,函数名2(参数类型表2)……]; 例8.22 外部函数应用。 (1)文件mainf.c main() { extern void input(…),process(…),output(…); input(…); process(…); output(…); } (2)文件subf1.c extern void input(……)/*定义外部函数*/ {……} (3)文件subf2.c extern void process(……)/*定义外部函数*/ {……} (4)文件subf3.c…… extern void output(……)/*定义外部函数*/ {……} 例8.23 数组排序----简单选择排序 file1.c main()

作用域与闭包,js插件内部传递function()内部值

《作用域与闭包:this,var,(function () {})》目标 无具体目标 知识点 1.理解js 中var 的作用域 2.了解闭包的概念 3.理解this 的指向 课程内容 *es6中新增了let 关键词,与块级作用域,相关知识参 考:https://www.wendangku.net/doc/f12983928.html,/#docs/let * var 作用域 先来看个简单的例子: var parent=function () { var name ="parent_name"; var age =13; var child=function () { var name ="child_name"; var childAge =0.3;

// => child_name 13 0.3 console.log(name, age, childAge); }; child(); // will throw Error // ReferenceError: childAge is not defined console.log(name, age, childAge); }; parent(); 直觉地,内部函数可以访问外部函数的变量,外部不能访问内部函数的变量。上面的例子中内部函数child 可以访问变量age,而外部函数parent 不可以访问child 中的变量childAge,因此会抛出没有定义变量的异常。 有个重要的事,如果忘记var,那么变量就被声明为全局变量了。 function foo() { value ="hello"; }foo();console.log(value); // 输出hello console.log(global.value) // 输出hello 这个例子可以很正常的输出hello,是因为value变量在定义时,没有使 用var关键词,所以被定义成了全局变量。在Node 中,全局变量会被定义在global对象下;在浏览器中,全局变量会被定义在window对象下。

变量的作用域和生存期

变量的作用域局部变量和全局变量 在函数和复合语句内定义的变量,只在本函数或复合语句范围内有效(从定义点开始到函数或复合语句结束),他们称为内部变量或局部变量。 在函数之外定义的变量是外部变量,也称为全局变量(或全程变量)。 如果在一个函数中全局变量和局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即他不起作用,此时局部变量是有效的。 全局变量的作用是增加函数间数据联系的渠道。 虽然全局变量有以上优点,但建议不必要时不要使用全局变量,因为全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。 在程序设计时,对模块的划分要求:内聚性强,与其他模块的耦合性弱,这样便于程序的移植,可读性强。 变量的生存期 变量的存储方式分为两种:静态存储方式和动态存储方式。 静态存储方式是指在程序与性能期间由系统在静态存储区分配存储空间的方式,在程序运行器件不释放;而动态存储方式则是在函数调用期间根据需要在动态存储区分配存储空间的方式。这就是变量的存储区别。 Auto----声明自动变量 函数中的形参和在函数中定义的变量都属于此类。在调用这些函数时,系统给这些变量分配存储空间,函数调用结束时就自动释放这些存储空间。因为这类局部变量称为自动变量(auto 变量)。关键字auto作为存储类别的声明。 Auto可省略 Static-----声明静态变量 希望函数中的变量的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时就用关键字static指定该局部变量为“静态存储变量”。 对静态局部变量的说明 静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占胴体啊存储区空间而不占静态存储区空间,函数调用结束后即释放。 对静态局部变量是在编译时赋初值的,即只赋初值一次,在以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。自动变量赋初值是在函数调用时进行的。 对静态局部变量来说,编译时自动赋初值0或空字符。而对自动变量来说,如果不赋值则他的值是一个不确定的值。 Registic--声明寄存器变量 这种变量一般不用,只需了解就可以了。 Extern-----声明外部变量的作用范围 如果一个程序中有两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num,否则在进行程序的连接时会出现“重复定义”的错误。正确的做法:在人一个文件中定义外部变量Num,而在另一个文件中用extern对Num作外部变量声明,即extern Num.

windows2003域控制器的冗余

对于部署了AD架构的企业来说AD/DNS/DHCP/WINS都是我们必须用到的服务,一但这些服务中断会导致整个企业IT系统无法正常运作,如何保障这些基础服务的高可用性是我们每一位管理员需要考虑的。 一般的中小企业最少都会用两台或多台服务器做冗余保证企业内基础服务的高可用性,当一台服务器坏了或需要维护另一台服务器照样能够提供相同的服务来保障企业IT系统的正常运作。 下面是一张很经典的AD部署场景图,图里用了两台计算机做服务器,同时提供了AD/DNS/DHCP/WINS服务。对AD/DNS/DHCP/WINS服务不了解的朋友请先学习一下理论知识,要动手实验朋友请先把下面的图看懂了再动手,本帖子适合对AD入门的朋友,老鸟们就直接跳过吧^_^。

下面是两台服务器的配置过程 在配置前请先在两台计算机上安装好Windows 2003 操作系统,升级打好最新补订! 一、WinOSDC2服务器的配置过程 1、AD的配置 2、DNS的配置 3、DHCP的配置 4、WINS的配置 二、WinOSDC3服务器的配置过程 1、AD的配置 2、DNS的配置 3、DHCP的配置 4、WINS的配置 三、验证两台服务器是否能够提供冗余服务、 一、WinOSDC2服务器的配置过程——1、AD的配置 1、登录到WinOSDC2服务器,安装DNS/DHCP/WINS网络服务;

2、配置本机的网络IP,子网掩码,网关,DNS,WINS;

3、在“开始菜单”“运行”输入AD配置命令dcpromo ; 4、下一步

5、选择“新域的域控制器”“下一步” 6、选择“在新林中的域”“下一步”

JSP的四大作用域:page、request、session、application

JSP的四大作用域:page、request、session、application page作用域:代表变量只能在当前页面上生效 reques t:代表变量能在一次请求中生效,一次请求可能包含一个页面,也可能包含多个页面,比如页面A请求转发到页面B session:代表变量能在一次会话中生效,基本上就是能在web项目下都有效,session的使用也跟cookie有很大的关系。一般来说,只要浏览器不关闭,cookie 就会一直生效,cookie生效,session的使用就不会受到影响。 application:代表变量能一个应用下(多个会话),在服务器下的多个项目之间都能够使用。比如baidu、wenku等共享帐号。 Cookie在jsp中语法: Cookie cookie_name =new Cookie("Parameter","Value"); 例: Cookie username_Cookie =new Cookie("username","waynezheng"); response.addCookie(username_Cookie); 读取cookie 从提交的HTML表单中获取,用户名 String userName=request.getParameter("username"); 以"username", userName 值/对创建一个Cookie Cookie theUsername=new Cookie("username",userName); 在JSP中,使用setMaxAge(int expiry)方法来设置Cookie的存在时间,参数expiry 应是一个整数。正值表示cookie将在这么多秒以后失效。注意这个值是cookie 将要存在的最大时间,而不是cookie现在的存在时间。负值表示当浏览器关闭时,Cookie将会被删除。零值则是要删除该Cookie。如: Cookie deleteNewCookie=new Cookie("newcookie",null); deleteNewCookie.setMaxAge(0); 删除该Cookie deleteNewCookie.setPath("/"); response.addCookie(deleteNewCookie); 实例: <%

变量的生命周期与作用域

作用域和生存周期是完全不同的两个概念。作用域可以看作是变量的一个有效范围,就像网游中的攻击范围一样;生存周期可以看成是一个变量能存在多久,能在那些时段存在,就像网游中的魔法持续时间……简单的以一个局部变量来举个例子:在main函数中声明了变量a,那么a的作用域就是main函数内部,脱离了main函数,a就无法使用了,main函数之外的函数或者方法,都无法去使用a。那么a的生存周期是指a在那些时候存在,具体到这个例子,a什么时候存在,要取决于main函数,或者说,main函数只要被调用,且调用没有完成,那么a就将存在。除此以外的情况,a都将被释放。生存周期也可以理解为从声明到释放的之间的时间。变量具体可以分为全局变量、静态全局变量、静态局部变量和局部变量。按存储区域分:全局变量、静态全局变量和静态局部变量都存放在内存的全局数据区,局部变量存放在内存的栈区按作用域分:全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。 总的分为局部变量和全局变量:局部变量又可分为动态局部变量(没特殊声明的变量一般都为动态局部变量)和静态局部变量(用static关键字声明的变量如:static int a;);两者的区别在于:静态的局部变量生存期比动态的局部变量来的长,动态的局部变量的生存期为所定义的范围内,如在函数内定义的,函数结束,变量也跟着结束,变量的值不会保存下来。而静态变量的生存期为整个源程序(也可说是一个文件,不同环境不同称呼)。而两者的作用域是一样。只能在定义他的函数内起作用,离开了这个函数就不起作用了。全局变量:在函数之外定义的变量称为全局变量。全局变量可以为本文件中其他函所共用(作用域),它的有效范围(生存期)从定义变量开始到文件结束。如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即全局变量不起作用。下面来看一个例子:#include"stdio.h"int d=1; //声明一个全局变量int fun(int p) { static int d=5; //定义一个静态局部变量d初值为5 //第二次调用时没有执行此行d=d+p; //此时局部变量d的值为9,(第一次调用)//第二次调用是局部变量d 的值为13,因为上一次执行完后d的值为9,printf("%d",d); //第一次输出为9,//第二次输出13}void main(){ int a=3; d=d+a; //此时d的值为4;a变量的值为3,全局变量d的值为1。for(i=0;i<2;i++) fun(d); //此处的d值为4,传送给形参p,再一次调用时还是将4传给开参p printf("d=%d",d); //输出d的值为4.此处的d为全局变量。} 看以上内容时,你先把程序看一篇,然后把会值代进去远算,每一次看注释时在同一行中只要看到第二个”//“时结束.第2个“//”为第二次调用时看的。以上内容有一点乱,但是希望可以帮助到你...88有什么不明白可以再问!答案补充 看程序时注释行不要选先看。本程序一共调用fun函数两次,两次实参的值都为4.

C++中的作用域解析

C++中的作用域解析 名字空间域 名字空间主要用于解决名字冲突的问题,在名字空间出现之前,库的作者通常通过附加给库中的类型,全局变量和函数予特定的前缀来防止名字冲突的问题,例如dbus库的Error类型和Error初始化函数被命名为: DBusError dbus_init_error 有了名字空间后,我们就可以通过附加名字空间的名字来构成名字的限定名(Qualified Name)来解决名字冲突的问题。 当然更主要的是我们可以通过名字空间别名,使用声明(特定的名字)和使用指示(全部名字)来达成即能有效防止冲突,又能在已确定的上下文中更方便的访问名字的作用。 跟Java的包机制不同,名字空间是纯逻辑上的,它不具备对文件组织上任何的物理约束,一个名字空间可以跨越多个编译单元(常见的方式,一个库一个名字空间),但也可以一个编译单元包含多个名字空间(比较少见,通常是用来通过嵌套的子名字空间来防止一些函数重载上的意外发生)。(Java中的包,编译单元,类型域的包含关系更加明确,容易理解和使用,一个包必然包含一个或多个编译单元,一个编译单元也必然包括一个或多个类型,而且只能有一个是包可见的--公共类) 有的意见认为,名字空间引起的问题比它解决的要多,比如连接时名字解析的问题,特别是不同编译器编译出来的程序片段(静态库,导入库,Object文件)如何能够正确的连接。名字空间也使得重载的决议规则变的更复杂。所以像有些的库仍然坚持使用前缀的方式,比如QT。 名字空间出现后,以前的全局域就变成了名字空间的一个特例--全局名字空间。没有放置在某个名字空间的类型,具有编译单元外部链接的非成员函数和变量就缺省属于全局名字空间。 编译单元域 编译单元域是个比较特殊的域,它通常跟代码的物理组织方式有关。一个编译单元中非成员变量和函数的名字可以有外部链接,从而使得链接器可以用来解决跨编译单元的名

执行环境,作用域理解

Javascript学习---2、执行环境,作用域 作者:名刘天下来源:博客园发布时间:2010-12-10 17:03 阅读:155 次原文链接[收藏]在javascript的学习中,执行环境、作用域是2个非常非常重要和基本的概念,理解了这2个概念对于javsacript中很多脚本的运行结果就能明白其中的道理了,比如搞清作用域和执行环境对于闭包的理解至关重要。 一、执行环境(exection context,也有称之为执行上下文) 所有JavaScript 代码都是在一个执行环境中被执行的。执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域、生存期等方面的处理,它定义了变量或函数是否有权访问其他数据,决定各自行为。 在javascript中,可执行的JavaScript代码分三种类型: 1. Global Code,即全局的、不在任何函数里面的代码,例如:一个js文件、嵌入在HTML页面中的js代码等。 2. Eval Code,即使用eval()函数动态执行的JS代码。 3. Function Code,即用户自定义函数中的函数体JS代码。 不同类型的JavaScript代码具有不同的执行环境,这里我们不考虑evel code,对应于global code和function code存在2种执行环境:全局执行环境和函数执行环境。 在一个页面中,第一次载入JS代码时创建一个全局执行环境,全局执行环境是最外围的执行环境,在Web浏览器中,全局执行环境被认为是window对象。因此,所有的全局变量和函数都是作为window对象的属性和方法创建的。 当调用一个JavaScript 函数时,该函数就会进入与该函数相对应的执行环境。如果又调用了另外一个函数(或者递归地调用同一个函数),则又会创建一个新的执行环境,并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后,执行过程会返回原始执行环境。因而,运行中的JavaScript 代码就构成了一个执行环境栈。 function Fn1(){ function Fn2(){ alert(document.body.tagName);//BODY //other code... } Fn2(); } Fn1(); //code here

符号表简介

符号表简介 符号表的作用:连接声明与引用的桥梁,记住每个符号的相关信息,如作用域和绑定等,帮助编译的各个阶段正确有效地工作。 对符号表设计的基本要求:目标是合理存放信息和快速准确查找。 1.正确存储各类信息。 2.适应不同阶段的需求; 3.便于有效地进行查找、插入、删除和修改等操作; 4.空间可以动态扩充; 4.3.1 符号表条目 每个声明的名字在符号表中占据一栏,称为条目,用于存放名字的相关信息。 符号表中的内容:保留字、标识符、特殊符号(包括算符、分隔符等)等等。不同类别的符号存放在不同的子表中,如变量名表、过程名表、保留字表等。 存放方式:关键字+属性。 例:下述符号的关键字应是,名字+类型,称为组合关键字: int x; struct x { float y, z; }; 为C构造的符号表中,组合关键字至少应该包括三项:名字+作用域+类型。 当一个名字x在同一作用域中允许有多于一个的声明,则对x的引用时需要根据上下文确定x到底属于哪个对象。因此有些程序设计语言在语法上规定了不允许这样的声明,以简化编译时的处理。 4.3.2构成名字的字符串的存储 定长数据与变长数据,直接存放与间接存放。 名字(直接存储)名字(间接存储)属性 sort 101 proc, ... a 106 int, ... readarray 108 proc, ... 118 boolean, ... draw_a_red_line_for_o bject_a sort#a#readarray#draw_a_red_line_for_object_a # ↑100

间接存储的方法实际上解决了复杂信息的存储问题,将其推广到属性,则任何一个复杂的属性,均可以为其另辟空间(空间本身可以是复杂结构,如数组的内情向量等),而仅需要将指向此空间的指针放在此属性在符号表中的对应位置即可。 4.3.3 名字的作用域 程序设计语言的名字可以出现在不同的范围内,并且可以具有不同的意义。 两种划分范围的方式:并列的和嵌套的。 不同的语言采用不同的方式:如Pascal的过程定义可以是嵌套的,而C的过程定义是并列的,但是C允许程序块是嵌套的。 名字的作用域:名字在哪个范围内起作用。并列的两个范围内的名字作用域互不相干,但是分别在嵌套的两个范围内的名字,其作用域的问题就需要制定规则来限定,以使得任何一个名字在任何范围内涵义都是无二义的。 名字的作用域规则:规定一个名字在什么样的范围内应该表示什么意义。 <1> 静态作用域原则(static-scope rule):编译时就可以确定名字的作用域,也可以说,仅 从静态读程序就可确定名字的作用域。 <2> 最近嵌套原则(most closely nested):以程序块为例,也适用于过程。 ①程序块B中声明的作用域包括B; ②如果名字x不在B中声明,那么B中x的出现是在外围程序块B'的x声明的作用域中, 使得 (a) B'有x的声明,并且 (b) B'比其它任何含x声明的程序块更接近被嵌套的B。 ## 通俗地讲,名字的声明在离其最近的内层起作用,即在名字引用处从内向外看,它处在所遇到的第一个该名字声明的作用域。 4.3.4 线性表 为了正确反映名字的作用域,线性表应具有栈的性质,即符号的加入和删除,均在线性表的一端进行。 表4.2 线性表的符号表组织

js的函数,语句,作用域,运算符

javaScript: javaScript是基于对象和事件驱动并具有安全性能的脚本语言。 javaScript的实现平台是依赖于浏览器。 javaScript的官方名是ECMAScript ?历史: ?前身:网景公司(Netscape) 的Livescript 。 ?网景与Sun公司共同將之推为脚本语言的标准,改名為JavaScript。 ?现状: ?2005年,Ajax热潮为JavaScript社区注入新的血液。 ?未来: ?在未来很长一段时间内都是作为客户端处理的重要程序。 作用: 网页特效(鼠标在网页上的移动是表现出来的效果); 表单验证(注册时输入的用户信息符合要求) 减少用户的操作(在soso中输入一个相关文字就会弹出很多相关的查询信息) 增加安全性(必须在浏览器中运行) 减少编写和维护代码的工作量(使用函数) 响应事件 游戏(网络五子棋,象棋) 特点: 一种脚本语言(直接在浏览器中运行,无需编译) 基于对象(有封装,但是没有继承和多态所以不是面向对象语言) 简单易用性(学习过Java和c语言) 动态性(循环语句) 安全性(只在浏览器中运行) 跨越平台性(能用浏览器上网) 改善用户体检 与java的不同 ?Java代码必须编译才能执行,而JavaScript不需编译,只需由浏览器解释执行; ?Java和JavaScript虽然都可以在服务器与客户端执行,但Java多运行于服务器,而 JavaScript多用于客户端; ?JavaScript使用的是松散的数据类型,而Java使用的是严谨的数据类型。 开发工具: ?任何可以编写HTML 文档的软件都可以用来开发JavaScript。 ?建议用EditPlus、Dreamweaver等编辑工具

Javascript深层原理探讨

Javascript深层原理探讨 Eval执行环境 构建Eval执行环境时的可变对象(Variable Object)就是调用eval时当前执行上下文中的可变对象(Variable Object)。在全局执行环境中调用eval函数,它的可变对象(Variable Object)就是全局对象;在函数中调用eval,它的可变对象(Variable Object)就是函数的活动对象(Activation Object)。 eval调用中可以访问函数fn的参数、局部变量;在eval中定义的局部变量在函数fn中也可以访问,因为它们的Varible Object是同一个对象。 进入Eval Code执行时会创建一个新的Scope Chain,内容与当前执行上下文的Scope Chain完全一样。 函数执行环境 在创建执行环境的过程中,会按照定义的先后顺序完成一系列操作: 1.首先会创建一个'活动对象'(Activation Object)。活动对象是规范中规定的另外一种机制。之所以称之为对象,是因为它拥有可访问的 命名属性,但是它又不像正常对象那样具有原型(至少没有预定义的原型),而且不能通过JavaScript 代码直接引用活动对象。2.为函数调用创建执行环境的下一步是创建一个arguments 对象,这是一个类似数组的对象,它以整数索引的数组成员一一对应地保存 着调用函数时所传递的参数。这个对象也有length 和callee 属性。然后,会为活动对象创建一个名为“arguments”的属性,该属性引用前面创建的arguments对象。 3.接着,为执行环境分配作用域。作用域由对象列表(链)组成。 4.之后会发生由ECMA 262 中所谓'活动对象'完成的'变量实例化'(Variable Instatiation)的过程。此时会将函数的形式参数创建为可 变对象的命名属性,如果调用函数时传递的参数与形式参数一致,则将相应参数的值赋给这些命名属性(否则,会给命名属性赋unde fined 值)。对于定义的内部函数,会以其声明时所用名称为可变对象创建同名属性,而相应的内部函数则被创建为函数对象并指定给该属性。变量实例化的最后一步是将在函数内部声明的所有局部变量创建为可变对象的命名属性。注:在这个过程中,除了实际参数有值外和函数定义外,其它都被'预解析'为undefined值. 5.最后,要为使用this 关键字而赋值。(此时的this指向的是全局对象,即window) 关于作用域和作用域链 在访问变量时,就必须存在一个可见性的问题,这就是作用域(Scope)。更深入的说,当访问一个变量或调用一个函数时,JavaScript引擎将不同执行位置上的Variable Object按照规则构建一个链表,在访问一个变量时,先在链表的第一个Variable Object上查找,如果没有找到则继续在第二个Variable Object上查找,直到搜索结束。这也就形成了作用域链(Scope Chain)的概念。 首先Scope Chain是一个类似链表/堆栈的结构,里面每个元素基本都是Variable Object/Activation Object。Variable Object也叫做Activation Object(因为有一些差异存在,所以规范中重新取一个名字以示区别,Global Code/Eval Code中叫Variable Object,Func tion Code中就叫做Activation Object)。每次进入函数执行都会创建一个新的Activation Object对象,然后创建一个arguments对象

python参数作用域解析

Python参数作用域解析 1.核心机制 1.1.疑问:作用域有哪些? 全局作用域的范围仅限于单个文件。在python中格式没有一个基于单个的、无所不包的情景文件的全局作用域。 1.2.疑问:如何定义作用域? Def/class/lambda三种方式 1.3.疑问:作用域的基本法则?LEGB法则 L:本地作用域;E:上层结构中的本地作用域;G:全局作用域;B:内置作用域; 法则描述: 1.变量名引用分为四个作用域进行查找:L→E→G→B,第一个能够完成查找的就算成功; 2.默认状态下,变量名赋值会创建或者改变本地变量;

3.全局声明将赋值变量名映射到模块文件内部的作用域; 需要讲的就这么多^_^ 接下来,希望大家能自己慢慢去体会“引用”和“赋值”之间的区别,那将是对大脑的一种摧残。 2.扩展说明 以下内容中有很多问题跟python的内存管理机制和python语言自身的规则相关,目前还没有看到那么细的地步,所以会有不少解释不够清晰的,个人只能尽量保证正确吧,请各位抱着找茬的心态继续一起继续前行。 2.1.疑问:什么叫变量名引用?什么叫变量名赋值? 只能举例说明啦…… ?变量名赋值: a. a = 1 a = 2 全局域申明一个变量a=1后,函数内部再去赋值的时,会重新创建一个新的本地局部变量a=2。 b. b = {} c. c = [] d.t = (1, 2, 3) e.…… ?2)变量名引用: a. a = 1 b = a #b为赋值,a为引用,产生的结果是b与a一样都指向对数字1的引用, 此时b和a的id应该是一样的 b. b = {} b[‘name’] = ‘chenweiguo’

(十二)变量的作用域和存储类型

一、作用域和生存期 C程序的标识符作用域有三种:局部、全局、文件。标识符的作用域决定了程序中的哪些语句可以使用它,换句话说,就是标识符在程序其他部分的可见性。通常,标识符的作用域都是通过它在程序中的位置隐式说明的。 1.局部作用域 前面各个例子中的变量都是局部作用域,他们都是声明在函数内部,无法被其他函数的代码所访问。函数的形式参数的作用域也是局部的,它们的作用范围仅限于函数内部所用的语句块。 void add(int); main() { int num=5; add(num); printf(%d\n,num); /*输出5*/ } void add(int num) { num++; printf(%d\n,num); /*输出6*/ } 上面例子里的两个num变量都是局部变量,只在本身函数里可见。前面我们说了,在两个函数出现同名的变量不会互相干扰,就是这个道理。所以上面的两个输出,在主函数里仍然是5,在add()函数里输出是6。 2.全局作用域 对于具有全局作用域的变量,我们可以在程序的任何位置访问它们。当一个变量是在所有函数的外部声明,也就是在程序的开头声明,那么这个变量就是全局变量。 void add(int); int num; main() { int n=5; add(n); printf(%d\n,num); /*输出6*/ } void add(num) /*形式参数没有指定类型*/

num++; printf(%d\n,num); /*输出6*/ } 上面的main()和add()里面,并没有声明num,但是在最后输出的时候却要求输出num,这是由于在程序的开始声明了num是全局变量,也就是在所有函数里都可以使用这个变量。这时候一个函数里改变了变量的值,其他函数里的值也会出现影响。上面的例子输出都是6,因为在add()函数里改变了num的值,由于num是全局变量,就好象它们两个函数共用一个变量,所以在main()函数里的num也随之改变了。 3.文件作用域 在很多C语言书上,都没有说明文件作用域,或者只是略微的提到,其实文件作用域在较大程序中很有作用(在多文件系统中)。文件作用域是指外部标识符仅在声明它的同一个转换单元内的函数汇总可见。所谓转换单元是指定义这些变量和函数的源代码文件(包括任何通过#include指令包含的源代码文件)。static存储类型修饰符指定了变量具有文件作用域。 static int num; static void add(int); main() { scanf(%d,&num); add(num) printf(%d\n,num); } void add(num) { num++; } 上面的程序中变量num和函数add()在声明是采用了static存储类型修饰符,这使得它们具有文件作用域,仅爱定义它们的文件内可见。 由于我们提到的大多数程序都只有一个编译文件组成,所以这种写法没有实际意义。但是实际工程上的文件有很多,它们不是由一个人写成的,由很多人共同完成,这些文件都是各自编译的,这难免使得某些人使用了一样的全局变量名,那么为了以后程序中各自的变量和函数不互相干扰,就可以使用static修饰符,这样在连接到同一个程序的其他代码文件而言就是不可见的。 二、变量存储类型 前面我们说了,声明变量时用如下类似的形式: int num; float total;

函数的重载和变量的作用域

C++语言实验报告实验名称:函数的重载和变量的作用域实验日期:2011-5-6 实验预习报告日期:2011-5-6 实验目的1、了解内联函数、重载函数、带默认参数函数的定义及使用方法。2、掌握作用域的概念、变量的存储类型及它们之间的差别。3、掌握程序的多文件组织。二、实验内容预习及准备(1)分析和设计(编程思路,关键公式、步骤或算法)实验一、重载函数允许不同的函数使用相同的名字,这使得完成类似的任务时可以使用相同的函数名。范例:编写几个计算面积的函数,分别计算圆、矩形、梯形和三角形的面积,计算边长为1的正方形及其内切圆、内接等腰三角形和等腰梯形面积。实验源码#include #include using namespace std; const double PI=3.14159; double area(double radius=0); double area(double a,double b); double area(double a,double b,double h); double area(double a,double b,double c,int); int main(){

cout<<"Area of point is:"<

javascript闭包高级教程

理解 JavaScript 闭包 要成为高级 JavaScript 程序员,就必须理解闭包。 本文结合 ECMA 262 规范详解了闭包的内部工作机制,让 JavaScript 编程人员对闭包的理解从“嵌套的函数”深入到“标识符解析、执行环境和作用域链”等等 JavaScript 对象背后的运行机制当中,真正领会到闭包的实质。 目录 ?简介 ?对象属性名解析 o值的赋予 o值的读取 ?标识符解析、执行环境和作用域链 o执行环境 o作用域链与 [[scope]] o标识符解析 ?闭包 o自动垃圾收集 o构成闭包 ?通过闭包可以做什么? o例 1:为函数引用设置延时 o例 2:通过对象实例方法关联函数 o例 3:包装相关的功能 o其他例子 ?意外的闭包 ?Internet Explorer 的内存泄漏问题 简介 返回目录 Closure 所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境 的表达式(通常是一个函数),因而这些变量也是该表达式的一部 分。 闭包是 ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下。如果想要

扬长避短地使用闭包这一特性,则必须了解它们的工作机制。而闭包工作机制的实现很大程度上有赖于标识符(或者说对象属性)解析过程中作用域的角色。 关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。 遗憾的是,要适当地理解闭包就必须理解闭包背后运行的机制,以及许多相关的技术细节。虽然本文的前半部分并没有涉及 ECMA 262 规范指定的某些算法,但仍然有许多无法回避或简化的内容。对于个别熟悉对象属性名解析的人来说,可以跳过相关的内容,但是除非你对闭包也非常熟悉,否则最好是不要跳下面几节。 对象属性名解析 返回目录 ECMAScript 认可两类对象:原生(Native)对象和宿主(Host)对象,其中宿主对象包含一个被称为内置对象的原生对象的子类(ECMA 262 3rd Ed Section 4.3)。原生对象属于语言,而宿主对象由环境提供,比如说可能是文档对象、DOM 等类似的对象。 原生对象具有松散和动态的命名属性(对于某些实现的内置对象子类别而言,动态性是受限的--但这不是太大的问题)。对象的命名属性用于保存值,该值可以是指向另一个对象(Objects)的引用(在这个意义上说,函数也是对象),也可以是一些基本的数据类型,比如:String、Number、Boolean、Null 或Undefined。其中比较特殊的是 Undefined 类型,因为可以给对象的属性指定一个 Undefined 类型的值,而不会删除对象的相应属性。而且,该属性只是保存 着undefined 值。 下面简要介绍一下如何设置和读取对象的属性值,并最大程度地体现相应的内部细节。 值的赋予 返回目录 对象的命名属性可以通过为该命名属性赋值来创建,或重新赋值。即,对于:

相关文档