图标编程
一位维基教科书用户认为此页面应拆分为具有更窄子主题的更小页面。 您可以通过将此大页面拆分为更小的页面来提供帮助。请确保遵循命名策略。将书籍分成更小的部分可以提供更多的关注点,并允许每个部分都擅长一件事,这对每个人都有益。 |
图标是一种现代高级编程语言。它提供了许多用于管理数据、生成器等的实用功能。它不是面向对象的,但是 UN-icon 变体,UNICON,是面向对象的,就像 ObjectIcon (code.google.com/p/objecticon) 一样。
这是一个很小但完整的图标程序。
procedure main() write("Hello world!") end
如您所见,代码非常简单。行 procedure main() 和 end 包含程序的主体。第二行负责在您的标准输出(通常是屏幕)上打印 Hello world!。自然地,过程 write 打印作为参数给出的字符串。有一个类似的过程 read 用于从标准输入(通常是键盘)读取一行。
将上一节中的程序保存到文件 helloworld.icn 中。键入
icont helloworld.icn
在 Linux shell 中。将生成名为 helloworld 的可执行文件。您现在可以运行它。
程序由过程组成。每个过程都以保留字 procedure 开始,后面跟着过程的名称和参数列表(可以为空)。过程以 end 结束。所有指令都以换行符或分号分隔。
必须有一个 main 过程,当用户运行程序时会自动调用该过程。
procedure p1(arg1, arg2, arg3) instr1 instr2 end procedure p2() instr1; instr2 end procedure main(arg) instr1 instr2 instr3 end
如果您想在代码中添加注释,请使用 # 字符。编译器将忽略该字符之后的该行中的所有文本。
图标中的变量没有类型,可以包含任何数据类型的值。这意味着您可以例如将数字分配给其中一个变量,并在几条指令后将字符串分配给它。
无需声明变量(全局变量除外),它们在首次使用时创建。也不需要销毁它们,因为有一个垃圾收集器自动执行此操作。
要给变量赋值,请使用 Pascal 类似的 := 运算符
procedure main() x := 1 # assigns 1 to variable x y := 3 # assigns 3 to variable y x := x + y # assigns 4 (1+3) to variable x y := "example string" # assigns string "example string" to variable y end
字符串是一系列字符。您可以轻松地将字符串常量放入代码中,用一对 " 字符将其括起来。例如
str := "abcdefgh"
将创建一个包含 8 个字符的字符串常量,并将此字符串分配给 str 变量。
字符串中的字符以非常方便的方式索引。与 Pascal 一样,1 指向第一个字符之前的位,2 指向第一个和第二个字符之间的位,依此类推。与许多其他语言不同,字符串也可以从末尾索引。0 指向最后一个字符之后的位,-1 指向最后一个字符之前的位,依此类推。
要访问您想要的字符串的一部分,请使用方括号 [ ] 运算符
- variablename[from:to]
- variablename[index]
第一种方法返回位于 from 和 to 指向的点之间的子字符串。如果您在方括号中只放置一个数字,它等效于 variablename[index:index+1]。
str := "sample string" str[1:7] := "SAMPLE" # str := "SAMPLE string" str[3] := "m" # str := "SAmPLE string" write(str[8:0]) # write("string")
- *str - 生成 str 的长度
- ?str - 生成 str 的随机单字符子字符串
- !str - 生成 str 的单字符子字符串序列
- str1 || str2 - 连接两个字符串
str := "Hello" || " " || "world" # str := "Hello world" str ||:= "!" # str := "Hello world!"
- 字符串区分大小写比较
- str1 == str2 - 如果两个字符串相等,则输出 str2,否则失败
- str1 ~== str2 - 如果两个字符串不相等,则输出 str2,否则失败
- str1 << str2 - 如果 str2 大于 str1,则输出 str2,否则失败
- str1 <<= str2 - 如果 str2 大于或等于 str1,则输出 str2,否则失败
- str1 >> str2 - 如果 str2 小于 str1,则输出 str2,否则失败
- str1 >>= str2 - 如果 str2 小于或等于 str1,则输出 str2,否则失败
- str ? expr - 将 str 设置为 expr 表达式的 &subject
列表类似于字符串,但它们可以包含更多不同的数据。像字符串一样,列表从开头和结尾索引(请阅读与字符串相关的访问字符和子字符串部分)。
您可以使用方括号将列表常量的元素括起来,并用,字符分隔它们来创建列表常量。例如
lst := [1, "hello", 44]
创建了三个元素的列表常量,并将其分配给 lst 变量。要创建空列表,不要在方括号之间放置任何内容
lst := [] # lst value is now an empty list
有一个用于创建所需长度的列表的特殊函数
- list (i,x)
创建 i 元素列表,所有元素都初始化为 x 值。默认情况下,i 为 0,x 为 &null。
list(5, 7) # [7, 7, 7, 7, 7] list(3, "text") # ["text", "text", "text"] list(6) # [&null, &null, &null, &null, &null, &null] list() # []
Icon 中没有数组。使用列表代替。如果您需要多维数组,请使用列表的列表。
matrix := list(3) # makes a list of 3 rows every !matrix := list(5, 0) # each a different list of 5 zeroes matrix[2][4] +:= 5 # adds 5 to the element # in 2nd row and 4th column every write(!!matrix) # writes all the elements
提供了一些非常有用的函数来管理堆栈和队列作为列表。
- push(list, elem) - 将 elem 添加到 list 列表的开头。
- pop(list) - 输出 list 的第一个元素,并将其从 list 中删除,或者如果 list 为空则失败。
- put(list, elem) - 将 elem 添加到 list 的末尾。
- get(list) - 输出 list 的第一个元素,并将其从 list 中删除,或者如果 list 为空则失败,它与 pop 相同。
- pull(list) - 输出 list 的最后一个元素,并将其从 list 中删除,或者如果 list 为空则失败。
queue := [] # creates an empty queue put(queue, 1) # puts 1 into the queue put(queue, "it is a string") # puts "it is a string" into the queue write(get(queue)) # writes 1 write(get(queue)) # writes "it is a string" # queue is now empty stack := [] # creates an empty stack put(stack, 1) # puts 1 into the stack put(stack, "it is a string") # puts "it is a string" into the stack write(get(stack)) # writes "it is a string" write(get(stack)) # writes 1 # stack is now empty write(*queue) # writes length of the queue
要声明记录类型,请使用 record 保留字,例如
record person(firstname, lastname, age)
当您声明一个记录时,会自动定义一个构造函数。构造函数是一个过程,其参数是记录字段的初始值,并返回创建的记录。构造函数的名称与记录的名称相同。
record person(firstname, lastname, age) # declaration of person record jd := person("John", "Doe", 47) # create and assign record value
- rec.fieldname - 输出 rec 记录的 fieldname 字段的值
- *rec - 输出 rec 记录的字段数量
- ?rec - 输出 rec 记录的随机字段的值
- !rec - 生成 rec 记录的所有字段的值
作为 Icon 语言一部分的过程通常称为“函数”。用户作为程序的一部分添加的函数称为“过程”。过程可以通过在标识符前加上保留字“return”来返回一个值。
#example of the use of the reserved word return
procedure ex-ret(var1, _Var2)
b := "a_proc succeeded"
if a_proc(var1) then return b else c_proc(_Var2)
end
生成器是新语言(如 Ruby 和 Python)中非常基础的一部分,最初是在 CLU 之后不久就在 ICON 中使用。
许多 ICON 表达式称为“条件表达式”,它们的评估结果是成功或失败。三个重要的例子是
read(res) find( Str_target, Str_source) match( Str_target, Str_source)
比较运算符形成成功或失败的表达式,例如
write(count > 0)
如果 count 不大于零,则条件表达式中的比较失败;如果没有表达式,则封闭的表达式(即对函数 write() 的调用)永远不会被评估,在这种意义上,它继承了条件表达式的失败。相比之下
b := "paused" if count > 0 then b := "running" write(b) # will write "paused"
目标导向执行不是 Icon 的基础,就像在 Prolog 中一样。Icon 更像是 Oz,其中回溯是一个选项。在 Icon 中,回溯是可用的,但在特定上下文的限制内。ICON 也有“数据回溯”的概念