了解伪代码

什么是伪代码?

伪代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java等)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。 介于自然语言与编程语言之间。以编程语言的书写形式指明算法职能。使用伪代码, 不用拘泥于具体实现。相比程序语言(例如Java, C++,C, Dephi 等等)它更类似自然语言。它是* [半角](半角,即一个字符指一个[字符]占用两个标准字符位置的状态。汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是[全角字符]占用一个标准字符的位置。)*式化、不标准的语言。可以将整个算法运行过程的结构用接近自然语言的形式(可以使用任何一种你熟悉的文字,关键是把程序的意思表达出来)描述出来。

人们在用不同的编程语言实现同一个算法时意识到,他们的实现(注意:这里是实现,不是功能)很不同。尤其是对于那些熟练于不同编程语言的程序员要理解一个(用其他编程语言编写的程序的)功能时可能很难,因为程序语言的形式限制了程序员对程序关键部分的理解。这样伪代码就应运而生了。

当考虑算法功能(而不是其语言实现)时,伪代码常常得到应用。计算机科学在教学中通常使用虚拟码,以使得所有的程序员都能理解。

综上,简单的说,让人便于理解的代码。不依赖于语言的,用来表示程序执行过程,而不一定能编译运行的代码。在数据结构讲算法的时候用的很多。

伪代码实例

伪代码只是像流程图一样用在程序设计的初期,帮助写出程序流程。简单的程序一般都不用写流程、写思路,但是复杂的代码,最好还是把流程写下来,总体上去考虑整个功能如何实现。写完以后不仅可以用来作为以后测试,维护的基础,还可用来与他人交流。但是,如果把全部的东西写下来必定可能会让费很多时间,那么这个时候可以采用伪代码方式。比如:

IF 九点以前 THEN
do 私人事务;
ELSE 9点到18点 THEN
工作;
ELSE
下班;
END IF
这样不但可以达到文档的效果,同时可以节约时间. 更重要的是,使结构比较清晰,表达方式更加直观.

赋值语句用符号←表示,x←exp表示将exp的值赋给x,其中x是一个变量,exp是一个与x同类型的变量或表达式(该表达式的结果与x同类型);多重赋值i←j←e是将表达式e的值赋给变量i和j,这种表示与j←e和i←e等价。

例如:

x←y
x←20(y+1)
x←y←30
以上语句用C分别表示为:
x = y;
x = 20
(y+1);
x = y = 30;

选择语句用if-then-else来表示,并且这种if-then-else可以嵌套,与Pascal中的if-then-else没有什么区别。
例如:

if (Condition1)
then [ Block 1 ]
else if (Condition2)
then [ Block 2 ]
else [ Block 3 ]

循环语句有三种:while循环、repeat-until循环和for循环,其语法均与Pascal类似,只是用缩进代替begin - end;
例如:

  1. x ← 0
  2. y ← 0
  3. z ← 0
  4. while x < N
  5. do x ← x + 1
  6. y ← x + y
  7. for t ← 0 to 10
  8. do z ← ( z + x * y ) / 100
  9. repeat
  10. y ← y + 1
  11. z ← z - y
  12. until z < 0
  13. z ← x * y
  14. y ← y / 2

上述语句用C或C++来描述是:

x = y = z = 0;
while( z < N )
{
x ++;
y += x;
for( t = 0; t < 10; t++ )
{
z = ( z + x * y ) / 100;
do {
y ++;
z -= y;
} while( z >= 0 );
}
z = x * y;
}
y /= 2;

伪代码语法规则11条:

  1. 算法中出现的数组、变量可以是以下类型:整数、实数、字符、位串或指针。通常这些类型可以从算法的上下文来看是清楚的,并不需要额外加以说明。

  2. 在算法中的某些指令或子任务可以用文字来叙述,例如,"设x是A中的最大项",这里A是一个数组;或者"将x插入L中",这里L是一个链表。这样做的目的是为了避免因那些与主要问题无关的细节使算法本身杂乱无章。

  3. 算术表达式可以使用通常的算术运算符(+,-,*,/,以及表示幂的^)。逻辑表达式可以使用关系运算符=,≠,<,>,≤和≥,以及逻辑运算符与(and),或(or),非(not)。

  4. 赋值语句是如下形式的语句:a<-b 。

这里a是变量、数组项,b是算术表达式、逻辑表达式或指针表达式。语句的含义是将b的值赋给a。

  1. 若a和b都是变量、数组项,那么记号a<->b 表示a和b的内容进行交换。

  2. goto语句具有形式

                                    goto label(goto标号)
    

它将导致转向具有指定标号的语句。

  1. 条件语句有以下两种形式:

                                        if c then s或者
    
                                           if c then s
    
                                              else s′
    

这里c是逻辑表达式,s和s′是单一的语句或者是被括在do和end之间的语句串。对于上述两种形式,假若c为真,则s被执行一次。假若c为假,则在第一种形式中,if语句的执行就完成了,而在第二种形式中,执行s′。在所有的情况下,控制就进行到了下一个语句,除非在s或s′中的goto语句使控制转向到其它地方。

  1. 有两种循环指令:while和for。

     while语句的形式是
    
                                          while c do  
    
                                                s
    
                                              end
    

这里c是逻辑表达式,而s是由一个或更多个语句组成的语句串。当c为真时,执行s。在每一次执行s之前,c都被检查一下;假若c为假,控制就进行到紧跟在while语句后面的语句。注意,当控制第一次达到while语句时,假若c为假,则s一次也不执行。

for语句的形式是

                                 for var init to limit by incr do

                                                   s

                                                 end

这里var是变量,init、limit和incr都是算术表达式,而s是由一个或多个语句组成的语句串。初始时,var被赋予init的值。假若incr≥0,则只要var≤limit,就执行s并且将incr加到var上。(假若incr<0,则只要var≥limit,就执行s并且将incr加到var上)。incr的符号不能由s来该改变。

  1. exit语句可以在通常的结束条件满足之前,被用来结束while循环或者for循环的执行。exit导致转向到紧接在包含exit的(最内层)while或者for循环后面的一个语句。

  2. return用来指出一个算法执行的终点;如果算法在最后一条指令之后结束,它通常是被省略的;它被用得最多的场合是检测到不合需要的条件时。return的后面可以紧接被括在引号的信息。

  3. 算法中的注释被括在之中。诸如read和output之类的各种输入或者输出也在需要时被用到。

在伪代码的使用中有以下一些约定:

1)书写上的“缩进”表示程序中的分程序(程序块)结构。用缩进取代传统的begin和end语句来表示程序的块结构,可以大大提高代码的清晰性。(在真正的程序设计语言里,一般不建议单独使用缩进来表示分程序结构,这是因为当代码跨页时,缩进的层次很难确定。)

2)while,for,repeat等循环结构和if,then,else条件结构与Pascal中相同。(多数分程序结构的语言中都有与此等价的语言构造,具体的语法与Pascal中的可能有所不同。)然而,对for循环来说有一点不同,在Pascal中,循环计数器变量在退出循环时是未定义的,但在伪代码中,在退出循环后,循环计数器的值仍然保持。于是,紧接着一个for循环之后,循环计时器的值就是第一个超过for循环终值的那个数字。

3)符合“▷”表示后面的部分是个注释。

4)多重赋值 i←j←e是将表达式e的值赋给变量i和j;等价于赋值j←e,再进行赋值i←j。

5)变量(如i,t和key等)是局部于给定过程的。在没有显示说明的情况下,我们不使用全局变量。

6)数组元素是通过“数组名[下标]”这样的形式来访问的。例如,A[i]表示数组A的第i个元素。符合“..”用来表示数组中的一个取值范围,例如,A[1..j]就表示A的一个子数组,它包含了j个元素:A[1],A[2],…,A[j]。

7)复合数据一般组织成对象,它们是由属性(attribute)或域(field)所组成的。域的访问是由域名后跟由方括号括住的对象名形式来表示。例如,数组可以被看作是一个对象,其属性有length,表示数组中元素的个数,如length[A]就表示数组A中的元素个数。在表示数组元素和对象属性时,都要用的方括号,一般来说,通过上下文就可以看出其含义。

用于表示一个数组或对象的变量被看作是指向表示数组或对象的数据的一个指针。对于某个对象x的所有域f,赋值y←x就使得f[y] = f[x]。更进一步,如果有f[x] ← 3,则不仅有f[x] = 3,同时f[y] = 3。换言之,在赋值y←x后,x和y指向同一个对象。

有时,一个指针不指向任何对象。这时,我们赋给它NIL。

8)参数采用按值传递方式:被调用的过程会收到参数的一份副本。如果它对某个参数赋值的话,主调过程是看不见这一变动的。当对象被传递时,实际传递的是一个指向该对象数据的指针,而对象的各个域则不被拷贝。例如,如果x是某个被调用过程的参数,在被调用过程中的赋值x←y对主调过程来说是不可见的。但是,赋值f[x] = 3却是可见的。

9)布尔运算符“and”和“or”都具有短路能力。亦即,当我们求表达式“x and y”的值时,首先计算x的值为FALSE,那么整个表达式的值就不可能为TRUE了,因而就无需再对y求值了。但是,如果x的值为TRUE的话,就必须进一步计算出y的值,才能确定整个表达式的值。类似地,在计算表达式“x or y”的值时,仅当x的值为FALSE时,才需要计算子表达式y的值。短路运算符允许我们写出如“x ≠ NIL and f[x] = y”这样的布尔表达式,而不用担心当我们试图在x为NIL时计算f[x],会发生怎样的情况。

你可能感兴趣的:(了解伪代码)