程序设计语言是指用来编译、解释、处理各种程序时所使用的机器语言,它包括汇编语言、解释程序、编译程序及高级语言等,如Visual Basic(简称VB)、Visual C++(简称VC)、Delphi等。

内容提要

  • 编译与解释
  • 文法
  • 有限自动机和正规式
  • 表达式
  • 传值与传址
  • 多种程序语言的特点

一、编译与解释

在编译与解释方面,很多编程工具书都有作详细解释。以下是我个人的拙见:

机器语言与人类语言

人类作为高级动物,最显著的特点就是有语言,例如中文,英语,法语等种类繁多,且沟通直观。相较于人类语言,机器语言就显得简单,计算机能读懂的数据只有0和1,而人类要与计算机交流,用人类语言肯定不行的,因为计算机太笨了,听不懂,所以只能用由0和1组成的代码编码,即早期的汇编语言,是一种低级语言。

人不再迁就机器

以前听说过这么一个笑话:“人类之所以科技能一直进步,是因为人太懒了。” 开始我很是不解,难道不是科学家们的努力钻研、刻苦实验,才换来科技的进步吗? 后来我有点了解了,举个不恰当的例子:就拿电风扇来说吧,大热天的还得自己扇风,多累啊,要是有个机器在那自动给我吹风该多好。为了有个自动扇风的机器,发明家改造了电机,在电机的基础上发明了电扇。我们有自己的语言,为什么要用难懂又难记的汇编指令呢?因此人不再迁就计算机,而是从人类语言的逻辑思维,发明了和计算机交流的高级语言,如C语言,C++,JAVA等。

编译器与解释器

两个不同母语的人交流需要翻译,人与计算机也一样。一个掌握高级语言的人通过代码与计算机交流,向计算机发送指令,也需要翻译。不同的高级语言翻译的方式不一样,例如Java使用编译器,而Python使用解释器。

  • 解释器:对每一行代码实时解释并执行
  • 编译器:将所有代码编译完成后,由编译好的目的代码执行

16

二、文法

文法的定义

一个形式文法是一个有序四元组G=(V, T, S, P),其中:

  • V:非终结符,它不是语言组成部分,也不是最终结果,可理解为占位符。
  • T:终结符,它是语言的组成部分 V∩T=∅
  • S:起始符,它是语言的开始符号
  • P:产生式,用终结符代替非终结符的规则。如α → β

4

语法推导树

一棵语法树应具备以下特征:

  • 每个结点都有一个标记,此标记是V的一个符号
  • 根的标记是S
  • 若一个结点n至少有一个它自己除外的子孙,并且有标记A,则A肯定在Vn中
  • 如果结点n的直接子孙,从左到右依次是n1、n2、…nk 其标记为A1、A2、…Ak;那么A → A1、A2、…Ak 一定是P中的一个产生式。

例题:

20

三、有限自动机和正规式

有限自动机

M = (S, ∑, δ, S0, Z)

  • S 是一个有限集,每个元素为一个状态
  • ∑ 是一个有穷字母表,每个元素为一个输入字符
  • δ 是转换函数,是一个单值对照
  • S0 属于S,是其唯一的初态
  • Z 是一个终态极(可空)

有限状态自动机可以形象地用状态转换图表示,如设有限自动机DFA = ({S,A,B,C,f},{1,0},δ,S,{f}),其中:δ(S,0)=B, δ(S,1)=A, δ(A,0)=f, δ(A,1)=C, δ(B,0)=C, δ(B,1)=f, δ(C,0)=f, δ(C,1)=f

17

例题:

8

正规式

正规式是一种表示正规集的工具,正规式是描述程序语言单词的表达式,对于字母表∑,其上的正规式及其表示的正规集可以递归定义如下。

  1. ε是一个正规式,它表示集合L(ε)={ε}。
  2. 若a是∑上的字符,则a是一个正规式,它所表示的正规集L(a)={a}。
  3. 若正规式r和s分别表示正规集L(r)、L(s),则
    • r|s是正规式,表示集合L(r)∪L(s);
    • r·s是正规式,表示集合L(r)L(s);
    • r是正规式,表示集合(L(r))
    • (r)是正规式,表示集合L(r)。

仅由有限次地使用上述三个步骤定义的表达式才是∑上的正规式。

运算符“|”、“·”、“*” 分别称为“或”、“连接”和“闭包”。

在正规式的书写中,连接运算符“·”可省略。

运算符的优先级从高到低顺序排列为:“*”、“·”、“|”。

运算符“|”表示“或”、并集。

“*”表示*之前括号里的内容出现0次或多次。

若两个正规式表示的正规集相同,则认为二者等价。两个等价的正规集U和V记作U=V。

— 以上均摘抄自百度百科

例如(a丨b)* 当*为3时,该式子可以是 aaa、aab、abb、bbb、bba、baa;

18

四、表达式

19

五、传值与传址

  • 传值:传值,实际是把实参的值赋值给行参,相当于copy。那么对行参的修改,不会影响实参的值。
  • 传址: 实际是传值的一种特殊方式,只是他传递的是地址,不是普通的赋值,那么传地址以后,实参和行参都指向同一个对象,因此对形参的修改会影响到实参。

通过代码比较区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>

void swap(int n1,int n2)
{
int temp;
temp=n1;
n1=n2;
n2=temp;
}

int main()
{
int a=5;
int b=15;
printf("交换前a,b的值分别为:\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
swap(a,b);
printf("交换后a,b的值分别为:\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
}

运行结果:

交换前a,b的值分别为:
a=5
b=15
交换后a,b的值分别为:
a=5
b=15

因为该代码只是把a,b的值传给了n1,n2;n1,n2在函数的作用下实现值的互换,但变量a,b指向值的地址已然没有改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>

void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}

int main()
{
int a=5;
int b=15;
printf("交换前a,b的值分别为:\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
swap(&a,&b);
printf("交换后a,b的值分别为:\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
}

运行结果:

交换前a,b的值分别为:
a=5
b=15
交换后a,b的值分别为:
a=15
b=5

这次a,b的值实现了互换,因为传入swap函数的参数是变量a,b指向值的地址,经过互换,指向值的地址发生改变,即a,b的指向的值也发生改变。

六、多种程序语言的特点

计算机编程发展到了今天,已经有很多种高级语言,以下简单说几个,有兴趣的朋友可以自行百度了解。

  • Fortran语言:用于科学计算,执行效率高
  • Pascal语言:为教学而开放的,表达能力强,后期演化出Delphi
  • C语言:面向过程,高效
  • Lisp语言:函数式程序语言,多用于符号处理,人工智能
  • C++语言:面向对象,跨平台
  • Java语言:面向对象,跨平台
  • Prolog语言:逻辑推理,简洁,表达能力强,多用于数据库或专家系