伪代码编写指南

林赛·沃德编辑了此页面2022 年 5 月 4 日 · 9次修订

良好伪代码指南

伪代码是设计和规划计算机程序的有用的早期步骤。这个想法是,根据算法(实现解决方案的步骤)而不是根据实际的计算机代码来思考更容易、更自然。

写出伪代码之后再写代码应该是一个简单的翻译过程——将算法转换为特定语言的程序。确切的实现将取决于语言,这就是为什么伪代码应该是“与语言无关的”。
程序员应该能够通过编写良好的算法(伪代码)实现(编码)解决方案,而不必解决更多问题(仅是琐碎的问题)。

没有规则可以生成“完美”伪代码,因为它不必编译,但本文档提供了编写良好伪代码的指南。

好的伪代码的属性

  1. 作为解决方案的完整性
  2. 一般概念和约定
  3. 清晰度、明确性和良好的格式
  4. 简洁表达
  5. 俭朴
  6. 良好的组织

1. 解决方案的完整性

伪代码必须使用定义良好的操作来解决手头的问题。翻译伪代码的程序员应该能够几乎机械地完成这项工作。在编程阶段不需要开发算法或解决问题。

软件开发是一个多阶段的过程,大部分艰苦的工作应该发生在设计过程中,而不是构建过程中。这里有一个类比,比如写一篇文章。困难的部分是提出你的想法和论点;正确掌握语法和拼写应该是比较容易的部分。在软件开发中,算法的设计是困难的部分,而翻译成编程语言实现应该很容易。

坏的

Calculate the tax

好的

tax = 0
if income > TAX_FREE_THRESHOLD
    tax = income × TAX_RATE

2. 一般概念和约定

伪代码不应该特定于特定的编程语言;它应该使用一般概念和惯例。

坏的

import random module
temperature = random.randint(LOW, HIGH)

好的

temperature = random integer between LOW and HIGH inclusive

为什么“导入随机模块”不好?并非每种语言都有随机模块,即使它们都有,导入该模块也不是算法的重要部分。你不是在告诉程序员如何编写程序,而是在告诉她如何解决问题。您可以假设实现伪代码的程序员有足够的智力和知识来使用其编程语言中可用的工具。

3. 清晰、明确、格式良好

伪代码需要缩进良好、间距适当并且风格一致,这样才不会令阅读它的程序员感到困惑或烦恼。变量名称必须一致、清晰,并且明确使用。

坏的

if a     >  B             # poorly spaced
    display message       # unclear (what kind of message?)
    get x                 # poor variable name
    if this is "y"        # not explicit
    vent the gas          # not explicit, not indented 
    display last message  # is this meant to be inside or outside the if?... we can't know

好的

if pressure > CRITICAL_PRESSURE
    display critical error message
    get ventGasChoice
    if ventGasChoice is "y"
        ventGas()
    display farewell message

您不得引用不存在的事物或对同一事物使用不同的名称。需要保持一致性。

坏的

get the user's choice
if choice is 'Q'
    display total

上面,一个可能相同的变量被称为choicethe user's choice。程序员永远不必猜测这是相同还是不同。始终如一。
total不存在,所以我们不能使用它。所有变量都必须适当引入(代码中也是如此)。
请注意,我们这里的一些示例只是完整伪代码的一部分,因此您会看到我们确实引用了不存在的名称的地方,但这不是一个错误;这只是一个不完整的例子,以关注我们所关心的部分。

好的

total = 0
get choice
if choice is 'Q'
    display total

注意:变量名称不必采用任何特定的样式,例如驼峰式或下划线式(例如“ventGasChoice”、“ventgas choice”或“vent_gas_choice”都可以)。这是独立于语言的一部分——没有固定的或与语言相关的约定。话虽如此,您可能会发现使用您希望实现的语言的约定很方便,因为您可以更轻松地复制并粘贴到代码中。

4、简洁的表达

伪代码应该简洁。在不牺牲清晰度的情况下,尽可能简单地编写说明。

坏的

get input from the user and store it in a variable called "value"
store the number one in a variable called "value"
make c equal to the sum of a and b

好的

get value
value = 1
c = a + b

请注意,“好”示例看起来很像代码,这没关系。您不必费尽心思使伪代码看起来与代码不同。只要简单、常规、清晰即可。

5. 节俭

伪代码应该可以解决问题,但仅此而已!不应有多余的材料。在伪代码中添加注释是可以的,但是指令本身不应该说明其意图。

坏的

if x < LEFT_BOUND or x > RIGHT_BOUND then the train could derail
    haltTrain() to stop the train from derailing

好的

(check if the train is about to derail and stop it)
if x < LEFT_BOUND or x > RIGHT_BOUND
    haltTrain()

不应该有任何不能实现任何目标的指令。

坏的

Define the constants

“定义常量”是不好的,因为程序员知道她必须定义变量!这样的声明没有添加任何信息。当软件开发人员在编写伪代码时从代码逆向工作时,经常会出现类似上述的情况。

6、良好的组织能力

伪代码应该组织成适当的函数,就像代码的情况一样。伪代码中的函数和代码中的函数之间应该存在一对一的映射。即,如果do_something是伪代码中的函数,那么它应该在代码中显示为函数,反之亦然。

函数内的伪代码应该具有已经讨论过的五个质量属性。每个单独的功能应单独指定;函数的伪代码不应该写在调用它的地方。为函数编写伪代码时,请确保包含任何参数(请参见下面的示例)。

伪代码模式

评论

如果确实需要注释,请将它们写在自己的行上,并用括号括起来。

(check if the train is about to derail and stop it)

终端输入:如何将数据放入变量中

get name
get age

如果您需要获取多个输入,只需将它们放在一起即可,例如:

get name, age, salary

终端输出:如何显示变量或消息

print "Hello world"
print name
print venting gas message

如果您需要打印多个输出,只需将它们放在一起即可,例如:

print name, salary, bonus

注意:没有必要通过编写细节来以伪代码复制接口。程序员应该有权访问计划的该部分,因此会知道“排气消息”是什么。包含大引号会使伪代码更难阅读。
没有必需的单词,所以printdisplay类似的都可以......但在一个程序中保持一致。

算术

gross = hours * rate
nett = gross – tax
average = total / count (use floating point arithmetic)

决策结构

if age >= 65
    price = price – seniorDiscount

if temperature > 60
    display "Too hot!"
else if temperature < 40
    display "Too cold!"
else
    display "Just right :)"

诸如“太热了!”之类的字符串。足够短,不会影响可读性,因此可以直接包含在内。请注意,我们可以使用“else if”或“otherwise if”,但不能使用“elif”,因为这是 Python 特有的而不是普通英语。

重复结构

total = 0
get price
while price > 0
    total = total + price
    get price

for count from 1 to 10
    display count

for each grade in grades
    display grade

repeat n times
    display horizontal line

函数定义

function do_something(x, y)
    return (x + y) * (y – x)

函数调用

result = do_something(azimuth, altitude)

文件输入

open "info.txt" as file_in for reading
get name from file_in
get age from file_in
close file_in

文件输出

open "stats.dat" as file_out for writing
for each datum in data
    write datum to file_out
    write newline to file_out
close file_out

异常处理

try
    get number as integer
    display some_list[number]
catch invalid number error
    display invalid number message
catch index error
    display invalid index message

不必担心异常名称的确切值;只要确保它是清楚的。

字符串操作

response = response in uppercase
words = split sentence on whitespace
comma_position = find first comma in sentence

列表

prices = empty list
add price to prices
prices[0] = 0.0
if index < length of prices
    display prices[index]

请注意列表/数组的伪代码与真实代码的相似程度——这很好。我们不需要让它变得更难,只是尝试变得不那么像代码。

字典(又名地图或关联数组)

name_to_phone = empty dictionary
name_to_phone[name] = number
display name_to_phone[name]

for each name in the keys of name_to_phone
    display name

for each name:number in name_to_phone
    display name, number

课程

class Person
    constructor(name, age, gender)
        instance.set_name(name)
        instance.set_age(age)
        instance.set_gender(gender)

    basic getters for name, age, gender

    basic setters for name, age

    method set_gender(gender)
        if gender in lowercase is not "male" or "female"
            gender = "female"
        instance.gender = gender

注意: get_name() 等非常简单,只需指定它们将存在(例如name、age、gender 的基本 getter),而不是编写伪代码。

带有Python代码实现的完整示例

伪代码

function main()
    get name
    while name is not blank
        get age
        if is_adult(age)
            print name is an adult
        else
            print name is a minor
        get name

function is_adult(age)
    return age >= 18

Python

    def main():
        print("Welcome to the name & age program that brings happiness.")
        name = input("Enter your name (blank to quit): ")
        while name != "":
            age = int(input("Enter your age: "))
            if is_adult(age):
                print(name, "is an adult")
            else:
                print(name, "is a minor")
            name = input("Enter your name (blank to quit): ")

    def is_adult(age):
        return age >= 18

    main()
 

需要注意的一些事项:

  • 排除了诸如欢迎消息以及如何显示输出字符串之类的次要细节。
  • 诸如需要调用 main 来运行程序以及年龄应该是整数等明显的事情被排除在外。包含这些并没有错,但它们大多是不必要的。
  • “虽然名称不为空”可以用不同的语言以多种不同的方式实现......这个伪代码清楚地说明了要做什么,而不是如何做。
  • 它看起来像简单的代码。(Python 看起来很像好的伪代码。)
  • 包括非常常见的“语法”字符,例如函数的括号,但不包括特定于语言的字符,例如 else 后面的冒号(仅在某些语言中)。

另一个例子

伪代码

DISCOUNT_THRESHOLD = 5
ITEM_PRICE = 32.5
DISCOUNT_RATE = 0.1

get number_of_products
while number_of_products <= 0
    print error message
    get number_of_products
total = number_of_products * ITEM_PRICE
if number_of_products > DISCOUNT_THRESHOLD
    total -= total * DISCOUNT_RATE
print number_of_products, ITEM_PRICE, total

Python

DISCOUNT_THRESHOLD = 5
ITEM_PRICE = 32.5
DISCOUNT_RATE = 0.1

print(f"If you buy over {DISCOUNT_THRESHOLD} items, 
                                    save {DISCOUNT_RATE * 100:.0f}%!")
number_of_products = int(input("Number of products: "))
while number_of_products <= 0:
    print("Invalid number")
    number_of_products = int(input("Number of products: "))
total = number_of_products * ITEM_PRICE
if number_of_products > DISCOUNT_THRESHOLD:
    total -= total * DISCOUNT_RATE
print(f"{number_of_products} x ${ITEM_PRICE:.2f} 
                                            products = ${total:.2f}")

本文档由詹姆斯库克大学 IT 学科的 Trevor Andersen 和 Lindsay Ward 编写。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值