首页/文档/动手练习

动手练习

可以自己修改并运行的小练习。

这些练习会用到语言基础里的内容。先尝试完成每道题,再展开查看答案。题目、提示和预期结果会一直显示,方便你先自己思考。

练习一到练习五:按答案提示保存文件,然后检查并运行。下面以 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 切片只是查看调用方提供的内存,这个函数不会分配或复制输入数据。

更多函数和循环示例见语言基础。切片属于进阶主题,详见内存与安全。

↵ 打开 · esc 关闭