CAPL 编程系列教程的第十五期内容,开始讲解 CAPL 中的一个核心概念:函数的定义与调用 (Function Definition and Call)。
CAPL 编程系列教程 - 第十五期:函数的定义与调用 (基础)
一、 课程回顾与本期目标
- 回顾: 前面学习了 CAPL 的基础语法,包括数据类型、变量、运算符、分支结构和循环结构。
- 本期目标: 学习如何在 CAPL 中定义自己的函数以及如何调用这些函数。
- 核心概念:
- 函数 (Function): 本质上是为了完成一个特定功能 (Function) 而组织起来的一段代码块。
- 目的:
- 提高代码重用性: 将常用或特定的功能封装起来,避免重复编写代码。
- 模块化: 将大型程序分解为多个功能独立的模块(函数),使代码结构更清晰,易于管理和维护。
- 与 C/C++ 的关系: CAPL 的函数定义与 C 语言几乎完全一致,但也借鉴了 C++ 的一些特性(如重载,本期未详述)。
二、 函数的定义 (Defining a Function)
- 基本语法:
Code snippet
<return_type> FunctionName(<parameter_list>) { // Function body (statements implementing the function's logic) // [return return_value;] // Optional return statement }
- 定义位置: 函数定义必须在事件处理代码块(如
on key)之外,通常与其他函数定义或全局变量定义放在同一层级。 - 组成部分:
return_type(返回值类型):- 指定函数执行完毕后返回给调用者的数据的类型(如
int,float,char,struct Point等)。 void: 如果函数不返回任何值,则使用关键字void作为返回值类型。- CAPL 特点: 如果函数不返回任何值,
void关键字可以省略。如果在 CAPL 代码中看到函数名前面没有类型,就等同于 void。
- 指定函数执行完毕后返回给调用者的数据的类型(如
FunctionName(函数名):- 自定义的函数的名称,用于后续调用。
- 必须符合 CAPL 的标识符命名规则。
parameter_list(形式参数列表 / 形参):- 放在函数名后的小括号
()内,小括号必须存在。 - 用于接收调用者传递给函数的数据。
- 列表包含零个或多个参数声明,多个参数用逗号
,分隔。 - 每个参数声明格式为
DataType ParameterName(如float a,int b)。 - 形参 (Formal Parameter): 定义函数时声明的参数,它们是函数内部使用的局部变量,起到占位作用,等待调用时接收实际值。
- 无参数: 如果函数不需要接收任何数据,参数列表为空,但小括号
()仍需保留(如MyFunction())。
- 放在函数名后的小括号
{ Function body }(函数体):- 花括号
{}内的代码块,包含实现函数具体功能的语句。 - 函数体可以包含变量定义、运算、流程控制、调用其他函数等。
- 局部变量: 在函数体内定义的变量是局部变量,仅在该函数内部有效。定义规则同事件处理块,必须在代码块开头声明。推荐声明和赋值分开。
- 花括号
return语句:- 功能: 用于结束函数的执行,并可选择性地将一个值返回给调用者。
- 带返回值:
return expression;计算expression的值,并将其作为函数的返回值。返回值的类型必须与函数定义时声明的return_type兼容。 - 不带返回值:
return;(或省略return语句) 用于结束void函数的执行。 - 非必须: 如果函数声明为
void,可以省略return语句,函数会在执行完最后一条语句后自动结束。如果声明了非void返回类型,则通常必须有return语句返回一个兼容类型的值。
三、 函数的调用 (Calling a Function)
- 基本语法:
FunctionName(<argument_list>);
- 调用位置: 可以在事件处理代码块(如
on key)、其他函数体内部,或者 CAPL 的特定执行上下文中调用函数。 - 方式: 使用函数名加上小括号
()来调用。 argument_list(实际参数列表 / 实参):- 放在调用时的小括号
()内,提供给函数的值。 - 实参的数量、类型和顺序必须与函数定义时的形参列表匹配。
- 实参可以是常量、变量或表达式。
- 放在调用时的小括号
- 执行流程:
- 当程序执行到函数调用语句时,会将实参的值按顺序传递(赋值)给函数定义中的形参。
- 程序的控制权转移到被调用函数的函数体第一条语句开始执行。
- 函数体执行完毕(遇到
return或执行到末尾)。 - 如果函数有返回值,
return语句会将返回值传递回调用点,函数调用表达式本身的值就是这个返回值。 - 程序的控制权返回到调用语句之后的位置继续执行。
- 使用返回值:
- 可以将函数调用的结果赋值给一个变量:
float r = power(2.5, 3);。 - 可以直接在表达式中使用函数调用的结果:
write("结果是 %d", power(4, 4));(如果需要类型转换,如(int)power(4, 4))。
- 可以将函数调用的结果赋值给一个变量:
四、 示例:求 A 的 B 次方 (power 函数)
Code snippet
// --- 函数定义 ---
float power(float a, int b) // 返回 float, 接收 float a 和 int b
{
float p; // 局部变量:用于存储乘积
int i; // 局部变量:循环计数
p = 1; // 初始化乘积为 1
// 使用 for 循环计算 a 的 b 次方
for (i = 0; i < b; i++) {
p *= a; // 等价于 p = p * a;
}
return p; // 返回计算结果
}
// --- 事件处理块 (调用函数) ---
on key 'a'
{
float r; // 用于接收返回值的局部变量
// 调用函数并将返回值赋给 r
r = power(2.5, 3); // 计算 2.5 的 3 次方
write("2.5 的 3 次方为: %.4f", r); // 输出结果
// 直接在 write 函数中调用 power 函数
write("4 的 4 次方为: %d", (int)power(4, 4)); // 计算 4 的 4 次方,并将 float 结果转为 int 输出
}
五、 总结与后续
- 本期学习了 CAPL 中函数定义和调用的基本语法和概念,这是实现代码复用和模块化的基础。
- 理解了形参和实参的区别,以及返回值的概念和
return语句的用法。 - 下一期将继续深入讲解函数的其他方面。