第一章 程式語言導論

1-1程式語言基本概念

一、定義

程式 = 演算法+資料結構

是人類與電腦溝通的工具,能描述問題的演算法及其資料結構的概念。每種程式語言都有其特定的撰寫規則 (語法),只要依其規則撰寫,即可命令電腦完成某些特定的工作。

 

Turing Machine

[杜林機(Turing machine)] 2 | 94, 104

96交員晉高、104地三

使用一個無限長的磁帶當作記憶體磁帶頭有讀與寫的功能,而且可以在磁帶上左右移動Turing Machine工作的情況就好像無法記得那麼長的資料,但是可以前後瀏覽作記號並且比對

※參考資料:http://nthucad.cs.nthu.edu.tw/~yyliu/personal/nou/05ct/chp08.pdf

 

二、程式語言的分類

[程式語言分類] 3 | 93,103,104

93專檢、103檢三、104高三

()第一代程式語言-機器語言(machine language)

01組成的二進位碼所構成,不同類型的計算機擁有不同的指令群,對應的二進位碼亦不相同,因此是一種與機器相關的語言撰寫及維護都極為困難。例如麥金塔電腦與 IBM 個人電腦的機器語言不相容。

()第二代程式語言-組合語言(assembly language)

又稱為低階語言 (low-level language)。將每一條機器語言指令用一個助記憶符號 (memonic symbol) 來取代。組合語言指令與機器語言指令具有一對一的對應關係,因此屬於與機器相關的語言

()第三代程式語言-高階語言(high-level language):如何做(how) / 師傅

又稱為程序導向語言 (procedure oriented language)告訴電腦如何做。與機器無關,具有移植性,不須要因為電腦設備的不同而修改大量程式指令。例如 PascalCC++BasicFortran Cobol

()第四代程式語言-超高階語言(very high level language):做什麼(what) / 老闆

通常稱為 4GL (fourth generation language)。是問題導向語言 (problem oriented language) 或非程序導向語言 (non-procedure language)告訴電腦做什麼。例如 SQL (Structured Query Language)

()第五代程式語言-自然語言(nature language)

利用人工智慧技術,使其接近人類使用的自然語言 (如英語),讓電腦讀懂人類的語言。目前人工智慧語言仍處於發展中的階段,現今開發的產品則多是以 Lisp Prolog 語言為基礎,專為特定領域設計的知識庫系統 (如醫療、財經)

※參考資料:

http://zh.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86

 

三、為何要學習程式語言

增進對所使用程式語言的了解、可以改進程式的架構、有助於選擇合適的程式語言、比較容易學習新的程式語言、較容易設計出一種新的程式語言。

 

四、電腦的應用領域及相關的程式語言

()科學應用:Fortran

()商業應用:COBOL

()人工智慧:LISPProlog

()系統程式:發展 UNIX 所用的 C 語言。

()超高階語言

UNIX 上面的各種腳本語言 (scripting languages),例如 shellkshawkperl

()特殊目的語言(問題導向語言)

例如用於產生商業報表的 RPG (Report Program Generator)

※參考資料:http://en.wikibooks.org/wiki/Fortran/Fortran_examples

 

93年專門職業及技術人員檢覈程式語言

四、我們通常將程式語言分為五代。

()請問第一代程式語言所指為何?(5分)

()第二代程式語言一般指的是「高階語言」,又稱為「程序導向語言」,請說明程序導向語言解決問題的方式為何?(5分)

()第四代程式語言一般指的是「問題導向語言」(problem oriented language),例如 SQL,請說明 SQL 解決問題的方式為何?(5分)

()第五代程式語言一般指的是「自然語言」(nature language),又稱為「知識庫語言」,請說明此類語言解決問題的方式為何?(5分)

答:

 

103年檢察事務官三等程式語言

一、何謂程式語言 (programming language)?又有那些分類?(17分)

答:

 

104年高考三級程式語言

一、請就解譯方式 (組譯、直譯、編譯)、程式結構 (程序導向、物件導向)、標記文字 (是、否) 等特性,分類說明程式語言 C, CSS, C#, HTML, Java, PHP, Python, SQL 的特性。請繪製表格作答。(25分)

答:

 

解譯方式

程式結構

標記文字

C

編譯

程序導向

CSS

直譯

非程序導向 (宣告方式)

(樣式可以嵌入於 HTML 文件中)

C#

編譯

物件導向

HTML

直譯

非程序導向 (超文件標記語言)

Java

編譯 (編譯後再直譯)

物件導向

PHP

直譯

物件導向

(程式碼必須在<?php ?> 標籤中)

Python

直譯

物件導向

SQL

直譯

非程序導向 (查詢語言)

 

1-2 高階程式語言

一、高階語言的優點

()學習容易,學習時間較短

()生產力較高,對於人力及管理的需求較少

()與機器無關

()程式的除錯較容易

()編寫較大的應用程式時,不至因瑣碎的程式細節而影響設計的進行

()高階語言的結構本身就具有卓越的文件說明能力

 

二、高階語言的實作

[編譯(compilation)] 15 | 82,86,91,94(2),95(3),96,97(2),98(2),99,104

82地三、86高三、91地三、94高三(2)95身三、95港員晉高、95地三、96地三、97高三、97地三、98關薦、98檢三、99高三、104地三

()編譯程式(compilation):程式編譯器

1.定義:是一種系統程式,將高階語言的原始碼轉換成機器語言程式 (目的程式)

2.編譯的作法:

原始程式→編譯器 (高階語言轉成組合語言)→組譯器 (組合語言轉成機器語言)→目的程式。

3.編譯的流程:

undefined

※參考資料:

http://digital.cs.usu.edu/~cdyreson/teaching/languages/142/lectures/printintroduction.htm

 

※語彙分析(Lexical Analysis)

將敘述句拆成組成語法的基本單元,例如保留字、關鍵字、識別字、運算子等。

 

※語法分析(Syntax Analysis)

將程式符號轉換成階層式的語法樹 (Syntax Tree) 符號。在語法樹中,階層最高的節點 (Node) assign 的符號,其餘的節點為其他的運算元符號,而葉子 (Leaf) 就都是變數的標記 (Token)

 

※語意分析(Semantic Analysis)

undefined

1.定義:

藉由語法樹來分析程式的邏輯與語法是否符合規定。主要是為語法樹加註節點的資料型態,並檢查資料型態是否相容,然後輸出語意樹

2.範例:

語意分析器將會發現到 a b 是無法相乘的,因而輸出錯誤訊息。

C語言程式

語義分析的結果

int a = 5, c;

char b[10];

c = a*b;

a, c 是整數

b 是字元陣列

c (錯誤?) = a (整數) * b (字元陣列)

 

LR parser

104地三

是一種由下而上 (bottom-up) 上下文無關語法剖析器LR 意指由左至右處理輸入字串並以最右邊優先衍生 (Right derivation) 的推導順序建構語法樹。由於 LR 剖析器 (LR parser) 由剖析樹的葉節點開始,然後透過文法規則逐步向上層化簡,最後化簡到樹的根部 (起始符號),所以是一種由下而上的剖析方法。

※參考資料:

https://zh.wikipedia.org/wiki/LR%E5%89%96%E6%9E%90%E5%99%A8

 

※中間碼產生:語意樹→中間碼

1.使用時機:語意樹建立完成後,就可以將語意樹中的每個節點展開為中間碼。

2.方法:

利用遞迴的方式,從根節點開始遞迴展開每個子節點,直到所有節點的中間碼都產生完畢為止。

3.範例:

C語言程式

中間碼

說明

sum = 0;

for(i = 1; i <= 10; i++)

{

    sum = sum+i;

}

return sum;

=    0    sum

=    1    i

FOR0:

    CMP     i  10

    J    >     _FOR0

    +    sum i  T0

    =    T0    sum

    +    i   1  i

    J           FOR0

_FOR0:

    RET        sum

設定 sum 0

設定 i 1

for 迴圈的起始點

    i  >=<  10  ?

    if (i>10) goto FOR1

    T0 = sum+i

    sum = T0

    i = i+1

 

 

傳回 sum

 

指定述句的翻譯:

undefined

<3>pic3

※參考資料:趙建華-編譯系統設計.pdf

 

※程式編譯器:

先用編譯再組譯。

 

※編譯(Compiler)

將高階語言轉成組合語言。

 

※組譯(Assembling)

將組合語言轉成機器語言。

 

※編譯器的步驟:

步驟

內容

1.詞彙分析(Lexical Analysis)

將整個程式分成一個一個的基本詞彙 (token)

2.語法分析(ParsingSyntax Analysis)

剖析器利用語法規則進行比對,建立語法剖析樹

3.語意分析(Semantic Analysis)

為剖析樹加註節點型態,並檢查型態相容性,輸出語意樹

4.中間碼產生(Pcode Generator)

將語意樹轉換成中間碼

5.最佳化(Optimization)

考慮暫存器配置問題,降低指令數量,增加效率

6.組合語言產生(Assembly Code Generator)

將中間碼轉換為組合語言輸出

7.編譯組譯(Compilation Assembly)

將中間碼碼產生的組合語言轉換成機器語言及載入程式所需的資訊

※參考資料:

http://www2.nuu.edu.tw/~elearning/nuuopencourse/93open/93004/html/contents.htm

 

※程式編譯器的過程:

undefined

Dev-C++ 主要工作為預先處理 (Preprocess)、編譯 (Compile) 和組譯(Assemble)。預先處理是做一些在編譯前要做的工作,之後就進行編譯。在編譯過程中,會檢查程式有沒有錯誤,而錯誤主要有語法錯誤 (Syntax Error) 語義錯誤 (Semantic Error) 兩類。如果有上述錯誤,編譯器會通知,而且停止編譯過程,這時候要修正程式內的錯誤,修改後重新開始編譯。當沒有任何錯誤後,編譯器會把程式內每個句子轉成更低階的方式,一般是轉成組合語言 (Assembly)。轉成組合語言後,組譯 (通常編譯器都內置了組譯器) 就會把每個組合語言句子轉成機械語言 (Machine Code)也稱為目的碼 (Object Code),產生另一個檔案 “file.obj”。最後到了連結 (Link) 過程,就會把程式、有關的程式和程式庫所產生出來的 *.lib轉成可以在電腦上執行的方式,產生另一個檔 “file.exe”,這個檔案就可以執行了。

※參考資料:http://www2.lssh.tp.edu.tw/~hlf/class-1/lang-c/compile.htm

 

※預先處理(Preprocess)

1.#define巨集的宣告與使用:

巨集指令 #define 宣告的格式如下

#define macroname string

假設有一 C 程式檔 file.c 其內容為:

  #define MAXSIZE 100

  main( ) {

      int A[MAXSIZE];

}

於編譯時經過前置處理後,該程式變成

  main( ) {

int A[100];

}

其中所有的 #define 指令都不見了,MAXSIZE 也都變成了100

2.#include的使用:

C 程式的設計,不僅可以用模組化的方式,以函數來表現,亦可將程式碼依其不同的目的與功能,呈現在不同的檔案中。為了程式碼的一致性,例如常數、巨集指令全域 (global) 變數宣告一些函數 (僅列出函數的標題 heading) 等,都放在一檔頭檔 .h,當然不見的是要以 .h 當作副檔名,不過,一般都是以 .h 來當作 include 檔的副檔名,再以指令 #include 方式將該檔 加入即可。指令 #include 的宣告方式如下:

#include <filename>

#include "filename"

經過編譯器前置處理後,含指令 #include 這行則由該檔 filename 來代替,如果 filename 是由 < > 所含,則編譯器會到 include 目錄下去找該檔或至預設的目錄去找。" " 常用來引用自定義的頭文件。

假設檔案 file1.h 的內容如下:

#define MAXSIZE 100

  extern int size;

  int f(int x);

假設檔案 file2.c 的內容如下:

#include "file1.h"

main( ) {

int A[MAXSIZE], i, sum;

for(i = 0; i < size; i++)

          sum = sum+f(i);

}

假設 file1.h file2.c 都在同一目錄經過前置處理file2.c 就先變成

  #define MAXSIZE 100

  extern int size;

  int f(int x);

  main( ) {

int A[MAXSIZE], i, sum;

      for(i = 0; i < size; i++)

          sum = sum+f(i);

}

經過前置處理完成後file2.c 就變成

extern int size;

int f(int x);

main( ) {

int A[100], i, sum;

for(i = 0;i < size; i++)

sum = sum+f(x);

}

3.#if#ifdef等的使用:

如果在一檔案欲 include 一檔頭檔 file1.h,又想避免在同一檔案宣告兩次相同的東西,例如:

檔案 file1.h extern int size

檔案 file2.h #include "file1.h"

檔案 file3.h #include "file1.h"

檔案 file.c #include "file2.h" #include "file3.h"

則在檔案 file.c 內,變數 size 重複宣告了兩次而產生錯誤。

欲避免這種情況發生,每個 #include "file1.h" 指令,可以改變為如下指令:

  #if !define(FILE1) // 如果沒有定義一個 file1.h 標頭檔,就執行底下所有操作

  #define FILE1 "file1.h" // 定義一個符號

  #include FILE1// 在程序中包含頭文件

  #endif // 結束

或是

  #ifndef FILE1

  #define FILE1 "file1.h"

  #include FILE1

  #endif

如果一個辨識名稱 X 沒有被 define 過,則 define(X) 的值為0,或者 ifndef X 為真值。當 file2.h file3.h 都含上述指令,如此一來 file1.h 僅能一次被加入 file.c 而不致於產生衝突。

參考資料http://nknucc.nknu.edu.tw/~jwu/c/cpgch8.htm#third

 

C語言前置處理器:

1.定義:

是一種特殊的文字編輯器,語法和 C 語言完全不同,能處理常數、巨集及 include 檔。可以條件式編譯,例如要在測試時將除錯用的程式碼放進來,然後在正式發行時予以刪除。如下:

#include < stdio.h >

#define value  99

void main(void) {

#if value < 100

printf("value < 100");

#else

printf("value >= 100");

#endif

}

2.原理:

undefined

(1)前置處理程式將原始檔中的 # 開頭的指令全部轉換為 C 指令。例如 #include <stdio.h>,將 stdio.h 內容展開。

(2)編譯程式將純 C 檔案轉為對應的機器語言 (目的檔案)

(3)連結程式將所用到的 C 函數由函式庫連結到目的檔案後形成執行檔。

(4)執行檔 .exe 才是真正可執行的檔案。

 

()直譯程式(interpretation)

1.定義:

是一種系統程式,按照高階語言所寫的原始程式執行時敘述的邏輯順序,逐一將指令轉換為機器語言並且執行它。直譯器不會一次把整個程式轉譯出來,只像一位「中間人」,每次執行程式時都要先轉成另一種語言再作執行,因此直譯器的程式運行速度比較緩慢每轉譯一行程式敘述就立刻執行,然後再轉譯下一行,再執行,如此不停地進行下去。可以使用語彙分析器 (lexical analyzer) 和語法分析器 (parser),然後轉譯產生出來的抽象語法樹 (abstract syntax tree)

2.直譯的作法:原始程式→直譯程式 (原始程式轉成機器語言)→執行結果。

undefined

※參考資料:

http://zh.wikipedia.org/wiki/%E7%9B%B4%E8%AD%AF%E5%99%A8

 

※編譯程式與直譯程式的差異:

 

編譯程式

直譯程式

原始程式的處理方式

產生目的程式 (機器語言) 卻不執行,可以透過連結過程產生執行檔

按照輸入程式執行時敘述的邏輯順序逐一地分析解碼並且執行

敘述的處理順序

照程式實體上敘述的輸入順序進行處理 (撰寫順序)

依照程式執行時敘述的邏輯順序進行處理

敘述的處理次數

程式中每個敘述都只處理一次

依照執行時敘述的邏輯順序進行處理,可能發生某些敘述被重複處理許多次 (迴圈),而某些敘述沒有被處理 (當錯誤發生時才執行的程式片斷可能不會被執行)

 

※編譯程式與直譯程式的優缺點:

 

優點

缺點

 

arrow
arrow
    文章標籤
    程式語言
    全站熱搜

    jacksaleok 發表在 痞客邦 留言(1) 人氣()