程序设计语言基础

程序设计语言基础

一.静态和动态

静态

编译阶段决定怎样解决一个问题,称为静态策略。

例如:Java和C++中,通过static来修饰一个字段,那么这个字段被称为静态成员或类成员。像这样的静态成员,它的存储位置在编译期间就已经决定了,这里采用的就是静态策略。

动态

程序运行阶段决定怎样解决一个问题,称为动态策略。

例如:Java中方法的动态绑定和C++中的虚函数。

二.环境和状态

环境

如上图,环境就是一个名字到一个存储位置(左值)的映射。

名字映射存储位置(也就是环境)时遵守语言的作用域规则。例如,下面的C代码:

#include <stdio.h>

int a = 1;
void func(){
    int a = 2;
    printf("%d", a);
}
int main(void){
    func();
    printf("%d", a);
    return 0;
}

因为C语言中,func函数中有一个局部的a,所以在func函数中,从a到存储位置的映射,映射到了局部的a。

main函数中的输出语句,使用的a映射到了全局的a。

名字到位置的映射,一般是动态的。因为在运行阶段一个名字可能映射到不同的位置,所以说名字到位置的绑定(映射)是动态的

状态

状态是一个位置(左值)到这个位置存储的内容(右值)的映射。

位置到值得映射,也是动态的。在程序运行前,无法确定一个位置中得内容

三.作用域

静态作用域和块结构

C语言得静态作用与描述如下:

  1. 一个C程序由一个顶层的变量(全局变量)声明和函数声明的序列组成。
  2. 函数内部可以声明变量,包括局部变量和参数。每个这样的声明的作用域被限制在他们所出现的那个函数内。
  3. 名字x的一个顶层声明的作用域包括气候的所有程序(全局变量在全局可以访问)。但是,如果一个函数中也有一个x的声明,那么函数中的那些语句就不在这个顶层生命的作用域内(也就是说,如果一个函数中声明了一个与全局变量名字相同的局部变量,那么,在函数中对这个名字的操作,操作的对象是局部的变量)。
  4. 如果名字x的声明D属于块B,那么D的作用域包括整个B,但是以任意深度嵌套在B中、重新声明了x的所有块B'不在此作用域中。这里x在B'中重新声明是指存在另一个属于B'的对相同名字x的声明B'。

第四句的书面化描述有一点晦涩,画个图理解下

对于最外层的块B,其中有一个声明D,声明了一个变量x,那么,变量x的作用域是整个B块(包括内部嵌套的块)。但是,如果嵌套在B中的块B'有一个相同名字的声明D',那么D的作用与就为B-B'(集合差集的概念)。  

注意:这里说的是使用变量的名字x访问这个变量的情况,并不是在块B'中不可以访问到B中声明的x。对于C++来说,声明在全局的变量,会有一个全局的域,可以通过域解析符显式的使用全局的同名变量。

通俗描述:就近原则,一个名字映射一个变量时,首先在自己的块找,如果没找到,就向上一层去找,如果没找到,继续向上找,直到找到这个名字或找到全局的位置,如果全局仍然没有找到,则会报错。

动态作用域

动态作用域的策略:对一个名字x的使用,指向的是最近被调用的,但还没有终止的,并且重新声明了x的这个过程中的声明。

举个例子:

int x = 2;

void c(){
    printf("%d\n", x);
}

void b(){
    int x = 1;
    printf("%d\n", x);
    c();
}

int main(){
    b();
    return 0;
}

在动态作用域的策略下(注意,C采用静态作用域的策略,这里只是假设,千万不要搞混),这里会输出两个1。

解释:

请看上面对动态作用域的描述,首先。

第一句:对一个名字x的使用。也就是我们例子中的x。
第二句:最近被调用的,但还没有终止。现在仍然活动的函数有3三个,调用顺序是main->b->c。
第三句:并且重新声明了x的这个过程中的声明。对于函数b来说,输出1是毫无疑问的,之后,b又调用了c,在这个时候,b就是那个最近被调用,但仍然没有结束,并且重新定义了x的过程(函数),所以函数c中的x,指向的是函数b中的声明。

当然,C语言是采用了静态作用域的策略,如果运行,这里的结果应该是1和2

四.参数传递机制

值调用

实参如果是一个表达式,则将计算结果传递给形参。
形参如果是一个变量,则将变量的值拷贝一份给形参。

引用调用

实参将地址传递给形参。结果:实参和形参都指向同一块内存。

名调用(已经不再使用,所以就不介绍了)

五.别名

如果两个变量指向同一个内存单元,那么,这两个变量地名字都是对方的别名。

编译器想要优化程序,就要理解别名现象以及产生这一现象地机制。例如,如果有一个变量只进行了一次赋值,并且没有别名,那么,就可以使用第一次赋值的常量来代替这个变量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章