脚本文件是包含(几乎)任意 Octave 命令序列的文件。它被读取和执行的方式与你直接在 Octave 提示符下逐条输入命令相同,为执行那些逻辑上不属于函数的命令序列提供了一种便捷方式。
与函数文件不同,脚本文件不得以关键字 function 开头。如果以 function 开头,Octave 会认为它是一个函数文件,并且它定义了一个单一函数,该函数应在被定义后立即执行。
脚本文件与函数文件的另一个区别在于:脚本文件中命名的变量不是局部变量,而是与命令行上可见的其他变量处于同一作用域中。
即使脚本文件不能以 function 关键字开头,仍然可以在单个脚本文件中定义多个函数,并一次性加载(但不执行)所有函数。要做到这一点,文件中的第一个标记(忽略注释和其他空白字符)必须是 function 以外的内容。如果没有其他要执行的语句,可以使用一个无实际效果的语句,如下所示:
# 防止 Octave 认为这是 # 一个函数文件: 1; # 定义函数 one: function one () ...
要让 Octave 读取并将这些函数编译为内部形式,你需要确保该文件位于 Octave 的加载路径中(可通过 path 函数访问),然后只需输入包含这些命令的文件的基本名称即可。(Octave 使用与搜索函数文件相同的规则来搜索脚本文件。)
如果文件中的第一个标记(忽略注释)是 function,Octave 将编译该函数并尝试执行它,同时打印一条警告消息,指出函数定义之后出现的任何非空白字符。
请注意,Octave 在对任何标识符进行求值之前,不会尝试查找其定义。这意味着,如果以下语句出现在脚本文件中,或者在命令行上输入,Octave 都将对其进行编译:
# 不是函数文件: 1; function foo () do_something (); endfunction function do_something () do_something_else (); endfunction
即使函数 do_something 在被函数 foo 引用之前尚未定义,这也不会导致错误。因为 Octave 不需要解析函数所引用的所有符号,直到该函数被实际执行时才会进行解析。
由于 Octave 在需要定义之前不会主动查找定义,因此无论以下代码是直接在命令行上键入、从脚本文件中读取还是作为函数体的一部分,它始终会打印出 ‘bar = 3’,即使 Octave 的路径中存在一个名为 bar.m 的函数或脚本文件。
eval ("bar = 3");
bar
如果定义在函数编译时就被解析,那么出现在函数体内部的类似代码可能会误导 Octave。实际上,要使 Octave 足够智能以一致的方式执行这段代码是几乎不可能的。解析器必须能够在编译时执行对 eval 的调用,而除非可以同时解析待求值字符串中的所有引用,否则这是不可能做到的。要求做到这一点将过于严格(字符串可能来自用户输入,或取决于函数执行时才能确定的内容)。
虽然 Octave 通常从名为 file.m 的脚本文件中执行命令,但你可以使用 source 函数从任意文件执行命令。
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4