浙江传媒学院 · 仓颉面向对象程序设计 · 基于 CangStream 框架构建
浙江传媒学院 · 仓颉面向对象程序设计 · 基于 CangStream 框架构建
基本输出程序,使用 println 函数向控制台输出字符串。
package demo
main(): Int64 {
println("hello! 仓颉")
return 0
}
''使用元组表示"仓"和"颉"两个汉字的偏旁组成结构。''
package demo
main() {
let cang = ("人", "㔾", "仓")
let jie = ("吉", "页", "颉")
let greeting = "hello," + cang[2] + jie[2]
println(greeting)
println("'${cang[2]}' 由 '${cang[0]}' 和 '${cang[1]}' 组成")
println("'${jie[2]}' 由 '${jie[0]}' 和 '${jie[1]}' 组成")
}
从标准输入读取编程语言名称,并输出问候语。
package demo
import std.console.Console
main() {
print("请输入您学习的编程语言名称:")
let name = Console.stdIn.readln().getOrThrow()
println("${name},你好!")
return 0
}
使用仓颉扩展库自定义 MyHttpServer 类,实现 Web 终端问候程序。完整实现将在类编程与网络编程章节详细介绍。
package demo
class MyHttpServer {
let fontName: String
let content: String
init(fontName: String, content: String) {
this.fontName = fontName
this.content = content
}
func start(): Unit {
println("Web 服务器已启动")
println("字体:${fontName}")
println("内容:${content}")
}
}
main(): Int64 {
let app = MyHttpServer("黑体", "Hello 仓颉!")
app.start()
return 0
}
定义 max 函数,通过 if-else 表达式比较并返回较大值。
package demo
func max(a: Int64, b: Int64): Int64 {
if (a > b) {
return a
} else {
return b
}
}
main(): Int64 {
let x = 1
let y = 5
let fmax = max(x, y)
println("${x} 和 ${y} 相比,${fmax} 比较大")
return 0
}
定义 FindMax 类,将比较逻辑封装为成员方法。
package demo
class FindMax {
public var x: Int64
public var y: Int64
FindMax(a: Int64, b: Int64) {
this.x = a
this.y = b
}
func max(): Int64 {
if (x > y) { return x } else { return y }
}
}
main(): Int64 {
var abmax = FindMax(1, 5)
let fmax = abmax.max()
println("${abmax.x} 和 ${abmax.y} 相比,${fmax} 比较大")
return 0
}
同一个数值 24 用二进制、八进制、十进制、十六进制四种形式表示。
package demo
main() {
let bInt: Int64 = 0b0001_1000 // 二进制
let oInt: Int64 = 0o30 // 八进制
let dInt: Int64 = 24 // 十进制
let hInt: Int64 = 0x18 // 十六进制
println("bInt is ${bInt}")
println("oInt is ${oInt}")
println("dInt is ${dInt}")
println("hInt is ${hInt}")
}
通过后缀 i8、u64、i32 明确指定整数字面量的类型。
package demo
main() {
var x = 100i8
var y = 0x10u64
var z = 0o432i32
println("x is ${x} with type Int8")
println("y is ${y} with type UInt64")
println("z is ${z} with type Int32")
}
字符字节字面量以 b 开头,表示 UInt8 类型的 ASCII 值。
package demo
main() {
var a = b'x'
var b = b'\n'
var c = b'\u{78}'
println("a is ${a} with type UInt8")
println("b is ${b} with type UInt8")
println("c is ${c} with type UInt8")
}
仓颉使用 ** 运算符进行幂运算,左操作数为 Int64 时右操作数须为 UInt64。
package demo
main() {
let p1 = 2 ** 3
let p2 = 2 ** UInt64(3 ** 2)
let p3 = 2.0 ** 3.0
let p4 = 2.0 ** 3 ** 2
let p5 = 2.0 ** 3.0 ** 2.0
println("2的3次方是 ${p1}")
println("2的3**2次方是 ${p2}")
println("2.0的3.0次方是 ${p3}")
println("2.0的3**2次方是 ${p4}")
println("2.0的3.0**2.0次方是 ${p5}")
}
浮点字面量支持十进制和十六进制两种形式,十六进制须包含指数部分(p/P)。
package demo
main() {
let a: Float32 = 3.14
let b: Float32 = 2e3
let c: Float32 = 2.4e-1
let d: Float64 = .123e2
let e: Float64 = 0x1.1p0
let f: Float64 = 0x1p2
let g: Float64 = 0x.2p4
println("a= ${a}")
println("b= ${b}")
println("c= ${c}")
println("d= ${d}")
println("e= ${e}")
println("f= ${f}")
println("g= ${g}")
}
''使用 Unicode 码点表示汉字,输出"浙江传媒学院"。''
package demo
main() {
let a: Rune = r'\u{6D59}'
let b: Rune = r'\u{6C5F}'
let c: Rune = r'\u{4F20}'
let d: Rune = r'\u{5A92}'
let e: Rune = r'\u{5B66}'
let f: Rune = r'\u{9662}'
print(a); print(b); print(c)
print(d); print(e); print(f)
}
字符串字面量可用单引号或双引号定义,支持转义字符。
package demo
main() {
let s0 = "开始"
let s1: String = ""
let s2 = '你好,仓颉'
let s3 = "\"你好,仓颉\""
let s4 = '你好,仓颉\n'
let s5 = "\'结束\'"
println("s0= ${s0}")
println("s1= ${s1}")
println("s2= ${s2}")
println("s3= ${s3}")
println("s4= ${s4}")
println("s5= ${s5}")
}
单字符 ASCII 字符串可隐式转换为 Byte 类型;单字符字符串可隐式转换为 Rune 类型。
package demo
main() {
var b: Byte = "0"
print(b)
b = "1"
print(b)
var r: Rune = "0"
print(r)
r = "1"
print(r)
}
''使用 ${} 将表达式嵌入字符串,实现动态文本拼接。''
package demo
main() {
let ch1 = "木"
let ch2 = "林"
let sentence = "${ch1}+${ch1}=${ch2}"
println(sentence)
}
字符串支持 == 判等和 + 拼接操作。
package demo
main() {
let char1 = "日"
let char2 = "月"
let char3 = "木"
let char4 = "木"
let char5 = "明"
let char6 = "林"
let r1 = char1 == char2
let r2 = char3 == char4
let result = "双${char3}成${char6},${char1}${char2}为${char5}!"
println(result)
println("\"明\"字的左右结构相同?答案是:${r1}")
println("\"林\"字的左右结构相同?答案是:${r2}")
}
元组可组合不同类型的值,通过下标 t[index] 访问指定位置的元素。
package demo
main() {
var ming = (1, "日月", "明")
println(ming[0]) // 输出第一个元素:1
println(ming[1]) // 输出第二个元素:"日月"
println(ming[2]) // 输出第三个元素:"明"
}
使用元组字面量对等号右侧的元组进行解构,_ 表示忽略对应位置的值。
package demo
main() {
var a: Int64
var b: String
var c: Unit
var f = { => ((1, "abc"), ()) }
((a, b), c) = f() // a=1, b="abc", c=()
((a, b), _) = ((2, "def"), 3.0) // a=2, b="def", 3.0 被忽略
println(a)
println(b)
println(c)
}
Array 是有序集合,可用 for-in 循环遍历所有元素。
package demo
main() {
let arr = [25, 45, 90]
for (i in arr) {
println("The element is ${i}")
}
}
size 属性返回数组元素个数,可用于判断数组是否为空。
package demo
main() {
let arr = [25, 45, 90]
if (arr.size == 0) {
println("This is an empty array")
} else {
println("The size of array is ${arr.size}")
}
}
通过下标 arr[index] 访问指定位置的元素,下标从 0 开始。
package demo
main() {
let arr = [23, 21, 62]
let a = arr[0] // a == 23
let b = arr[1] // b == 21
let c = arr[arr.size - 1] // c == 62,最后一个元素
println(a)
println(b)
println(c)
}
Unit 类型只有一个值 (),用于只关心副作用而不关心返回值的场景。
package demo
main() {
let c: Unit = ()
func sayHello(): Unit {
println("Hello, Cangjie!")
}
let result = sayHello()
let u1: Unit = ()
let u2: Unit = ()
println(u1 == u2) // true
println(u1 != u2) // false
println(c) // ()
println(result) // ()
}
break、continue、return、throw 表达式的类型均为 Nothing,执行后其后的代码不会被执行。
package demo
func testReturn() {
println("准备返回")
return 42 // return 表达式类型是 Nothing
}
func testThrow() {
throw Exception("发生错误!") // throw 表达式类型是 Nothing
}
main() {
let arr = [1, 2, 3, 4, 5]
for (i in arr) {
if (i == 2) { continue }
if (i == 4) { break }
println("当前元素: ${i}")
}
let result = testReturn()
println("返回值是:${result}")
testThrow()
return 0
}
通过自定义 decimalToHex 函数实现十进制到十六进制的进位计数制转换。
package demo
func decimalToHex(num: UInt32): String {
if (num == UInt32(0)) { return "0" }
var result = ""
var n = num
let hexChars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
while (n > UInt32(0)) {
let remainder = n % UInt32(16)
result = hexChars[Int64(remainder)] + result
n = n / UInt32(16)
}
return result
}
main() {
println(decimalToHex(10)) // 输出:A
}
Rune 与 UInt32 之间的转换基于 Unicode 标量值:UInt32(rune) 得到码点,Rune(uint32) 得到对应字符。
package demo
main() {
let x: Rune = 'a' // 'a' 的 Unicode 编码为 97
let y: UInt32 = 65 // 65 对应字符 'A'
let r1 = UInt32(x) // Rune -> UInt32,结果为 97
let r2 = Rune(y) // UInt32 -> Rune,结果为 'A'
println("The type of r1 is 'UInt32', and r1 = ${r1}")
println("The type of r2 is 'Rune', and r2 = ${r2}")
}
读取用户输入的年份,根据闰年规则(能被4整除且不被100整除,或能被400整除)进行判断。
package demo
import std.env.*
import std.convert.*
main() {
getStdOut().write("请输入年份:")
let s = getStdIn().readln().getOrThrow()
let year = Int32.parse(s)
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
getStdOut().write("${year}是闰年\n")
} else {
getStdOut().write("${year}不是闰年\n")
}
}
计算 1! + 2! + 3! + … + n! 的累加和。
package demo
import std.env.*
import std.convert.*
main() {
getStdOut().write("请输入一个小于12的整数:")
let s = getStdIn().readln().getOrThrow()
let n = Int64.parse(s)
var sum = 0
var prod = 1
for (i in 1..n+1) {
prod = prod * i
sum = sum + prod
}
getStdOut().write("1到${n}的阶乘和为${sum}\n")
}
用嵌套 for-in 循环输出九九乘法表。
package demo
import std.env.*
import std.convert.*
main() {
getStdOut().write("请输入一个小于10的整数:")
let s = getStdIn().readln().getOrThrow()
let n = Int64.parse(s)
for (i in 1..n+1) {
for (j in 1..i+1) {
getStdOut().write("${i}*${j}=${i*j} ")
}
getStdOut().write("\n")
}
}
读取一个整数,使用试除法判断其是否为素数。
package demo
import std.env.*
import std.convert.*
main() {
getStdOut().write("请输入一个整数:")
let s = getStdIn().readln().getOrThrow()
let n = Int64.parse(s)
var flag = true
if (n == 1) { flag = false }
var i = 2
while (i * i <= n) {
if (n % i == 0) { flag = false; break }
i++
}
if (flag) {
getStdOut().write("${n}是素数\n")
} else {
getStdOut().write("${n}不是素数\n")
}
}
将字符串转为 Rune 数组后从尾到头输出,实现字符串翻转。
package demo
import std.env.*
main() {
let s: String = "秋江楚雁宿沙洲"
getStdOut().write("原字符串为 :${s}\n")
let str = s.toRuneArray()
getStdOut().write("翻转后字符串为:")
var i = str.size - 1
while (i >= 0) {
getStdOut().write("${str[i]}")
i--
}
getStdOut().write("\n")
}
读取两个整数,分别求其最大公约数(辗转相减法)和最小公倍数。
package demo
import std.env.*
import std.convert.*
func gcd(a: Int64, b: Int64): Int64 {
var t = a
while (t >= 1) {
if (a % t == 0 && b % t == 0) { break }
t--
}
return t
}
func lcm(a: Int64, b: Int64): Int64 {
return a * b / gcd(a, b)
}
main() {
getStdOut().write("请输入第一个整数:")
var s = getStdIn().readln().getOrThrow()
let a = Int64.parse(s)
getStdOut().write("请输入第二个整数:")
s = getStdIn().readln().getOrThrow()
let b = Int64.parse(s)
getStdOut().write("${a}和${b}的最大公约数为${gcd(a,b)}\n")
getStdOut().write("${a}和${b}的最小公倍数为${lcm(a,b)}\n")
}
将汉字的 Unicode 标量值转换为十六进制,并以 U+ 前缀形式输出。
package demo
func decimalToHex(num: UInt32): String {
if (num == UInt32(0)) { return "0" }
var result = ""
var n = num
let hexChars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
while (n > UInt32(0)) {
let remainder = n % UInt32(16)
result = hexChars[Int64(remainder)] + result
n = n / UInt32(16)
}
return result
}
func decimalToHexWithPrefix(num: UInt32): String {
return "U+" + decimalToHex(num)
}
main() {
let a = r'啊'
println("汉字${a}的Unicode码是${decimalToHexWithPrefix(UInt32(a))}")
}