这一章在干嘛?
这是全书的地基:认识 MATLAB 这个软件、学会在命令窗口(Command Window)里跟它「对话」,掌握变量、赋值、运算符优先级、数据类型和真假判断。学完这章,你就能把 MATLAB 当成一个超强的「科学计算计算器」来用了——而后面 13 章,都是在这个计算器上盖楼。
1.1 初识 MATLAB
MATLAB 的名字来自 Matrix Laboratory(矩阵实验室)——记住这一点很重要:它生来就是为矩阵运算设计的,这和 C 语言「一切从字节和循环开始」的思路完全不同。在 C 里你要写三层 for 循环才能做的矩阵乘法,在 MATLAB 里一个 * 号就解决了。
它是一个集数值计算、图形绘制、编程开发环境于一体的软件包,还带各种工具箱(Toolbox,如信号处理、控制系统)。The MathWorks 公司每年发布两个版本,命名如 R2016a、R2016b。
启动 MATLAB 后,主窗口就是命令窗口(Command Window),你会看到一个提示符(prompt):
>>在 >> 后面输入任何命令或表达式,MATLAB 会立即给出结果——这种「一问一答」的交互方式,是它和 C 语言「先写完整个程序再编译运行」最大的区别。你可以把命令窗口当成一个可以验证任何数学疑问的草稿纸。
几个入门必备的求助命令:
| 命令 | 作用 |
|---|---|
demo | 打开官方示例浏览器 |
help 函数名 | 查看某函数的用法,如 help sin |
help | 列出所有帮助主题(很长) |
lookfor 关键词 | 按关键词搜索帮助(较慢) |
doc 函数名 | 在帮助浏览器中打开文档页 |
退出 MATLAB 在提示符后输入 quit 或 exit 即可。
如果你写过 C 语言,可以这样定位 MATLAB:C 是「通用型系统语言」,一切都要自己造轮子,写个矩阵乘法得手搓三层循环;MATLAB 是「领域专用型计算环境」,矩阵、三角函数、绘图全是内置能力,代价是运行慢、离了它的运行环境跑不起来。工程界的用法通常是两者配合:用 MATLAB 做算法原型和数值验证,验证通过后再用 C 移植到嵌入式设备上。所以学 MATLAB 时,重点不是背语法,而是培养「把问题翻译成矩阵运算」的思维——这恰恰是 C 语言练不出来的。
初学者最重要的一个习惯
遇到任何不认识的函数,第一反应不是上网搜,而是敲
help 函数名。MATLAB 的内置帮助是最快、最准的文档来源,养成这个习惯受益全书。
1.2 桌面环境:各个窗口都是干嘛的
默认布局(以 R2016a 为例)中,命令窗口周围还有几个窗口,先混个脸熟:
- 当前文件夹窗口(Current Folder):在命令窗口左侧。它显示的文件夹就是你的「工作目录」——脚本文件默认保存在这里。想运行一个 .m 文件,它必须在当前文件夹(或在搜索路径上),否则 MATLAB 找不到它。
- 工作区窗口(Workspace):在命令窗口右上方,实时显示当前所有变量及其值和类型。你每创建一个变量,这里就多一行——调试时盯住它,比打印语句还直观。双击某个变量还会打开变量编辑器(Variable Editor),可以像 Excel 一样查看和修改数组内容(到第 2 章处理矩阵时特别好使)。
- 命令历史窗口(Command History):右下方,记录你输入过的所有命令(包括上次会话的),双击可重新执行。
- 工具条(Toolstrip):顶部的 HOME / PLOTS / APPS 三个选项卡,集成了常用操作。
每个窗口右上角有下拉菜单,可以关闭、停靠(dock)、取消停靠(undock),布局完全自定义。想恢复默认布局,在 HOME 选项卡的 Layout 菜单里一键搞定。
常见坑:「Undefined function or variable」
十有八九不是你写错了函数,而是当前文件夹不对:你自己写的 .m 脚本不在当前文件夹里,MATLAB 就「看不见」它。运行脚本前先看一眼左侧当前文件夹窗口。
1.3 变量与赋值语句
1.3.1 赋值:= 不是「等于」
在 MATLAB 里存一个值,用赋值语句(assignment statement):
变量名 = 表达式
>> mynum = 6
mynum =
6读法很关键:= 是赋值运算符(assignment operator),不是数学上的相等。mynum = 6 应读作「把 6 放进 mynum」,而不是「mynum 等于 6」。这和 C 语言一致——但注意,MATLAB 声明变量不需要先写类型(不用 int mynum;),直接赋值即用,变量的类型由存进去的值自动决定。
变量名必须在左边,表达式在右边,反了会报错:
>> 6 = mynum
Error: The expression to the left of the equals sign
is not a valid target for an assignment.分号抑制输出:语句末尾加分号 ;,赋值照常执行但不回显结果。写脚本时几乎每行都以分号结尾,只在你想看结果时才省略它:
>> res = 9 - 2; % res 已被赋值为 7,但不显示
>>如果不写变量名,直接敲一个表达式,结果会自动存进默认变量 ans(answer 的缩写):
>> 6 + 3
ans =
9ans 会被下一次未赋值的表达式覆盖,所以别自己把结果寄托在 ans 上,更别拿 ans 当变量名。需要结果就老老实实存进命名变量。
另一个提效技巧:按 ↑ 方向键可以调回上一条命令,配合 ← 修改,避免重打长表达式;命令历史窗口里也可以选中命令右键重跑。比如你刚敲完 6 + 3 结果进了 ans,现在又想把它存进 result 变量——按 ↑ 调回来,再按 ← 移到行首补上 result = 即可,不用整条重打。这对「长表达式敲错一个数」的场景尤其救命。
变量可以被反复赋值覆盖,而且可以引用自己当前的值:
>> mynum = 3
mynum =
3
>> mynum = mynum + 1
mynum =
4mynum = mynum + 1 在数学上是矛盾方程,但在编程里天经地义:先算右边(取出 mynum 的 3,加 1 得 4),再放回 mynum。这叫增量(incrementing);减 1 就叫减量(decrementing)。第一次给变量赋值叫初始化(initializing)。
再来看一组完整的「变量生命周期」演示,请逐行跟着在命令窗口敲一遍,同时观察右侧工作区窗口的变化:
>> who % 刚打开时可能什么都没有
>> mynum = 3; % 创建变量,分号不回显
>> mynum + 5; % 结果 8 没存变量,进了 ans
>> who
您的变量为:
ans mynum
>> clear mynum % 只删 mynum
>> who
您的变量为:
ans给有 C 语言基础的同学:三个思维转换
- 不用声明类型:C 里要
double x = 3.5;,MATLAB 直接x = 3.5,类型跟着值走,还可以随时被另一种类型的值覆盖。- 没有 main 函数也能跑:命令窗口本身就是程序的「执行现场」,每敲一行立即执行一行,适合边试边学。
- 变量即工作区状态:只要不清空,变量在整个会话里都活着——这既是便利(随时查看中间结果),也是隐患(上次实验的旧变量可能悄悄污染这次的计算)。调试诡异问题时,先
clear一把再来。
1.3.2 变量命名规则
变量名属于标识符(identifier),规则如下:
- 必须以字母开头,后面只能是字母、数字、下划线(
value_1合法,my value不合法——不能有空格); - 长度有上限,用
namelengthmax可查询(超长部分会被截断); - 区分大小写:
mynum、MYNUM、Mynum是三个不同的变量(千万别这么干); - **保留字(reserved words / keywords)**不能用作变量名(如
if、end、while); - 内置函数名可以被覆盖当变量名,但强烈不要——见下面的坑。
常见坑:拿函数名当变量名
>> abs = 11 % abs 从此变成一个 double 变量 >> abs(-6) % 再想用绝对值函数? Subscript indices must either be real positive integers or logicals. >> clear abs % 删掉这个变量,函数才能"回来"这类 bug 特别隐蔽:报错信息完全不提「函数名被覆盖」。同理,永远别用
ans、pi、i当变量名。命名要见名知义(mnemonic):存半径就叫radius,别叫x2。
管理变量的常用命令:
| 命令 | 作用 |
|---|---|
who | 列出当前所有变量名 |
whos | 列出变量名 + 尺寸 + 字节数 + 类型 |
clear | 删除全部变量 |
clear 变量名 | 删除指定变量(多个用空格隔开) |
1.3.3 数据类型(类)
MATLAB 中每个变量都有类型,官方叫类(class)。常用的有:
| 类型 | 用途 |
|---|---|
double | 双精度浮点数,默认类型,不声明就是它 |
single | 单精度浮点数,省内存但精度低 |
int8 / int16 / int32 / int64 | 带符号整数,数字表示总位数 |
uint8 / uint16 / uint32 / uint64 | 无符号整数,只能存 0 和正数 |
char | 字符 / 字符串,用单引号括起来 |
logical | 真假值(true / false) |
int8 用 8 位(1 字节)存储,其中 1 位是符号位,所以范围是 ;uint8 不存符号,范围是 。位数为 的带符号整数范围是 ,无符号是 。
查类型用 class 函数:
>> num = 6 + 3;
>> class(num)
ans =
double为什么默认是 double?因为 MATLAB 的祖先是工程师写的数值计算库——工程计算几乎全是带小数点的实数,与其让用户在 float/double 之间纠结精度,不如统一用精度最高的 double(8 字节,约 15~16 位有效数字),牺牲一点内存换取「永远不会因为精度不够而算错」。这个默认值贯穿全书:你写的 3 其实是 double 的 3.0,除法 1/2 得 0.5 而不是 C 里的整数 0——MATLAB 的除法天生是实数除法,这让初学者少踩无数坑。
那什么时候才需要整数类型?答案是省内存的大批量数据:比如一张百万像素的灰度图,用 uint8 存每像素 1 字节,用 double 就要 8 字节,差 8 倍。日常做算术时不必操心,double 走天下。
1.4 数值表达式:运算符、格式与随机数
表达式由值、变量、运算符、内置函数和括号组成。来个开胃菜:
>> 2 * sin(1.4)
ans =
1.97091.4.1 format 命令与续行符
MATLAB 默认显示4 位小数(format short)。注意:format 只改变显示精度,不改变内部存储的值。想看更多位,切到 format long(15 位小数):
>> format long
>> 2 * sin(1.4)
ans =
1.970899459976920
>> format short % 切回默认
>> 2 * sin(1.4)
ans =
1.9709format loose / compact 则控制结果与命令之间是否留空行,纯观感问题。
表达式太长一行写不下时,用三个点 ...(续行符 / ellipsis)换行接着写:
>> 3 + 55 - 62 + 4 - 5 ...
+ 22 - 1
ans =
161.4.2 运算符与优先级
常见算术运算符:
| 运算符 | 含义 | 示例 |
|---|---|---|
+ - | 加、减(- 也可作一元取负) | 5-2 |
* | 乘 | 2*3 |
/ | 除:除以 | 10/5 = 2 |
\ | 除:除入(左除) | 5\10 = 2 |
^ | 乘方 | 5^2 = 25 |
\ 是 MATLAB 特色的「反向除法」:a\b 意思是 。现在只需知道它存在,到学解线性方程组(A\b 即解 )时它才是主角。
大数可用科学计数法,用 e 表示 的幂:
>> 2 * 10^4
ans =
20000
>> 2e4
ans =
20000优先级规则(从高到低):
( )括号(内层括号先算)^乘方-一元取负*/\乘除+-加减
同一优先级内从左到右依次计算(这叫结合性,associativity)。括号既能改变优先级,也能让表达式更易读:
>> 4 + 5 * 3
ans =
19
>> (4 + 5) * 3
ans =
27常见坑:
-5^2不等于 25乘方优先级高于一元负号,所以
-5^2是 ;想算 必须写(-5)^2。C 语言里同样的表达式也有这个歧义,但 MATLAB 新手踩这个坑的比例格外高。动手验证:1\2是几?10 - 6/2呢?先心算再上机。
练一练(原书 Practice 1.1):先心算,再上机验证。
| 表达式 | 心算过程 | 结果 |
|---|---|---|
1\2 | 2 | |
-5 ^ 2 | ,负号最后才生效 | -25 |
(-5) ^ 2 | 先把 -5 括起来再乘方 | 25 |
10 - 6/2 | 先 ,再 | 7 |
5 * 4/2 * 3 | 同级从左到右: | 30 |
全对说明优先级规则已经过关;错任何一个,回到上面的优先级表再读一遍。
顺便一提,所有运算符都有对应的「函数形式」:2 + 5 等价于 plus(2,5),还有 minus、times 等。日常没人这么写,但读懂它有助于理解「运算符本质上就是函数」这个编程共识。
1.4.3 内置函数与 help
MATLAB 自带海量函数。调用格式是「函数名(参数)」,函数计算后返回结果:
>> abs(-4) % 求绝对值,-4 是传入的参数
ans =
4
>> plus(2,5) % 运算符都有函数形式:+ 就是 plus
ans =
7查函数清单:help elfun 列出所有初等数学函数(三角、指数、取整、求余等)。输入函数名时按 Tab 键会弹出补全列表(tab completion),拼错了 MATLAB 还会提示「Did you mean: …」。
1.4.4 常量
有一类值天生不变,MATLAB 用「函数」的形式提供它们:
| 名称 | 值 |
|---|---|
pi | 圆周率 |
i、j | 虚数单位 |
inf | 无穷大 (如 1/0) |
NaN | Not a Number,非数(如 0/0 的结果) |
inf 和 NaN 不只是数学概念,它们是信号里的异常标记:传感器读数丢失时常见 NaN 占位,inf 可能意味着除以了零。后面学到 isnan、isinf 这类检测函数时你会频繁遇到它们。另外 pi、i 名义上是「函数」,被赋值覆盖后同样会失效——pi = 3.14 这种代码能跑,但属于自断后路。
1.4.5 随机数:rand 家族
写程序时数据还没到位?用随机数先把程序跑起来;仿真(simulation)更是离不开它。
先说原理:计算机生成的「随机数」其实是伪随机数(pseudorandom)——从一个**种子(seed)**出发,按固定算法递推下一个数。所以只要种子相同,产生的序列就完全相同。MATLAB 启动时用固定值初始化一个「全局随机数流」,所有随机函数都从这条流里取数。
>> rand % (0,1) 开区间内均匀分布的随机实数
ans =
0.8147
>> rand
ans =
0.9058rng 函数控制种子:
>> rng('shuffle') % 用当前时钟做种子,每次启动都不同
>> rng(42) % 固定整数种子:结果可复现
>> rng('default') % 恢复默认种子为什么要「固定种子」?
调试含随机数的程序时,每次运行结果都不同会让人发疯。
rng(42)让随机序列可复现——等程序调通了,再换rng('shuffle')。这是仿真和算法开发的标准做法。
rand 只给 区间的数,通过线性变换可以推广到任意区间:
>> rand * 10 % (0,10) 内的随机实数
>> low = 3; high = 5;
>> rand * (high - low) + low % (3,5) 内的随机实数要随机整数用 randi,它更直接:
>> randi(4) % 1~4(含两端)的随机整数
>> randi([3, 6]) % 3~6(含两端)的随机整数练一练(原书 Practice 1.2):写出下列随机数的表达式,再上机各跑几次确认范围正确。
- (0, 1) 内的随机实数 →
rand - (0, 100) 内的随机实数 →
rand * 100 - (20, 35) 内的随机实数 →
rand * (35 - 20) + 20 - 1~100(含两端)的随机整数 →
randi(100) - 20~35(含两端)的随机整数 →
randi([20, 35])
一个实用小例子——模拟掷骰子:
>> rng(1) % 固定种子,结果可复现
>> dice = randi([1,6], 1, 10) % 一次掷 10 颗骰子
dice =
6 3 5 3 4 3 6 5 1 3randi 还能一次生成一整行随机整数(第三个用法在 2.1 节造随机矩阵时还会见到)。记住区间口诀:rand 开区间,randi 闭区间——rand 永远取不到 0 和 1,randi([a,b]) 两端都能取到。
另外 randn 生成正态分布(均值 0、方差 1)的随机实数,做信号仿真时常用。
常见坑:想当然的 round(rand*10)
round(rand*10)确实能出 0~10 的整数,但两端出现的概率只有中间的一半(分布不均匀)。要均匀分布的随机整数,直接用randi。
1.5 字符与字符串
字符用单引号括起来,字符串就是一串字符:
>> myword = 'hello'
myword =
hello
>> var = 3 % 数字 3
>> var = '3' % 字符 '3'——注意显示时会缩进,类型完全不同计算机里字符靠字符编码(character encoding)存储:每个字符对应一个整数。最经典的是 ASCII 编码,128 个字符对应整数 0~127,且字母按序排列(‘a’ 是 97,‘b’ 是 98……)。MATLAB 用的编码前 128 个与 ASCII 一致。所以带引号的 '3' 是编码表里的一个字符(值为 51),不带引号的 3 才是数字——两者的差距在 1.7 节会看得更清楚。
常见坑:单引号 vs 双引号
和 C / Python 不同,传统 MATLAB 字符串只用单引号
'hello'。写成'..."hello"...'风格的双引号在新版本里会被解释成另一种类型(string 数组),初学阶段请统一用单引号,避免混乱。
1.6 关系表达式与逻辑运算
1.6.1 关系运算符
凡是结果为「真 / 假」的表达式叫关系表达式(relational expression),也叫布尔 / 逻辑表达式。MATLAB 的关系运算符:
| 运算符 | 含义 |
|---|---|
> < | 大于、小于 |
>= <= | 大于等于、小于等于 |
== | 等于(两个等号!) |
~= | 不等于(不是 !=,和 C 不同) |
真为逻辑 1,假为逻辑 0,结果的类型是 logical 而非 double:
>> 3 < 5
ans =
logical
1
>> 2 > 9
ans =
logical
0
>> true % 内置的 true 即 logical(1),false 即 logical(0)
ans =
logical
1逻辑值还能参与数学运算(1 就是 1,0 就是 0):
>> logresult = 5 < 7;
>> logresult + 3
ans =
4字符比较按编码值进行:'a' < 'c' 为真,因为 ‘a’(97) 排在 ‘c’(99) 前面。
1.6.2 逻辑运算符与真值表
| 运算符 | 含义 | 口诀 |
|---|---|---|
&& | 与(and) | 两个都真才真 |
|| | 或(or) | 有一个真就真 |
~ | 非(not,一元) | 真假互换 |
xor(a,b) | 异或 | 恰好一个真才真 |
真值表(Table 1.1):
| x | y | ~x | x || y | x && y | xor(x,y) |
|---|---|---|---|---|---|
| true | true | false | true | true | false |
| true | false | false | true | false | true |
| false | false | true | false | false | false |
&& 和 || 是短路运算符(short-circuit operators):如果看第一个操作数就能定生死,第二个根本不算。比如 2 < 4 || 'a' == 'c' 中前半已为真,后半直接跳过——这在后面章节还能用来「先检查再使用」防止报错。xor(3 < 5, 'a' > 'c') 中恰好一个为真,结果为 1;而 xor(3 < 5, 'a' < 'c') 两个都真,结果为 0。逻辑运算符满足交换律:x || y 等价于 y || x。
练一练(原书 Practice 1.3):先遮住右列心算,再上机验证。
| 表达式 | 答案 | 解析 |
|---|---|---|
3 == 5 + 2 | 0 | 加法优先: 为假 |
10 > 5 + 2 | 1 | 为真 |
(10 > 5) + 2 | 3 | 括号得 1,再加 2 |
'b' < 'a' + 1 | 0 | 'a'+1 是 98,'b' 也是 98, 为假 |
10 > 5 > 2 | 0 | 从左到右: 得 1, 为假 |
xor(5 < 6, 8 > 4) | 0 | 两个都真,异或为假 |
每个「直觉陷阱」都值得体会:关系运算符优先级低于算术运算符,以及连比式 10 > 5 > 2 为什么靠不住——这两个坑贯穿全书。
完整优先级表(从高到低,务必收藏):
( ) 括号
^ 乘方
- ~ 一元取负、非
* / \ 乘除
+ - 加减
< <= > >= == ~= 关系
&& 与
|| 或
= 赋值(最低)
常见坑:
3 < x < 5是个永远为真的废话数学里「3 < x < 5」写作条件天经地义,但在 MATLAB(以及 C)里它从左到右计算:先算
3 < x得 0 或 1,再算0 < 5或1 < 5——永远为真,不管 x 是多少!正确的写法是3 < x && x < 5。这是初学者最经典的逻辑错误,编译器不会报错,只会让你的程序悄悄出错。另一个隐藏坑:浮点数别用
==判等。由于舍入误差(roundoff error),cos(pi/2)理论上是 0,实际是6.1232e-17,于是cos(pi/2) == 0返回 0(假)。判断浮点相等应比较差的绝对值是否足够小。
1.7 类型的范围与类型转换
每种整数类型能存的数有范围(range),用 intmin / intmax 查询(参数是带引号的类型名字符串):
>> intmin('int8')
ans =
-128
>> intmax('int8')
ans =
127把值从一种类型转成另一种,叫类型转换(type casting)——转换函数名和类型名相同:
>> num = 6 + 3; % double
>> numi = int32(num); % 转成 int32
>> whos
Name Size Bytes Class
num 1x1 8 double
numi 1x1 4 int32whos 能看到 int32 只占 4 字节(32 位 = 4 × 8 位),而 double 占 8 字节。用整数类型省内存,是它最重要的用途——存一百万个传感器读数时,int8 和 double 的内存差 8 倍。
超出范围会怎样?MATLAB 做饱和运算(saturation arithmetic):超上限就给上限,超下限就给下限,不报错也不回绕:
>> int8(200)
ans =
127
>> int8(-130)
ans =
-128还有个 cast 函数,能用 'like' 选项把变量转成「和另一个变量相同的类型」:
>> a = uint16(43);
>> b = 11;
>> b = cast(b, 'like', a) % b 现在也是 uint16练一练:不查表,用数学公式推出 int16 和 uint16 的范围,再用 intmin / intmax 验证。
int16:16 位,1 位符号 + 15 位数值,范围 ,即 -32768 ~ 32767uint16:无符号,16 位全用,范围 ,即 0 ~ 65535
这个「位数的幂」推法值得内化——嵌入式背景的同学会发现它和 C 里 INT16_MIN / UINT16_MAX 的定义一模一样,只是 MATLAB 提供了运行时查询函数,不用背头文件里的常量。
字符与数值互转
数值函数也能用在字符上,得到其编码值;反向转换用 char:
>> double('a')
ans =
97
>> char(97)
ans =
a
>> char('abcd' + 1) % 整串整体"平移"
ans =
bcde因为字母按序编码,「字符 + 1 = 下一个字符」:
>> 'a' + 2 % 字符参与算术,自动变数值
ans =
99注意上面这行的细节:'a' + 2 的结果是数值 99 而不是字符——字符一旦参与算术,就自动「降维」成它的编码值参与运算。想要回字符,用 char 包一层:char('a' + 2) 得 'c'。这一对互转在后面处理字符串加密、大小写转换(char('A' + 32) 会得到什么?上机试试)时会反复出现。
前 128 个字符与标准 ASCII 相同;128~65535 的字符取决于计算机的区域设置(locale)(如 en_US)。
'x' 和 x 的本质区别是什么?
不带引号的
x是一个变量名,MATLAB 会去工作区找它的值(没定义就报错 Undefined);带引号的'x'是字符常量,值就是编码表里第 120 号字符。同理,5是数字 5,'5'是编码值为 53 的字符——两者类型不同、能参与的运算也不同。
1.8 常用内置数值函数
取整与符号函数
elfun 帮助主题下有一组天天要用的函数:
| 函数 | 作用 |
|---|---|
fix | 朝零取整(抹掉小数部分) |
floor | 朝负无穷取整(向下) |
ceil | 朝正无穷取整(向上) |
round | 四舍五入(可指定位数:round(pi,3) → 3.142) |
sign | 正数返回 1,零返回 0,负数返回 -1 |
rem(a,b) | a 除以 b 的余数 |
mod(a,b) | 模运算(与 rem 的区别在负数行为) |
取整四兄弟对负数的行为差异最能暴露理解漏洞,务必对比记忆:
| 表达式 | fix | floor | ceil | round |
|---|---|---|---|---|
f(3.4) | 3 | 3 | 4 | 3 |
f(3.5) | 3 | 3 | 4 | 4 |
f(-3.4) | -3 | -4 | -3 | -3 |
f(-3.5) | -3 | -4 | -3 | -4 |
一句话总结:fix 朝零砍(「截断」);floor 永远向数轴左端走;ceil 永远向右走;round 四舍五入(负 0.5 同样远离零)。原书练习特意让你验证「fix(-3.2) 等于 floor(-3.2) 吗」——答案是不等(-3 与 -4),正数时它们才一致。
rem 与 mod 都能取余数,但参数含义不同:rem(a,b) 按「a 除以 b」取余,rem(13,5) 是 3:
>> rem(13, 5) % 13 ÷ 5 = 2 余 3
ans =
3
>> sign(-5)
ans =
-1sign 在信号处理里是把波形「削成方波」的利器,2.4 节找过零点时就会用到它。
常见坑:rem 的参数顺序
rem(a,b)是「b 除入 a 取余」。写反成rem(5,13),结果是 5(13 除不入 5,余数就是 5 本身)——不报错,只会悄悄给出错误答案。测函数时一定要用正数、负数、小数多种参数都试一遍。
幂、根与对数
sqrt(x):平方根;nthroot(x, n):n 次方根(nthroot(64,3)= 4)exp(n):。没有内置常量 e,要 e 就写exp(1)log(x):自然对数 (注意!不是以 10 为底,和很多计算器不同)log2(x)、log10(x):以 2、10 为底的对数deg2rad/rad2deg:角度与弧度互转(R2015b 引入)
>> exp(1)
ans =
2.7183
>> deg2rad(180)
ans =
3.1416对数复习一下:若 ,则 。常用底数三个: 叫常用对数(对应 log10), 是计算领域常客(对应 log2), 叫自然对数(对应 log)。所以 给出 log10(100) 为 2, 给出 log2(32) 为 5。
常见坑:两个 e 完全是两回事
科学计数法里的
e(如2e4表示 )和数学常数 只是碰巧同字母。2e4是数值写法,exp(1)才是常数 e。还有:MATLAB 里没有logE或ln函数,自然对数就叫log——从 C 的math.h过来的同学注意,这点两者恰好一致。
三角函数默认用弧度
sin、cos等默认吃弧度(和数学课本一致)。拿惯了角度的话,要么先deg2rad转换,要么直接用度数版函数sind、cosd、tand。
本章速查表
写代码时最常回头翻的内容,一表收齐:
| 想做什么 | 用什么 |
|---|---|
| 查变量列表 / 详情 | who / whos |
| 删变量 | clear 名字 |
| 查类型 / 查整数范围 | class(x) / intmin('int8')、intmax('int8') |
| 多显示几位小数 | format long(只影响显示) |
| 长表达式换行 | 行尾加 ... |
| 求帮助 | help 函数名、doc 函数名 |
| 随机实数 / 随机整数 | rand*(high-low)+low / randi([a,b]) |
| 固定随机序列 | rng(整数) |
| 字符 ↔ 编码值 | char(97) / double('a') |
| 取整 / 取余 / 取符号 | fix floor ceil round / rem / sign |
实战:把本章知识点串成一个 30 秒小实验——生成 5 个 20~50 的随机整数存入变量,查看它的类型,再统计其中大于 40 的个数:
>> rng('shuffle') % 用时钟做种子
>> data = randi([20, 50], 1, 5)
data =
35 42 27 50 21
>> whos data
Name Size Bytes Class
data 1x5 8 double
>> sum(data > 40) % 有几个数大于 40?
ans =
2短短五行用到了:rng 种子、randi 区间、whos 查类型,甚至预演了第 2 章的逻辑索引求和——这就是本章所有知识点的「合体技」。
本章通关标准:
- 能不看书记住:赋值
=与判等==的区别、分号抑制输出、单引号才是字符串,并且能解释3 < x < 5为什么永远为真。- 能徒手心算
4 + 5*3、-5^2、10 - 6/2、1\2的结果,并上机验证全对。- 会用
help、whos、class、format long、rng这五个工具自查任何疑惑,能生成 (3,7) 区间的随机实数和 20~50 的随机整数。
1.
mynum = mynum + 1在数学上不成立,为什么在 MATLAB 里完全合法?
=是赋值不是等式:先计算右边的表达式mynum + 1(取出 mynum 当前的值加 1),再把结果存回 mynum。所以这是「变量自增 1」的标准写法,C 语言里同样如此。
2.
who和whos有什么区别?
who只列变量名;whos还显示每个变量的尺寸(Size)、占用字节数(Bytes)和类型(Class)。排查「这个变量到底是什么类型、占了多少内存」时用whos。
3. 为什么
abs = 11之后abs(-6)会报错?变量名覆盖了内置函数名。MATLAB 按名字查找时优先找到你新建的 double 变量
abs,把它当成数组去做下标索引,于是报错。执行clear abs删除变量后函数恢复可用。教训:不要用内置函数名做变量名。
4.
format long会改变计算精度吗?不会。它只改变显示的小数位数(15 位),MATLAB 内部始终以 double 双精度存储和计算。要真正控制计算精度需要用
single等类型转换。
5. 写出「x 在 3 到 5 之间(不含端点)」的正确 MATLAB 条件表达式。
3 < x && x < 5。写成3 < x < 5是错的:它先算3 < x得 0 或 1,而 0 和 1 都小于 5,所以无论 x 取何值结果恒为真。