程序設計語言基礎

程序設計語言基礎

一.靜態和動態

靜態

編譯階段決定怎樣解決一個問題,稱爲靜態策略。

例如: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

四.參數傳遞機制

值調用

實參如果是一個表達式,則將計算結果傳遞給形參。
形參如果是一個變量,則將變量的值拷貝一份給形參。

引用調用

實參將地址傳遞給形參。結果:實參和形參都指向同一塊內存。

名調用(已經不再使用,所以就不介紹了)

五.別名

如果兩個變量指向同一個內存單元,那麼,這兩個變量地名字都是對方的別名。

編譯器想要優化程序,就要理解別名現象以及產生這一現象地機制。例如,如果有一個變量只進行了一次賦值,並且沒有別名,那麼,就可以使用第一次賦值的常量來代替這個變量。

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