动手练习
可以自己修改并运行的小练习。
这些练习会用到语言基础里的内容。先尝试完成每道题,再展开查看答案。题目、提示和预期结果会一直显示,方便你先自己思考。
练习一到练习五:按答案提示保存文件,然后检查并运行。下面以 exercise-1.ck 为例,请替换成对应题目的文件名:
macOS 或 Linux:
./ckc check exercise-1.ck
./ckc run exercise-1.ck
Windows PowerShell:
.\ckc.exe check .\exercise-1.ck
.\ckc.exe run .\exercise-1.ck
练习六和练习七是可供其他程序调用的函数,由调用方提供数据。它们没有 main 函数,因此用 ckc check 检查;题目中的示例结果表示函数收到指定输入后会返回的值。
如果还没有下载编译器或创建过 .ck 文件,快速开始会一步步说明怎么做。
练习一:算出总数#
任务: 把 12 和 5 相加,并让程序显示结果。
提示: 把结果存入一个变量,再打印出来。
预期输出:
17
点击查看完整答案
保存为: exercise-1.ck
fn main() -> i32 {
let first: i32 = 12;
let second: i32 = 5;
let total: i32 = first + second;
print_i32(total);
print_newline();
return 0;
}
练习二:修改函数#
任务: double 函数会把收到的数字乘以 2。请把它改成乘以 3,再调用它计算 7。
从这个函数开始,再补上 main:
fn double(value: i32) -> i32 {
return value * 2;
}
提示: 修改函数里的乘法,再在 main 中用 print_i32(double(7)); 显示结果。
预期输出:
21
点击查看完整答案
保存为: exercise-2.ck
fn double(value: i32) -> i32 {
return value * 3;
}
fn main() -> i32 {
print_i32(double(7));
print_newline();
return 0;
}
函数保留了原来的名字,但现在会把数字乘以三。main 会打印函数返回的结果。
练习三:判断是否及格#
任务: 分数至少为 60 时显示 1,否则显示 0。先用 75 运行,再把分数改成 50,重新运行。
提示: 使用 if 和 else 决定要打印哪个数。
预期输出:
1
把分数改成 50 后,输出为 0。
点击查看完整答案
保存为: exercise-3.ck
fn main() -> i32 {
let score: i32 = 75;
if score >= 60 {
print_i32(1);
} else {
print_i32(0);
}
print_newline();
return 0;
}
>= 表示“大于或等于”。分数为 50 时,条件不成立,else 分支会打印 0。
练习四:把 1 到 5 加起来#
任务: 使用 while 循环计算 1 + 2 + 3 + 4 + 5,并显示总和。
提示: 用一个变量记录总和,每轮循环后把当前数字加一。
预期输出:
15
点击查看完整答案
保存为: exercise-4.ck
fn main() -> i32 {
let number: i32 = 1;
let total: i32 = 0;
while number <= 5 {
total = total + number;
number = number + 1;
}
print_i32(total);
print_newline();
return 0;
}
每轮先把当前数字加进 total,再把 number 增加一。它变成 6 后,条件不再成立,循环就会结束。
进阶练习#
接下来的练习会用到可复用的计算、循环和切片。练习六和练习七适用于由调用方提供内存的程序;先阅读内存与安全中的切片介绍,再用 ckc check 检查你的函数。
练习五:计算阶乘#
任务: 编写一个函数,计算 6 的阶乘。阶乘就是从 1 开始,连续乘到指定数字:6! = 1 × 2 × 3 × 4 × 5 × 6。
提示: 把乘积从 1 开始,使用一个从 1 增加到 6 的计数变量。
预期输出:
720
点击查看完整答案
保存为: exercise-5.ck
fn factorial(value: i32) -> i32 {
let factor: i32 = 1;
let product: i32 = 1;
while factor <= value {
product = product * factor;
factor = factor + 1;
}
return product;
}
fn main() -> i32 {
print_i32(factorial(6));
print_newline();
return 0;
}
循环把每一步的乘积保存在同一个变量里。也可以把其他较小的正整数传给这个函数;过大的结果会超出 i32 范围。
练习六:找出切片中的最大值#
任务: 编写一个函数,接收一段非空的整数切片,并返回其中最大的值。输入 [6, -2, 14, 9] 时,应返回 14。
提示: 先把第一项当作当前最大值,再逐项与它比较。
示例结果: 输入 [6, -2, 14, 9] 时,函数返回 14。
点击查看完整答案
保存为: exercise-6.ck
export fn largest(items: slice<i32>) -> i32 {
let best: i32 = items[0];
let index: u32 = 1;
while index < items.len {
if items[index] > best {
best = items[index];
}
index = index + 1;
}
return best;
}
这个函数要求切片不能为空。调用它的程序需要提供对应的内存;index 会逐项检查,并在发现更大的值时更新 best。
练习七:计算切片中一段数据的总和#
任务: 编写一个函数,接收一个切片和两个索引,计算从 start 开始、到 end 之前(不包括 end)这一段数据的总和。对于 [4, 7, 1, 9, 3] 和范围 1..4,选中的数字是 7、1、9。
提示: 先用 items[start..end] 得到一个子切片,再用索引逐项累加。
示例结果: 输入 [4, 7, 1, 9, 3] 和范围 1..4 时,函数返回 17。
点击查看完整答案
保存为: exercise-7.ck
export fn sum_range(items: slice<i32>, start: u32, end: u32) -> i32 {
let selected: slice<i32> = items[start..end];
let index: u32 = 0;
let total: i32 = 0;
while index < selected.len {
total = total + selected[index];
index = index + 1;
}
return total;
}
调用方需要保证索引满足 start <= end <= items.len。CK 切片只是查看调用方提供的内存,这个函数不会分配或复制输入数据。