zhouqijie

程序设计语言基础



静态和动态

静态:如果一个语言使用的策略支持编译器静态决定某个问题,那么我们说这个语言使用了一个静态(static)策略,或者说这个问题在编译时刻(compile time)决定。
动态:如果一个只允许在运行程序的时候做出决定的策略被称为动态(dynamic)策略,或者说被认为需要在运行时刻(run time)做出决定。

作用域(scope):x的一个声明的作用域(scope)是指程序的一个区域,在其中对x的使用都指向这个声明。如果仅通过阅读就可以确定一个声明的作用域,那么这个语言使用静态作用域或者词法作用域,否则这个语言使用的是动态作用域。如果使用动态作用域,当程序运行时,同一个对x的使用就会指向x的几个声明的某一个。

大部分语言例如C和Java都使用静态作用域。



环境与状态

//     环境           状态    
//    /    ↘         /   ↘    
//名字 --->  内存位置  --->  值
//            (变量)

环境(environment)是一个从名字到存储位置的映射。因为变量就是指内存位置(C语言的”左值”)
状态(state)是一个从内存位置到它们值的映射。(C语言术语:状态把左值映射为它们的右值)

CRE:环境的映射可以是动态的(局部作用域和全局的同名变量),也可以是静态的(全局变量的永久存储位置)。
CRE:状态的映射可以是动态的(变量赋值操作),也可以是静态的(常量定义)。



静态作用域和块结构

包括C语言等语言使用静态作用域。C语言的作用域规则是基于程序结构的,一个声明的作用域在由该声明在程序中出现的位置隐含地决定。

稍后出现的C++、C#、JAVA等语言,也通过private、public、protected等关键字的使用提供了对作用域的明确控制。

块(block)是声明和语句的一个组合。C语言使用{}来界定一个块。另一些语言使用begin/end



显式访问控制

private、public、protected这些关键字通过限制访问来支持封装(encapsulation)

C++中,一个类的定义可能和它的方法的定义分离。作用域之内和之外的代码区域可能相互交替。



动态作用域

术语动态作用域通常是指以下策略:对一个名字x的使用指向的是最近被调用但还没有终止且声明了x的过程中的这个声明。

这种类型的动态作用域仅仅在一些特殊情况下才会出现。例如C预处理器中的宏扩展,以及OOP中的方法解析。

实例:

#define a (x+1)

int x = 2;
void b()
{
    int x = 1;
    printf("%d", a);
}
void c()
{
    printf("%d", a);
}
void main()
{
    b();
    c();
}
//b执行时打印宏a的值,因此首先用(x+1)替换掉a,所以对x的使用解析为函数b中的int x = 1,打印的值为2。  
//c在b之后被调用,然而唯一可以访问的x是全局变量的x,所以打印的值是3。  

实例:

class Person
{
public:
    virtual void Speak();
}
class Student:Person
{
public:
    virtual void Speak();
}
void main()
{
    Person* p = new Student();
    p->Speak();
}



参数传递机制

值调用的效果是,被调用过程所做的所有有关形式参数的计算都局限于这个过程,相应的实在参数本身不会被改变。

实在参数的地址作为相应的形参的值被传递给调用者。

被早期的程序设计语言Algol60使用,它要求被调用者的运行方式好像是用实在参数以字面方式替换了被调用者的代码中的形式参数一样。这么做就好像形式参数是一个代表了实在参数的宏。



(DONE)