Matlab gui设计学习手记(第2版)

Page 1

北 京


MATLAB 开发实例系列图书

MATLABGUI设计学习手记

编著

空 航

罗华飞

(第 2 版 )


内 容 简 介 本书在第 1 版的基础上,完善了全 书 知 识 结 构,突 出 了 GUI设 计 重 点,对 读 者 经 常 遇 到 的 38

个问题作了透彻的解答,并提炼 出 13 个 专 题 作 了 详 尽 的 介 绍,最 后 配 以 长 达 17. 5小时的免费视

频教程对书中专题和答疑部分进行了全面细致的讲解。本书由浅入深、循序渐进地介绍了 GUI设

计的基础知识和技巧,旨在使读者在较短时间内熟练掌握 GUI设计的精要所在。

本书首先介绍了 GUI设计的预备知识;然后详细讲 解 了 GUI对 象 的 属 性 及 两 种 创 建 GUI的

方法:采用函数创建和采用 GUIDE 创建;之后深入讲解了 Ac t i veX 控件、定 时 器、串 口 及 mc c编 译

的相关知识;最后,书中给出两个 综 合 实 例,供 读 者 研 究 学 习。 书 中 穿 插 了 大 量 的 图 表 和 例 题,方 便读者边查边练。

本书适合需要短时间内迅速掌握 MATLABGUI设计的初 学 者,也 可 作 为 相 关 专 业 师 生 或 工

程开发人员的参考手册。

Ⅲ.① 算法语言—程序设计

Ⅳ.①TP312

Ⅱ.① 罗…

I SBN978 7 5124 0292 8 Ⅰ.①M…

MATLABGUI设计学习手记/罗华飞编著 . 2版 . - 北京:北京航空航天大学出版社, 2011. 2

图书在版编目( CIP)数据

版权所有,侵权必究。

空 航

中国版本图书馆 CIP 数据核字( 2010)第 247035 号

MATLABGUI设计学习手记(第 2 版) 罗华飞 编著 责任编辑

陈守平

* 北京航空航天大学出版社出版发行 //www. 北京市海淀区学院路 37 号(邮编 100191) h t t bua ap r e s s. c om. cn p: 发行部电话:( 010) 82317024 传真:( 010) 82328026

读者信箱:bhp r e s s@263. ne t 有限公司印装

邮购电话:( 010) 82316936

各地书店经销

*

开本: 787×1092 1/16 印张: 36. 75 字数: 941 千字

2011 年 2 月第 1 版 2011 年 2 月第 1 次印刷

印数: 6000 册

I SBN978 7 5124 0292 8 定价: 69. 80 元 (含光盘)


言 (第 2 版 )

本书是《MATLAB GUI设计学习手记》的修订版。修订版在第 1 版的基础上,做了如下 改进: ① 修正了第 1 版所有的已知错误,并删除了部分不够经典的例题。 ② 增加了专题分析、答疑精选等内容。书中包含有大量知识点和经典例题,并随书赠送1

张视频教学光盘,内附所有 源 代 码(均 在 MATLAB2010b 环 境 下 运 行 通 过),以 及 17. 5小时 的视频讲座(本人亲自主讲,手把手教你设计 GUI),另有书中所涉及基础知识的 33 小时视频

讲座,读者可到 MATLAB 中文论坛免费下载。保证全书讲解透彻、内容由浅入深。 ③ 规 范 了 代 码 的 结 构、可 读 性,优 化 了 代 码 的 效 率。 添 加 了 大 量 的 注 释,注 释 量 超 过 50% 。

本书共分 11 章,每章(第 3 章和最后 3 章除外)依次由以下 4 节内容组成:知识点归纳、重

难点讲解、专题分析和精选答疑。知识点归纳详细全面地介绍了本章的内容与知识点,容易理

解错的知识点用【注意】标明,个别地方配以典型例题讲解;重难点讲解简要概括了本章的重点

和难点,便于读者重点掌握;专题分析系统全面地对 某 个 知 识 点 进 行 专 门 讲 解,达 到 一 针 见 血

的目的;精选答疑筛选出读者在学习过程中经常遇到的问题,配合习题进行解答。本书包含大

量的例题,建议读者先自行将例题完成,然后参考例题解析,并配合本书附赠的视频教程,分析 比较程序代码。这样边学边练,可以进一步牢固地掌握 GUI设计技巧和方法。

空 航

第 1 章: GUI设计预备知识。本章 主 要 介 绍 了 MATLAB 的 基 本 程 序 元 素、几 种 GUI设 计中经常使用的数据类型和矩阵操作函数,以及程序设计的 5 种句型( f o r、 wh i l e 循环结构, i f、

swi t ch 条件分支结构和t r a t ch 结构)。之后以专题形式,分别讲解了 MATLAB 的编程风 y…c 格、代码优化以及基于 MATLAB7. 11 的 M 文件编程小技巧。

/O。本章主要介绍了文件I /O 操作的相关函数,分为高级文件I /O 和低级 第 2 章:文件I

/O 两 部 分。 高 级 文 件 I /O 介 绍 了 读 写 MAT 或 ASCI 文件I I 文 件、读 写 TXT 文 件、读 写 /O 介 绍 了 读 写 二 进 Exc e l文件、读写图像文件及读写音频文件的方 法 及 相 关 函 数;低 级 文 件 I

制文件和读写文本文件的方法及相关函数。之后以 专 题 形 式,全 面 讲 解 了 读 写 文 本 文 件 的 技 巧和方法。 第 3 章:二维绘图简介。本章主要介绍了与 GUI设计密切相关的线性二维绘图及其相关

函数、绘图工具函数和绘图注释函数。二维绘图函数常用于 GUI设计中的数据可视化模块。

第 4 章:句柄图形系统。本章主要介绍了句柄图形对象的概念及其操作函数,各种句柄图

形对象的创建方法、属性及含义。之 后 以 专 题 形 式,全 面 讲 解 了 超 文 本 标 记 语 言 (HTML)在

MATLAB 中的应用、表格设计及坐标轴设计。本章是 GUI设计的重点内容,需要熟练掌握。 第 5 章:预定义对话框。本章介绍了 MATLAB 环境下可调用的所有预定义对话框,包括 公共对话框和 MATLAB 自 定 义 的 对 话 框。 之 后 以 专 题 形 式,详 细 介 绍 了 预 定 义 对 话 框 在

GUI设计中的应用。预定义对话框使得 GUI设计更加直观、灵活。 第 6 章:采 用 GUIDE 建 立 GUI。本 章 首 先 介 绍 了 采 用 GUIDE 建 立 GUI的 方 法,GUI 的 M 文件构成、回调函数的分类 以 及 回 调 函 数 的 编 写 方 法,然 后 举 例 介 绍 了 GUIDE 环 境 下


GUI组件的使用方法。最后以专题形式,系统讲解了 GUI对 象 之 间 的 数 据 传 递 方 法,及 回 调 函数的应用实例。通过本章的学习,读 者 可 以 设 计 出 精 美 的 GUI界 面,实 现 复 杂 的 功 能。 本 章是 GUI设计的重点内容,需要熟练掌握。

第 7 章: Ac t i veX 控件。本章首先详细介绍 了 7 大 类 的 Ac t i veX 控 件: LED 状 态 显 示、七 段 LED 数码显示、表盘显示、线性测量、滑动条、进 度 条 和 选 项 卡,然 后 以 专 题 形 式,详 细 讲 解 了选项卡( TabS t r i p)控件在 GUI设 计 中 的 应 用。 熟 练 掌 握 这 些 控 件,可 以 使 GUI的 界 面 更 加美观。本章是 GUI设计的精华之处,只 有 掌 握 了 Ac t i veX 控 件 的 设 计,才 能 设 计 出 精 美 的 软件界面。

第 8 章:定时器。本章首先介绍了 GUI设计中定时器的使用方法,然后以专题形式,举例

讲解了定时器在 GUI 设 计 中 的 应 用。 熟 练 掌 握 定 时 器,可 以 实 现 更 复 杂、实 时 性 高 的 GUI 设计。

第 9 章:串口编程。本章首先介绍了 GUI设计中串口的使用方法,然后以专题形式,详细

讲解了串口在 GUI设计中的应用,并给出了一个串口通信助手的设计实例。

第 10 章: mc c编译。本章简要介绍了 GUI编译为独立可执行文件的方法、 mc c编译的局

限性和 P 文件的使用方法。通过本章的学习,读者可以轻松编译带有 Ac t i veX 控件的 GUI为

EXE 格式文件。 第 11 章:综合实例。通过详细讲解密码登录框和科学计算器这两个实例,使读者深入、熟

项目,设计出精美、稳定可靠的 GUI。

练地掌握采用 MATLABGUI进行工 程 项 目 设 计 的 精 髓。 每 个 实 例 都 有 详 细 的 构 思 和 源 程 序,源程序包含详细的注释说明。通过 本 章 的 练 习,读 者 可 以 独 立 完 成 复 杂 的 GUI设 计 工 程 最后,附录部分列出了常用的 GUI设计相关函数,供读者参考查询。

空 航

本书在编写过程中,参考了大量的网络资料,也得到 了 ma t h、 l t h、 make su r e 5、 l skyp、 yqma

谢中华等很多论坛上朋友的热心帮助,没有他们的帮助,本书会缺少很多闪光点。感谢 MAT-

LAB 中文论坛提供的珍贵资源! 在此我还要特别感谢以下这些朋友:陈德芝、陈华、龙士斌、陈红玲、高文秀、陈伟、王欢、王

修兵、王倩、余泽文、江礼元、苏秀华、江俊、王万寿、姜明惠、李文光、刘建军、聂艳、王修珍、刘德 明、刘天鹅、王家宝,他们在本书的编写过程中,不遗余力地协助我顺利完成了本书。 另外,我要特别感谢一下我的妻子刘琴,创作 本 书 的 过 程 中,她 在 背 后 给 了 我 无 微 不 至 的 照顾和鼓励。

//www. 同时,北京航空航天大学出版社联合 MATLAB 中文论坛( h t t i l ovema t l ab. cn) p: //b 为本书设立了在线交流版块,作者也开通了新浪博客( h t t l og. s i na. c om. cn/ma t l abgu i), p: 与读者在线交流,有问必答! 作者会第一时间在 MATLAB 中文论坛和新浪博客上勘误,也会 根据读者要求上传更多案例和相关资料。希望这本不断“成长”的书能最大限度地解决您在学 习、研究、工作中遇到的 MATLABGUI相关问题。 由于作者水平有限,加之时间仓促,书中难 免 有 不 足 与 疏 忽 之 处,敬 请 读 者 批 评 指 正。本

//www. 书勘误网址: h t t i l ovema t l ab. cn/ t hr e ad 112739 1 1. h tml。 p:

罗华飞 2010 年 12 月


目 第1章

GUI设计预备知识

视频教学:3 小时

…………………………………………………………………… 1

1. 1 知识点归纳 ……………………………………………………………………………… 1

1. 1. 1 基本程序元素 ……………………………………………………………………… 1 1. 1. 2 数据类型 …………………………………………………………………………… 7 1. 1. 3 矩阵操作 …………………………………………………………………………… 36

1. 1. 4 程序设计 …………………………………………………………………………… 45 1. 2 重难点讲解 ……………………………………………………………………………… 56

1. 2. 1 矩阵、向量、标量与数组 …………………………………………………………… 56 1. 2. 2 数据类型转换 ……………………………………………………………………… 57 1. 3 专题分析 ………………………………………………………………………………… 60

专题 1 编程风格 ………………………………………………………………………… 60 专题 2 代码优化 ………………………………………………………………………… 64

专题 3 M 文件编程小技巧 ……………………………………………………………… 68

1. 4 精选答疑 ………………………………………………………………………………… 75 问题 1 单元数组占用的内存空间如何计算 …………………………………………… 75

第2章

如何给数组元素排序 …………………………………………………………… 83 /O ……………………………………………………………………………… 86 文件 I

问题 5

如何查找或删除数据中满足条件的元素 ……………………………………… 80

问题 4

空 航

问题 2 如何生成指定格式的常矩阵、字符串 …………………………………………… 76 问题 3 如何生成随机矩阵 ……………………………………………………………… 79

视频教学:1. 5 小时

2. 1 知识点归纳 ……………………………………………………………………………… 86 /O 操作 ……………………………………………………………… 86 2. 1. 1 高级文件I /O 操作 ……………………………………………………………… 103 2. 1. 2 低级文件I

2. 2 重难点讲解 …………………………………………………………………………… 117

2. 2. 1 二进制文件与文本文件 ………………………………………………………… 117

2. 2. 2 spr i n t f与f i n t f函数 …………………………………………………………… 118 pr 2. 2. 3 f s c an f与t ex t s c an 函数 ………………………………………………………… 119 2. 2. 4 Exc e l文件操作 ………………………………………………………………… 119

2. 2. 5 图像数据的操作 ………………………………………………………………… 119 /O 操作 ……………………………………………………………… 120 2. 2. 6 低级文件I 2. 3 专题分析 ……………………………………………………………………………… 120 专题 4 MATLAB 读写文本文件 ……………………………………………………… 120 2. 4 精选答疑 ……………………………………………………………………………… 130


问题 6 如何提取 Exc e l文件中的数据信息 …………………………………………… 130

问题 7 如何由图像生成字符矩阵 ……………………………………………………… 133

问题 8 如何循环播放 WAV 音乐,并可以倍速/慢速播放、暂停/继续播放和停止播放 …………………………………………………………………………………… 136

问题 9 如何读取文本和数值混合的文件中的数据 …………………………………… 138

问题 10 如何将十六进制数转换为f l oa t值 …………………………………………… 139 二维绘图简介 ………………………………………………………………………… 140

第3章

视频教学:0. 25 小时

3. 1 知识点归纳 …………………………………………………………………………… 140

3. 1. 1 常用的二维绘图函数 …………………………………………………………… 140

3. 1. 2 绘图工具 ………………………………………………………………………… 147 3. 1. 3 绘图注释 ………………………………………………………………………… 149 3. 2 重难点讲解 …………………………………………………………………………… 159

3. 2. 1 二维绘图的相关函数 …………………………………………………………… 159

3. 2. 2 Tex 字符 ………………………………………………………………………… 160 3. 3 精选答疑 ……………………………………………………………………………… 161 问题 11 如何绘制几何曲线,例如矩形、圆、椭圆、双曲线等 ………………………… 161

问题 12 如何绘制数据的统计图 ……………………………………………………… 162 问题 13 如何绘制特殊的字符、表达式 ………………………………………………… 163

句柄图形系统 ………………………………………………………………………… 165

空 航

第4章

问题 14 如何绘制网格图 ……………………………………………………………… 163 视频教学:4. 5 小时

4. 1 知识点归纳 …………………………………………………………………………… 165

4. 1. 1 句柄图形对象 …………………………………………………………………… 166 4. 1. 2 句柄图形对象的基本操作 ……………………………………………………… 167

4. 1. 3 句柄图形对象的基本属性 ……………………………………………………… 177

4. 1. 4 根对象 …………………………………………………………………………… 181

4. 1. 5 图形窗口对象 …………………………………………………………………… 185 4. 1. 6 坐标轴对象 ……………………………………………………………………… 196

4. 1. 7 核心图形对象 …………………………………………………………………… 203

4. 1. 8 u i con t r o l对象 …………………………………………………………………… 226 4. 1. 9 hgg r oup 对象 …………………………………………………………………… 231 4. 1. 10 按钮组与面板 …………………………………………………………………… 234 4. 1. 11 自定义菜单与右键菜单 ………………………………………………………… 237 4. 1. 12 工具栏与工具栏按钮 …………………………………………………………… 245 4. 1. 13 u i t ab l e对象 …………………………………………………………………… 254

4. 2 重难点分析 …………………………………………………………………………… 265 4. 2. 1 句柄式图形对象的常用函数总结 ……………………………………………… 265 4. 2. 2 F i r e对象的几个重要属性 …………………………………………………… 266 gu


4. 2. 3 Axe s对象的几个重要属性 ……………………………………………………… 267 4. 2. 4 L i ne对象的几个重要属性 ……………………………………………………… 268 4. 2. 5 t ex t对象的几个重要属性 ……………………………………………………… 268

4. 2. 6 u i t ab l e对象的几个重要属性 …………………………………………………… 269 4. 2. 7 u i con t r o l对象中的t ex t控件与核心图形对象中的t ex t对象的比较 ………… 269 4. 2. 8 对象的 Tag 值与句柄值的概念比较(对 GUIDE 创建的 GUI而言)………… 270

4. 2. 9 u imenu 与 u i c on t ex tmenu 对象 ………………………………………………… 270 4. 3 专题分析 ……………………………………………………………………………… 270 专题 5 超文本标记语言(HTML)在 MATLAB 中的应用 …………………………… 270 专题 6 表格设计 ………………………………………………………………………… 283 专题 7 坐标轴设计 ……………………………………………………………………… 287

4. 4 精彩答疑 ……………………………………………………………………………… 292 问题 15 如何创建满足要求的l i ne对象 ……………………………………………… 292 问题 16 如何创建动态的 GUI对象 …………………………………………………… 293

问题 17 如何为窗口设计背景图片 …………………………………………………… 295 问题 18 如何定制窗口的菜单 ………………………………………………………… 296

问题 19 如何设计窗口菜单并编写回调函数 ………………………………………… 297 问题 20 如何采用 UI控件实现简易的时钟 …………………………………………… 298

问题 21 如何实现文字的水平循环滚动效果 ………………………………………… 300 问题 22 如何构造和使用 hgg r oup 对象 ……………………………………………… 303

空 航

问题 23 如何使窗口最大化、最小化、置顶和居中,如何在窗口中更换图标 ………… 305 问题 24 怎样利用 Ui t ab l e对象在列名、行名或单元格中输入上下标和希腊字母 … 306

预定义对话框 ………………………………………………………………………… 310

视频教学:1. 5 小时

第5章

问题 25 如何更改菜单项的字体大小,如何设置菜单项的字体颜色 ………………… 307 问题 26 如何逐个输出坐标轴内的图形到单独的图片中 …………………………… 308

5. 1 知识点归纳 …………………………………………………………………………… 310 5. 1. 1 文件打开对话框( u i t f i l e)……………………………………………………… 311 ge 5. 1. 2 文件保存对话框( u i t f i l e) …………………………………………………… 314 pu

5. 1. 3 颜色设置对话框( u i s e t c o l o r)…………………………………………………… 315 5. 1. 4 字体设置对话框( u i s e t f on t) …………………………………………………… 316 5. 1. 5 页面设置对话框( a e s e t upd l p g g)…………………………………………………… 317

5. 1. 6 打印预览对话框( r i n t r e v i ew)…………………………………………………… 317 p p 5. 1. 7 打印设置对话框( r i n t d l p g)……………………………………………………… 317 ) 5. 1. 8 进度条( wa i t ba r ………………………………………………………………… 317 5. 1. 9 菜单选择对话框( menu)………………………………………………………… 322 5. 1. 10 普通对话框( d i a l og) …………………………………………………………… 324 5. 1. 11 错误对话框( e r r o r d l g) ………………………………………………………… 325

5. 1. 12 警告对话框( wa rnd l g) ………………………………………………………… 327 5. 1. 13 帮助对话框( he l l pd g) ………………………………………………………… 328


5. 1. 14 信息对话框( msgbox) ………………………………………………………… 329 5. 1. 15 提问对话框( s t d l que g)………………………………………………………… 330 5. 1. 16 输入对话框( i npu t d l g)………………………………………………………… 331

5. 1. 17 目录选择对话框( u i t d i r) …………………………………………………… 332 ge 5. 1. 18 列表选择对话框( l i s t d l g)……………………………………………………… 333 5. 2 重难点分析 …………………………………………………………………………… 334

5. 2. 1 u i t f i l e ………………………………………………………………………… 334 ge 5. 2. 2 u i t f i l e ………………………………………………………………………… 334 pu 5. 2. 3 wa i t ba r…………………………………………………………………………… 334

5. 2. 4 msgbox

………………………………………………………………………… 334 5. 2. 5 que s t d l g ………………………………………………………………………… 334 5. 2. 6 i npu t d l g ………………………………………………………………………… 335 5. 2. 7 l i s t d l g …………………………………………………………………………… 335 专题分析 ……………………………………………………………………………… 335 5. 3

专题 8 预定义对话框在 GUI设计中的应用 ………………………………………… 335 5. 4 精选答疑 ……………………………………………………………………………… 340 问题 27 如何制作一个嵌套到当前窗口内的进度条 ………………………………… 340

问题 28 如何制作文件浏览器 ………………………………………………………… 343 第 6 章 采用 GUIDE 建立 GUI ……………………………………………………………… 345

视频教学:1. 75 小时

空 航

6. 1 知识点归纳 …………………………………………………………………………… 345 6. 1. 1 GUIDE 界面基本操作 …………………………………………………………… 346 6. 1. 2 GUI的 M 文件 ………………………………………………………………… 356

6. 1. 3 回调函数 ………………………………………………………………………… 366 6. 1. 4 GUI跨平台的兼容性设计 ……………………………………………………… 369 6. 1. 5 断点调试和代码性能分析器 …………………………………………………… 370

6. 1. 6 采用 GUIDE 创建 GUI的步骤 ………………………………………………… 371 6. 1. 7 触控按钮( PushBu t t on)………………………………………………………… 371 6. 1. 8 静态文本( S t a t i cTex t) ………………………………………………………… 374

6. 1. 9 切换按钮( Togg l eBu t t on)……………………………………………………… 376 6. 1. 10 滑动条( S l i de r) ………………………………………………………………… 379 6. 1. 11 单选按钮( Rad i oBu t t on)……………………………………………………… 380

6. 1. 12 可编辑文本( Ed i tTex t) ……………………………………………………… 382 6. 1. 13 复选框( Che ckBox)…………………………………………………………… 384 6. 1. 14 列表框( L i s t box) ……………………………………………………………… 386

nu)…………………………………………………… 388 6. 1. 15 弹起式菜单( Pop up Me 6. 1. 16 按钮组( Bu t t onGr oup)………………………………………………………… 389 6. 1. 17 面板( Pane l) …………………………………………………………………… 392

6. 1. 18 表格( Tab l e) …………………………………………………………………… 393 6. 1. 19 坐标轴( axe s)…………………………………………………………………… 398


6. 2 重难点分析 …………………………………………………………………………… 400

6. 2. 1 回调函数中的数据传递 ………………………………………………………… 400

6. 2. 2 GUI界面之间的数据传递 ……………………………………………………… 401 6. 2. 3 KeyPr e s sFcn 与 Cu r r en tCha r a c t e r …………………………………………… 402 6. 2. 4 Wi ndowBu t t onDownFcn、 Ca l l ba ck 与 Se l e c t i onType ………………………… 402

6. 3 专题分析 ……………………………………………………………………………… 402 专题 9 GUI对象之间的数据传递 ……………………………………………………… 402

专题 10 回调函数的应用实例 ………………………………………………………… 407 6. 4 精选答疑 ……………………………………………………………………………… 421 问题 29 如何动态修改 L i s tBox 的选项 ……………………………………………… 421

问题 30 如何动态修改 Pop Up Menu 的选项 ……………………………………… 423 第 7 章 Ac t i v eX 控件 ………………………………………………………………………… 428 视频教学:1. 25 小时

7. 1 知识点归纳 …………………………………………………………………………… 428 7. 1. 1 LED 状态显示( LED Ac t i veXCon t r o l) ……………………………………… 430 7. 1. 2 七段 LED 数码显示控件( Nume r i cLED Ac t i veXCon t r o l) ………………… 437

7. 1. 3 表盘显示控件( Angu l a rGaugeAc t i veXCon t r o l) …………………………… 439 7. 1. 4 线性测量控件( L i ne a rGaugeAc t i veXCon t r o l)……………………………… 443 7. 1. 5 滑动条控件( S l i de rAc t i vexCon t r o l) ………………………………………… 448

空 航

7. 1. 6 进度条控件( Pe r c en tAc t i veXCon t r o l) ……………………………………… 451 7. 1. 7 选项卡控件( TabS t r i t r o l)………………………………………………… 454 pCon 7. 2 重难点讲解 …………………………………………………………………………… 465

7. 2. 1 LED Ac t i veXCon t r o l概述

…………………………………………………… 465

7. 2. 2 Nume r i cLED Ac t i veXCon t r o l概述 ………………………………………… 466 7. 2. 3 Angu l a rGaugeAc t i veXCon t r o l概述 ………………………………………… 466 7. 2. 4 S l i de rAc t i vexCon t r o l概述 …………………………………………………… 466

7. 3 专题分析 ……………………………………………………………………………… 466

专题 11 TabS t r i p 控件在 GUI设计中的应用 ………………………………………… 466 7. 4 精选答疑 ……………………………………………………………………………… 470 问题 31 如何采用 Ac t i veX 控件制作一个滑动条 …………………………………… 470 问题 32 如何采用 Ac t i veX 控件制作一个表盘 ……………………………………… 471 问题 33 如何采用 Ac t i veX 控件制作一个数码显示器 ……………………………… 473

问题 34 如何编写 Ac t i veX 控件的回调函数 ………………………………………… 474

第8章

定时器 ………………………………………………………………………………… 476

视频教学:1. 5 小时

8. 1 知识点归纳 …………………………………………………………………………… 476

8. 1. 1 定时器对象及其属性 …………………………………………………………… 476 8. 1. 2 定时器的执行模式 ……………………………………………………………… 478 8. 1. 3 定时器的回调函数 ……………………………………………………………… 479


8. 1. 4 定时器的操作函数 ……………………………………………………………… 480 8. 1. 5 定时器的操作步骤 ……………………………………………………………… 481 8. 2 重难点分析 …………………………………………………………………………… 482

8. 2. 1 Time rFcn 函数 …………………………………………………………………… 482 常用的定时器操作函数 ………………………………………………………… 482 8. 2. 2 8. 3 专题分析 ……………………………………………………………………………… 483

专题 12 定时器在 GUI设计中的应用 ………………………………………………… 483 8. 4 精选答疑 ……………………………………………………………………………… 492 问题 35 如何让切换按钮定时弹起 …………………………………………………… 492 问题 36 如何在菜单栏上创建万年历 ………………………………………………… 493 问题 37 如何采用数码管显示当前的年月日和时刻 ………………………………… 494

问题 38 如何实现一个流水灯 ………………………………………………………… 496 第 9 章 串口编程 ……………………………………………………………………………… 500

视频教学:1 小时

9. 1 知识点归纳 …………………………………………………………………………… 500 9. 1. 1 串口概述 ………………………………………………………………………… 500 9. 1. 2 串口对象的属性 ………………………………………………………………… 502

9. 1. 3 串口的基本操作 ………………………………………………………………… 506 /O 函数汇总 ……………………………………………………………… 509 9. 1. 4 串口I 9. 2 重难点分析 …………………………………………………………………………… 510

空 航

9. 2. 1 串口对象的创建 ………………………………………………………………… 510 9. 2. 2 重要的串口操作函数 …………………………………………………………… 510 9. 3 专题分析 ……………………………………………………………………………… 511

专题 13 串口在 GUI设计中的应用 …………………………………………………… 511 第 10 章 mc c编译 …………………………………………………………………………… 527 10. 1 mc c编译 ……………………………………………………………………………… 527

10. 2 mc c编译的局限性 …………………………………………………………………… 529 10. 3 MATLAB 保护文件( P 文件) ……………………………………………………… 530 第 11 章 综合实例 …………………………………………………………………………… 531

视频教学:1. 25 小时

MATLABGUI设计常用函数 ……………………………………………………… 575


第 1章

GUI设计预备知识 1. 1 知识点归纳 本章内容: ◆ 基本程序元素 ◇ 变量

◇ 特殊值 ◇ 关键字

◇ 运算符 ◆ 数据类型 ◇ 数值型

◇ 逻辑型 ◇ 字符数组

空 航

◇ 结构数组 ◇ 单元数组

◇ 连接矩阵 ◇ 重塑矩阵形状

◆ 矩阵操作 ◇ 创建矩阵

◇ 函数句柄 ◇ 日期和时间

◇ 矩阵元素移位和排序 ◇ 向量(数集)操作

◆ 程序设计 ◇ 函数参数

◇f o r、 wh i l e循环结构 ◇i f、 swi t ch 条件分支结构

◇t r a t ch 结构 y…c ◇ con t i nue、 b r e ak 和 r e t u rn

◇ 其他常用函数

1. 1. 1 基本程序元素 1.变 量 程序中,为了方便操作内存中的值,需要给内 存 中 的 值 设 定 一 个 标 签,这 个 标 签 称 之 为 变


量。变量不需事先声明,MATLAB 遇到新的变量名时,会自动建立变量并分配内存。给变 量 赋值时,如果变量不存在,会创建它;如果变量存在,会更新它的值。 变量名命名规则如下: ① 始于字母,由字母、数字或下画线组成。 ② 区分大小写。

③ 可任意长,但仅使用前 N 个 字 符。N 与 硬 件 有 关,由 函 数 name l eng t hmax 返 回,一 般 N=63。 ④ 不能使用关键字作为变量名。 ⑤ 避免使用函数名作为变量名。

如果变量采用函数名,该函数失效。如在命令行键入:

空 航

虚数单位i失效。 与变量有关的函数见表 1. 1。

i = 3; 1+2*i ans = 7

c l e a r函数失效,不能清除基本工作空间里的变量。

clear = 3; clear clear = 3

函数说明

函数名

表 1. 1 与变量有关的函数

c l e a r

c l e a r va r s

i s va r name

移除工作空间里的数据项,释放内存

r name genva

ans

name l eng t hmax

a s s i i n gn

从内存中清除变量 检查输入的字符串是否为有效的变量名 采用字符串构建有效的变量名 当没指定输出变量时,临时存储最近的答案 返回最大的标识符长度 指派变量到基本工作空间或当前空间

【注】 ①c l e a r移除工作空间的变量,而 c l c则清空命令窗口的输出。 ②c l e a r va r s可以清除内存中的某些或全部变量,也可以保留指定的变量。例如: a = 1; b = 1; clearvars -exceptb % 清除工作空间中除变量 b 以外的所有其他变量 a ??? Undefinedfunctionorvariable a . b


b= 1

MATLAB 将变量存储在一块内存区域中,该区域称为基本工作空间。脚本文件(没有 输 入输出参数、不带f unc t i on 关键字、由一系列命令语句组成的 M 文件)或命令行创建的变量都 存在基本工作空间中。

函数不使用基本工作空间,每个函数都有自己的函数空间。 在函数空间生成的变量,只在函数空间有效;在 基 本 工 作 空 间 生 成 的 变 量,只 在 基 本 工 作 空间有效。若需要在函数空间中指派变量到基本工作空间,使用 a s s i i n 函数: gn assignin( workSpace, varName ,varValue)

指派变量 v a rName到 wo r kSp a c e表示的空 间 中,且 变 量 v a rName 的 值 初 始 化 为 v a rVa l u e。

wo rkSpa c e取值为 ba s e 表示基本工作空间;取值为 c a l l e r 表示当前回调函数空间。 不能在基本工作空间中指派变量到函数空间。 变量有以下 3 种基本类型:

如果要获取函数的局部变量,可以在函数内部设置断点。

① 局部变量。每个函数都有自己 的 局 部 变 量,这 些 变 量 只 能 在 定 义 它 的 函 数 内 部 使 用。 当函数运行时,它的变量保存在自己的工作空间里,一旦函数退出,这些局部变量将不复存在。 脚本没有单独的工作空间,只能共享脚本调用者的工作空间。当从命令行调用,脚本变量

存在基本工作空间内;当从函数调用,脚本变量存在函数空间内。

② 全局变量。在函数或基本工作 空 间 内,用 g l oba l声 明 的 变 量 为 全 局 变 量。 例 如,声 明 变量 a为全局变量:

空 航

globala

声明了全局变量的函数或基本工作空间,共享该全局变量,都可以给它赋值。

如果函数的子函数也要使用全局变量,也必须用 g l oba l声明。 全局变量要放在函数开始处声明。

为增强程序的逻辑性、可读性和封装性,应谨慎使用全局变量。 ③ 永久变量。永久变量用 pe r s i s t en t声明,只能在 M 文件函数中定义和使用,只允许声 明它的函数存取。当声明它的函数退出时,MATLAB 不会从内存中清除它。例如,声明变 量

a为永久变量:

persistenta

最好在函数开始处声明永久变量。声明后,默认初始值为空矩阵[]。

2.特殊值 一些函数返回重要的特殊值,这些值可以在 M 文件中使用,见表 1. 2。 表 1. 2 特殊值

函 eps

i n tmax

函数说明 浮点数相对精度;MATLAB 计算时的容许误差

本计算机能表示的 8 位、 16 位、 32 位、 64 位的最大整数


续表 1. 2 函

函数说明

i n tmi n

本计算机能表示的 8 位、 16 位、 32 位、 64 位的最小整数

r e a lmi n

本计算机能表示的最小浮点数

r e a lmax

本计算机能表示的最大浮点数

i p

3. 1415926535897…

i n f

无穷大。当 n>0 时, n/0 的结果是i n f;当 n<0 时, n/0 的结果是 -i n f

i,j

虚数单位

/ 非数,无效数值。比如: 0/0 或i n f i n f,结果为 NaN

NaN

c r o s o f tWi ndows MATLAB 运行平台。比如:当返回字符串 PCWIN 时,操作系统为 Mi

c ompu t e r

7. 8. 0. 347 ( R2009a) MATLAB 版本字符串。比如:

ve r s i on

【注】 e s为 MATLAB 进行数学运算(如平方、开方、求正弦)时,计算结果所容许的误差。 p 因为浮点数的计算存在容许误差,因此,在比较浮点数的值是否相等,或查找数组中某个浮点值

时,要考虑这个容许误差。例如,查找数组 a中是否存在 1. 01 这个元素,不要采用以下方法:

find( a == 1. 01)

而应该考虑容许误差:

find( abs( a - 1. 01)﹤ =eps)

3.关键字

空 航

MATLAB 为程序语言保留的一些字,称为关键字。变量名不能为关键字。 MATLAB 所 有 的 关 键 字 有 b r e ak、 c a s e、 c a t ch、 c on t i nue、 e l s e、 e l s e i f、 end、 f o r、 f unc t i on、

iskeyword(if ) ans = 1

l oba l、 i f、 o t he rwi s e、 r s i s t en t、 r e t u rn、 swi t ch、 t r wh i l e、 c l a s sde f、 r f o r、 spmd。 g pe y、 pa 查看或检查关键字用i skeywo r d 函数。例如:

4.运算符 运算符主要分为算术运算符、关系运算符和逻辑运算符 3 大类,还包括一些特殊运算符。 ( 1)算术运算

算术运算符分为两类:矩阵运算和数组运算。矩阵运算是按线性代数的规则进行运算,而

数组运算是数组对应元素间的运算,见表 1. 3。

表 1. 3 算术运算符

运算符 + 、-

/ *、

\

运算方式

矩阵运算、数组运算

加、减

矩阵运算

乘、除

矩阵运算

左除,左边为除数

运算符 + 、.*

. \

运算方式

矩阵运算、数组运算

单目的加、减

数组运算

数组乘

数组运算

数组左除


续表 1. 3 运算符

运算方式

^ :

运算符

运算方式

/ .

矩阵运算

乘方

矩阵运算

转置

矩阵运算、数组运算

索引,用于增量操作

. ^

.

数组运算

数组右除

数组运算

数组乘方

数组运算

数组转置

MATLAB 数组的算术运算,是两 个 同 维 数 组 对 应 元 素 之 间 的 运 算。 一 个 标 量 与 数 组 的

运算,是标量与数组每个元素的运算,这种特性称之为标量扩展。 ( 2)关系运算

关系运算比较两个同维数组或同维向量的 对 应 元 素,结 果 为 一 个 同 维 的 逻 辑 数 组。如 果

运算对象有一个为标量,另一个是数组或向量,那 么 先 进 行 标 量 扩 展,然 后 再 比 较。关 系 运 算 符见表 1. 4。

表 1. 4 关系运算符 运算字符 >

小于

运算字符

大于

>=

小于或等于

大于或等于

==

~=

等于 不等于

<=

<

运算字符

例如:

% 创建变量 a,并初始化为 1 % 比较 a 与 1 的值,返回比较后得到的逻辑值,并赋给逻辑变量 b

空 航

a = 1; b= ( a == 1) b= 1 c= ( a 2)

% 判断 a 是否大于 2,返回比较后得到的逻辑值,并赋给逻辑变量 c

c=

( 3)逻辑运算

0

MATLAB 提供了两种类型的逻辑运算:元素运算和捷径运算,见表 1. 5。 表 1. 5 逻辑运算符与函数

运算类型

运算符与函数 &

元素运算

|

~

xo r

( and) ( o r)

( no t)

运算类型

逻辑与 逻辑或 逻辑非 逻辑异或

运算符与函数

&&

对标量值的捷径与

||

对标量值的捷径或

捷径运算

捷径运算首先判断第 1 个运算对象,如果可 以 知 道 结 果,直 接 返 回,而 不 继 续 判 断 第 2 个

运算对象。捷径运算提高了程序的运行效率,可以避免一些不必要的错误。例如: x = b&& ( a/b 10)

% 相当于 x = ( b&& ( a/b > 10))

/b > 10)的值了,也就避免了被 0 除的错误。 如果 b 为 0,捷径运算符就不会计算( a


【注意】 捷径运算符只能对标量值执行“逻辑与”和“逻 辑 或”运 算,而 元 素 运 算 则 可 以 对 向量进行逻辑运算。例: [ 123]|| [ 110] ??? Operandstothe||and&&operatorsmustbeconvertibletologicalscalarvalues. [ 123]| [ 110]

ans = 1

1

1

( 4)位运算

位运算相关函数见表 1. 6。

位运算函数

b i t xo r

返回指定位的数值,值为 0 或 1, doub l e型

b i t t ge

位与

设定指定位的值为 0 或 1,返回运算结果

b i t s e t

位或

b i t sh i f t

位比较,反码

移位运算,返回运算结果

swapby t e s

位异或

b i t cmp

位运算函数

翻转字节的位顺序,返回运算结果

b i t o r

b i t and

表 1. 6 位运算相关函数

【注意】

① 位运算函数的输入必须同为 无 符 号 整 数、无 符 号 整 数 数 组 或 标 量 浮 点 数,且 输 出 与 输 入的数值类型一致。若输入为标量浮点数,MATLAB 会先将其转换为无符号整数,再进行位

运算。

空 航

② 字节的合并可以采用位运算。例如,有一个整数由 2 字 节 组 成:低 字 节 为 120,高 字 节 为 1。那么这个整数的值为 120+1×256=376,可以采用位函数计算:

low_uint 8 = uint 8( 120); % 低字节为 uint 8 型值 _ high uint 8 = uint 8( 1); % 高字节为 uint 8 型值 v a l u e_u i n t 16 = b i t o r( u i n t 16( l o w_u i n t 8),b i t s h i f t( u i n t 16( h i h_u i n t 8),8)); % 返回 u i n t 16 整型值 g _ ( _ ) ; value double = double value uint 16 % 返回 double 值

( 5)特殊运算符

除了以上运算符,还有一些特殊的运算符经常使用,见表 1. 7。 表 1. 7 特殊运算符

特殊运算符 []

{}

()

说 生成向量和矩阵

给单元数组赋值,或创建一个空单元数组 在算术运算中优先计算;封装函数参数;封装向量或矩阵的下标

=

用于赋值语句

.

域访问

... ,

在矩阵或向量之后表示复共轭转置;两个“”之间的字符为字符串 续行符 分隔矩阵下标和函数参数


续表 1. 7 特殊运算符

;

在括号内结束行;禁止表达式显示结果;隔开声明

:

创建矢量、数组下标;循环迭代

%

注释;格式转换定义符中的初始化字符

@

函数句柄,类似于 C 语言中的取址运算符 &

( 6)运算优先级

在包含前面介绍的运算符的表达式中,运算顺序按优先级进行。优先级高的先执行,同优

先级的从左至右执行。运算符按优先级从高到低排列见表 1. 8。 表 1. 8 运算优先级

4 5

6

. . +

-

+

-

:

号 7

<

9

|

11

8

~

单目运算

/ . . \ * / \

&

10 双目运算

运算符 <=

&&

>

>=

备 ==

~=

优先级最高 ∧

.*

3

()

2

优先级最低

1

运算符

空 航

1. 1. 2 数据类型

京 北

符显示在图 1. 1 中。

MATLAB 有 17 种基本的数据类型,每种类型的数据都以矩阵或数组形式存在。矩 阵 或 数组的最小尺寸是 0×0,它能够扩展为任意大小的 n 维数组。所有的基本数据类型用小写字

图 1. 1 基本数据类型

表 1. 9 详细描述了这些数据类型。

表 1. 9 数据类型

数据类型 i n t 8, u i n t 8, i n t 16,

u i n t 16, i n t 32, u i n t 32, i n t 64, u i n t 64

带符号和无 符 号 整 数 数 组。 存 储 空 间 比 单 精 度 或双精度数 小。 除i n t 64 和 u i n t 64 外,都 可 用 于 数学运算

举 f l ag=u i n t 16( 0);

a=u i n t 8( 3)+u i n t 8( 10); b=i n t 8( 1: 10)


续表 1. 9 数据类型 s i ng l e doub l e i l og i c a l

单精度数数组。存储空间比双 精 度 小,数 的 精 度 和范围也比双精度小 双精度数 组。 默 认 的 数 字 类 型。 二 维 数 组 可 为

逻辑值数 组。 逻 辑 值 1 或 0 分 别 代 表 真 和 假。 二维数组可为稀疏数组

串的数组最好用单元数组

us e rc l a s s

MATLAB a{ 1, 1}= Red ;

a{ 1, 2}= mag i c( 4)

型的数组 结构数组。类似 于 C 语 言 中 的 结 构 体。 每 个 域

a. day = 12;

函数句柄,指向一个函数,能传递给其他函数

可保存不同维数和不同类型的数组

a. c o l o r= Red @s i n

l 0 -2 -5]) po ynom([

从用户定义的类构造的对象 从一个 J ava类构造的对象

ava. awt. Fr ame j

J avac l a s s

mag i c( 4)> 7

f unc t i onhand l e

3 * 10 ^ 300

s t r uc t ur e

单元数组。各单元可存储不同 维 数、不 同 数 据 类

c e l la r r ay

s i ng l e( 5* 10 ^ 38)

5+6

稀疏数组

字符数组。字 符 串 表 示 为 字 符 向 量。 多 个 字 符

cha r

1.数值型 数值型数据包括无符号和 带 符 号 整 数、单 精 度 和 双 精 度 浮 点 数。 MATLAB 默 认 将 所 有

空 航

数值存为双精度浮点数( doub l e型),但整数和单精度数组更节省内存空间。 所有 的 数 值 型 数 据 都 支 持 基 本 的 数 组 操 作,如 下 标 操 作 和 尺 寸 重 塑。除i n t 64 和 u i n t 64 外,都可用于数学运算。 数

( 1)整

下面介绍整数、浮点数、复数和其他常用函数。

整数类型有 8 种: 4 种带符号整数和 4 种无 符 号 整 数。带 符 号 整 数 可 表 示 负 整 数、 0和正

整数,最高位为符号位,而无符号整数只能表示 0 和 正 整 数。它 们 表 示 的 数 值 范 围 一 样 大,只 是对范围进行了“平移”。整数的数据类型及其表示范围见表 1. 10。 表 1. 10 整数的数据类型及其表示范围

数据类型

值的范围

转换函数

数据类型

值的范围

转换函数

单精度 8 位整数

-2 ~2 -1

i n t 8

无符号 8 位整数

0~2 -1

u i n t 8

7

7

8

单精度 16 位整数

-2 ~2 -1

i n t 16

无符号 16 位整数

0~2 -1

u i n t 16

单精度 64 位整数

-2 ~2 -1

i n t 64

无符号 64 位整数

0~2 -1

u i n t 64

单精度 32 位整数

15

15

-2 ~2 -1 31 63

31 63

i n t 32

无符号 32 位整数

16

0~2 -1 32 64

u i n t 32

整数算术运算的操作数可以为: ◆ 具有相同数据类型的整数或整数数组。运算结果的数据类型与操作数相同。例如: x = uint 8([ 133452]).* uint 8( 3);

◆ 整数或整数数 组 与 标 量 doub l e 型 浮 点 数。 运 算 结 果 的 数 据 类 型 与 整 数 操 作 数 的 一


样。例如: x = uint 32([ 132347528]).* 75. 49; % 相当于 x= uint 32( round([ 132347528].* 75. 49));

常见的整数操作函数见表 1. 11。

表 1. 11 其他常见的整数操作函数

函数名

函数说明

函数名

函数说明

c e i l

向无穷大方向取整

r ound

四舍五入

f i x

向 0 取整

f l oo r

i s i n t ege r

判断输入是否为整数数组

i snume r i c

向无穷小方向取整

判断输入是否为数值数组

( 2)浮点数

doub l e型数据共 64 位,位存储格式见图 1. 2 和表 1. 12。

浮点数有单精度( s i ng l e)和 双 精 度 ( doub l e)两 种 格 式,默 认 是 doub l e 格 式。 两 种 格 式 之 间可进行强制转换。

图 1. 2 IEEE 定义的 doub l e型数据存储格式

数值计算公式为:

空 航

s 当 0<e<2047 时, va l ue= (-1) ×2e-1023 ×1. f; s 当 e=0, ×2e-1022 ×0. f; f≠0 时, va l ue= (-1)

s 当 e=0, f=0 时, va l ue= (-1) ×0. 0;

当 e=2047, f=0, s=0 时, va l ue=+i n f;

当 e=2047, f=0, s=1 时, va l ue=-i n f; 当 e=2047, f≠0 时, va l ue=NaN。

表 1. 12 doub l e型数据的位存储格式

位 63

62~52

符号位, 0 为正, 1 为负 指数,偏移量为 1023

位 51~0

数 1. f的小数f

1 例如,-1= (-1) ×21023-1023 ×1. 0,即 -1 的位存储值为: s=1, e=1023, f=0。 所 以,双 精度 数 -1 的 二 进 制 值 为 10111111 11110000 00000000 00000000 00000000 00000000

0000000000000000。 doub l e可把其他数值型数据、字符或逻辑数转换成双精度。如: a=double( uint 8( 44)) a= 44


b=double(c ) b= 99

s i ng l e型数据共 32 位,位存储格式见表 1. 13。 常见的浮点数操作函数见表 1. 14。 表 1. 13 s i ng l e型数据的位存储格式 位

符号位, 1 为负 0 为正,

31

30~23

指数,偏移量为 127

22~0

( 3)复

表 1. 14 其他常见的浮点数操作函数

函数名

函数说明

i s f l oa t

检查输入是否为浮点数

r e a lmax

数 1. f的小数f

返回本计算机能够表示的最大浮点数

r e a lmi n

返回本计算机能够表示的最小浮点数

eps

浮点相对精度

i s r e a l

检查是否数组的所有元素为实数

复数由两部分构成:实部和虚部。基本虚数单位为 -1 的开方,用i或j表示。

生成复数有两种方法:

① 直接生成。如:

a=2+4i a= 2. 0000 + 4. 0000i

% 判断变量 a 是否为实数

ans = 1

a=2+0i a= 2 isreal( a)

空 航

这种方法不能生成虚部为 0 的复数。如:

② 用c omp l ex 函数生成。c omp l ex 函数有两种调用格式,见表 1. 15。 表 1. 15 c omp l e x 函数

函数调用格式

函数格式说明

函数调用格式

函数格式说明

c= c omp l ex( a, b)

生成复数 c,且 c= a + b i

c= c omp l ex( a)

生成复数 c,且 c=a。c虚部为 0

用c omp l ex 函数可生成虚部为 0 的复数。在命令行输入以下语句:

a=complex( 2) a= 2 isreal( a) ans = 0

从复数中提取实部和虚部,分别用 r e a l和imag 函数。如:


z=2+3i; real( z)

ans = 2 imag( z) ans = 3

( 4)其他常用函数

数字型数据还经常用到一些其他函数,见表 1. 16。

表 1. 16 其他常用函数 函数名

i snan

检查数组元素是否为 NaN

f o rma t

i s i n f

f i nd

检查数组元素是否为无穷大或无穷小

i s f i n i t e

检查数组元素是否为有限值

i s a

s e t d i f f

检查输入是否为指定的数据类型

c l a s s

s e t xo r

who s

控制输出的显示格式 查找非零元素的值和索引号 返回第 1 个 向 量 中 存 在 而 第 2 个 向 量 中 不 存在的元素

返回两个向量中单独存在的元素

创建对象或返回对象类型

函数说明

函数说明

函数名

nnz

返回矩阵中非零元素的个数

显示输入的数据类型

如下:

% 第 1 个向量 % 第 2 个向量 % 向量 A 中查找元素 3,返回 3 的位置 % 返回向量 A 中非零元素个数

空 航

A= [ 0123432101234]; B= [ 2468]; index_3 = find( A == 3) index_3 = 4 6 12 num = nnz( A)

表中的f i nd、 s e t d i f f、 s e t xo r(向 量 异 或 )、 nnz( numbe ro fnonz e r o 的 缩 写 )函 数 用 法 举 例

num = 11 element_diff = setdiff( A,B) element_diff = 0 1 3 element_xor = setxor( A,B) element_xor = 0

1

3

6

% 返回 A 中存在而 B 中不存在的元素

% 返回 A、 B 中单独存在的元素

8

【注意】 一般不用f i nd 函数查找 数 组 的 下 标,数 组 下 标 直 接 用 逻 辑 数 组 来 代 替,运 算 效

率更高。例如,对于数组[ 1 :100],不要使用下面的写法查找元素: a = 1 :100; a( find( a 10))

而要使用下面的写法: a( a 10)


表 1. 16 中, f o rma t函数用于控制命令窗口中数值的显示格式,调用格式见表 1. 17。 表 1. 17 f o rma t函数

函数调用格式

函数格式说明

f o rma t

按默认格式输出,即 5 位短定点格式

f o rma tt ype

改变输出为 t ype指定的格式

f o rma t(t ype )

改变输出为 t o rma t的函数形式 ype指定的格式。f

表 1. 17 中的t 18。 ype为数值显示格式。常用的数值显示格式见表 1. 表 1. 18 f o rma t常用的数值显示格式

显示格式参数值 sho r t

作用范围

取 5 位定点和浮点格式中最好的

浮点变量

5 位定点格式

sho r tg l ong

长定点格式,双精度 15 位,单精度 8 位 长浮点格式,双精度 15 位,单精度 8 位

l ongg

取长定点和长浮点格式中最好的

l onge

5 位浮点格式

sho r te

hex

对正、负和 0 元素显示 + 、- 和空字符

+

十六进制数

r a t

数字变量

分数形式。用小整数之比来近似数字值

c ompa c t

空 航

紧凑格式。除去多余的换行所

l oo s e

所有变量

松散格式。加换行

例如:

% 临时修改当前命令窗口文本的显示方式为紧凑格式

formatcompact a= 1 a= 1

显示格式

【注意】 ①f o rma t仅改变数值显示的方式,并不影响 MATLAB 怎样计算和保存数值。 ② 若要设置命令窗口文本默认的显示方式,可以 进 入 MATLAB 主 菜 单:【 F i l e】→ 【 Pr e f -

e r enc e s】→ 【 Command Wi ndow】→ 【 Tex td i sp l ay】,修 改 【Nume r i cf o rma t】和 【Nume r i cd i s l ay】这两项的值为默认值。 p 2.逻辑型 逻辑性数据分别用 1 和 0 表示真和假两种 状 态。一 些 函 数 和 运 算 返 回 逻 辑 真 或 假,以 表

明某个条件是否满足。逻辑值 1 或 0 组成的数组,称为逻辑数组。如: [ 1040556974] 40 ans = 0 0 1

1

1


上面生成的变量 ans为逻辑数组。 生成逻辑数组有两种方法:

① 使用t rue和f a l s e函数直接生成。如:

a= [ truefalsetruefalse] a= 1 0 1 0

② 通过逻辑运算生成。逻辑运算函数见表 1. 19。

表 1. 19 逻辑运算及逻辑运算函数

逻辑运算函数(括号内为函数对应的运算符)

t r ue或f a l s e

值为真或假

l og i c a l

数字值转化为逻辑值

a l l and(&)、 o r( |)、 no t(~ )、 xo r、 any、

逻辑运算

&&、 ||

捷径与和捷径或

ne(~= )、 l t(< )、 eq(== )、 t(> )、 l e(<= )、 g ge(>= )

c e l l f un i s* (* 为通配符)、

关系运算

测试运算

s t r cmp i、 s t r ncmp i s t r ncmp、 s t r cmp、

字符串比较

表 1. 19 中 any 和 a l l函数的调用格式见表 1. 20。

A 至少有一个元素非零返回真,全零返回假。忽略 NaN 值

A,d im) B = any( A) B=a l l(

B=a l l( A,d im)

a l l

A) B = any(

例如: A= [ 1, 0, 1; 0, 0, 1]; ( , ) any A 1 ans = 1 0 1 any( A, 2) ans = 1 1 all( A, 1) ans = 0 0 1 all( A, 2) ans = 0 0

格式说明

空 航

any

调用格式

d im=1,列向量非全零返回真,否则返回假。返回行向量;

d im=2,行向量非全零返回真,否则返回假。返回列向量

表 1. 20 any和 a l l函数的调用格式

A 所有元素非零返回真,否则返回假。忽略 NaN 值

d im=1,列向量所有元素非零返回真,否则返回假。返回行向量;

d im=2,行向量所有元素非零返回真,否则返回假。返回列向量


any 和 a l l函数的用法见图 1. 3。 3.字符数组

MATLAB 中,每个字 符 都 用 一 个 数 值 表 示,采 用 16 位的 Un i c ode 编 码。8 位 的 ASCI I字 符 代 码 集是 Un i c ode字符代码集的子集。

m×n 的字符数组 由 cha r 函 数 创 建; 1×n 的 字 符数组也称为字符串。 长度 不 同 的 字 符 串 组 成 的 数 组,称 为 字 符 串 单 元数组。 下面 介 绍 字 符 数 组 与 字 符 串 单 元 数 组,以 及 常

图 1. 3 any和 a l l函数用法示例

用的字符串操作函数。 ( 1)字符数组与字符串单元数组

把字符放在一对单引号内,就定义了一个一维的字符数组。一维字符数组,也称为字符串

c l a s s和i s cha r函数都能识别字符数组:

name = Luohua-fei ; whosname Name Size Bytes Class name 1x 11 22 chararray Grandtotalis11elementsusing22bytes

或字符向量。每个字符占用 2 字节的存储空间(想想这是为什么?),如:

空 航

class( name) ans = char ischar( name)

ans = 1

用[]创建二维字符数组时,必须保证每行有相同的长度,可在短的字符串后加空格。如: a= [abcd ;efg ] a= abcd efg

用 cha r函数创建二维字 符 数 组,函 数 会 自 动 在 短 的 字 符 数 组 后 加 空 格,使 其 长 度 一 致,

cha r调用格式见表 1. 21。如: char(abcd ,efg ) ans = abcd efg

创建二维字符数组时,要求所有的字符串等 长,这 意 味 着 常 常 要 对 字 符 串 尾 部 填 充 空 格, 使其长度一致。然而,MATLAB 有另一 类 数 组,能 够 容 纳 不 同 大 小 和 类 型 的 数 据,这 就 是 字 符串单元数组。


字符串单元数组主要用到 c e l l s t r和i s c e l l s t r两个函数,见表 1. 21。

c=c e l l s t r( S)将字符数组 S 的每一行变为字符串单元数组c的一个单独单元,并去掉尾部 空格。如: ;Monday week= [Sunday ( ) a=cellstr week a= Sunday Monday Tuesday

;Tuesday ];

用i s c e l l s t r可以判断变量是否为字符串单元数组: iscellstr( a) ans = 1

\和字符 n 组成的字符串呢,还是一个转义字符(换行符)呢? 先看两条语句的执行结果:

【思考】 MATLAB 中,字符和字符串都是用单引号标识 的,而 没 有 用 到 双 引 号。这 与 C 或 C++ 语言中的表示方法不太一样。这种表示方法会引发一个问题: \n 到底是一个由字符

double( \n ) ans = 92 110 double( sprintf( \n )) ans = 10

% 输出字符串\n 的 ASCII 值

空 航

% 输出字符换行符的 ASCII 值

MATLAB 中是这么规定的: \n 只有在格式化输出时,才表示为转 义 字 符。换 句 话 说,转 义 字 符 只 有 在 格 式 化 输 出 时

才有效。

要得到换行符,可使用以下方法: char( 10); % 采用 char 函数获取换行符 sprintf( \n ); % 采用 sprintf 函数获取换行符

( 2)常用的字符串操作函数

常用的字符串操作函数见表 1. 21。

表 1. 21 常用的字符串操作函数

调用格式

s t r c a t

t= s t r c a t( s 1,s 2,s 3,…)

依次横向连接字符数组 s 1, s 2, s 3…

S = cha r( t 1,t 2,t 3,…)

创建二维数组;短 的 字 符 串 后 加 空 格,使 每 行 长 度 一 致;

s t r v c a t cha r

S=s t r v c a t( t 1,t 2,t 3,…)

S = cha r( C)

函数说明

依次纵向连接字符数组 t 1, t 2, t 3…

也可以将字符串单元数组 C 转换为二维字符数组


续表 1. 21 函

i s cha r

c e l l s t r

调用格式

函数说明

t f=i s cha r( A)

A 为字符数组返回真,否则返回假

c=c e l l s t r( S)

生成字符串单元数组

i s c e l l s t r

t f=i s c e l l s t r( A)

判断 A 是否为字符串单元数组

deb l ank

c= deb l ank( c)

去掉字符串或单元数组所包含的字符串尾部空格

s o r t

s o r t r ows s t r t r im s t r r ep

s t r us t j f i nds t r s t r f i nd

s t r cmp s t r ncmp

s t rma t ch s t r t ok i s s t r r op p i s l e t t e r i s spa c e

num2s t r

eva l i n( wo rkSpa c e,exp r e s s i on)

只执行函数; f hand l e为函数句柄,f unc t i on 为包含函数名

的字符串; x1,…, xn 为被执行函数的输入参数

[ eva l( f hand l e,x1,…,xn) y1,y2,…]= f

[ unc t i on ,x1,…,xn) eva l(f y1,y2,…]= f

执行由 MATLAB 表达式组成的字符串

在指定的工作空间内执行表达式

t=l owe r( s)

将包含的全部字母转换为小写

B = uppe r( s)

uppe r

eva l( exp r e s s i on)[ a 1, a 2, a 3,… ]=eva l(f unc -

t i on( b1, b2, b3,…))

将包含的全部字母转换为大写

B=s o r t( A)

B=s o r t( A, d im)

按值的大小对数组元素排序

B =s o r t r ows( A) B = s o r t r ows( A, c o l umn) [ B,i ndex]= s o r t r ows( A,…)

S=s t r t r im( s t r)

s t r 1,s t r 2,s t r 3) s t r= s t r r ep(

T =s t r us t( S,r i t) j gh

T =s t r us t( S) j

T =s t r u s t( S,l e f t) T = s e n t e r) t r u s t( S,c j j

k =f i nds t r( s t r 1,s t r 2)

l owe r

按格式f o rma t从字符串变量 s中读取数据

A =s s c an f( s,f o rma t,s i z e)

eva l i n

A =s s c an f( s,f o rma t)

f eva l

按格式f o rma t写矩阵 A 的数据到字符串 s

空 航

eva l

[ s, e r rms r i n t f( f o rma t, A,…) g]=s p

s s c an f

创建含 n 个空格符的字符串

sp r i n t f

b l anks( n)

按列值的升序或降序,对矩阵的每行排序

移除字符串首部和尾部的空白 将s t r 1 中的 s t r 2 全部替换为 s t r 3 调整字符数组的对齐方式,分 为 靠 右、靠 左、居 中;其 他 位 置填充空格 在长字符串中搜索短字符串

k =f i nds t r( s t r 1,s t r 2)

在s t r 1 中搜索 s t r 2

k=s t r cmp( S,T)

较字符串单元数组 S 和 T,对应单元相同返回真

b l anks

t r 1 ,s t r 2) k=s t r cmp(s

k=s t r ncmp(s t r 1 ,s t r 2 ,n)

x=s t rma t ch(s t r ,STRS)

比较 s t r 1与s t r 2,完 全 相 同 才 返 回 真;否 则 返 回 假;或 比

s t r 1与s t r 2 前 n 个字符完全相同返回真;否则返回假 在字符数组或字符串单元数组中查找指定的字符串

t oken = s t r t ok(s t r)

t oken 为字符串 s t r 中被选择的部分;

[ t oken,r ema i n]= s t r t ok(…)

r ema i n 为字符串 s t r 中未被选择的部分

t f=i s s t r r op(s t r ,c a t ego r p y)

数组元素为 c a t ego r y 类型,返回真;否则返回假

t oken = s t r t ok(s t r ,de l imi t e r)

t f=i s l e t t e r(s t r)

de l imi t e r为分隔符;

数组元素若为字母,返回真;否则返回假

t f=i s spa c e(s t r)

数组元素若为空格字符,返回真;否则返回假

s t r= num2s t r( A,p r e c i s i on)

r e c i s i on 为最大精度,默认为 5 位精度; p

s t r= num2s t r( A)

s t r= num2s t r( A,f o rma t)

数字转换为字符串。若 A 为字符串,返回 A;

f o rma t为格式字符串


续表 1. 21 函

调用格式

函数说明

s t r 2num

t r) x=s t r 2num(s

将字符串或字符数组转换为数字或矩阵;4 位精度

i n t 2s t r

s t r=i n t 2s t r( N)

先进行四舍五入,再进行转换

s t r 2doub l e ma t 2s t r

将整数 N 转换为字 符 串 s t r;N 也 可 为 整 数 矩 阵;非 整 数

x=s t r 2doub l e(s t r) A) s t r= ma t 2s t r(

X =s t r 2doub l e( C)

s t r= ma t 2s t r( A,n)

字符串或字符串单元数组转换为双精度; 输入若不是有效标量值返回 NaN 矩阵转换为字符串; n 为数字精度

在表 1. 21 中部分函数的用法举例如下:

1)s t r c a t。连接多个字 符 数 组,可 使 用 字 符 串 连 接 函 数 s t r c a t和 s t r v c a t,或 连 接 运 算 符 []。这里重点讲解 s t r c a t函数的用法。 s t r c a t函数横向连接字符串,调用格式为: str = strcat( s 1,s 2,s 3,…)

s 1= [a ;b ]; s 2= c ;

例如,有一个字符数组 s 1 和一个字符串 s 2:

数相同的字符数组,然后各行相连,组成新的字符数组。

① 当s 1,s 2,s 3,…为字符数组时,所有字符数组的行数必须相等,各行相连组成新的字 符数组;若 s 1,s 2,s 3,…中包含单个字符串,则将单个 字 符 串 纵 向 扩 展 成 与 其 他 字 符 数 组 行

strcat( s 1, s 2) ans = ac bc

空 航

将s 1和s 2 相连:

② 当s 1,s 2,s 3,…中至少有一个为字符串单元数组时, s t r c a t函数连接字符数组或字符 , , ,… 串单元数组的对应单元,并返 回 一 个 单 元 数 组。s 必 须 有 相 同 的 尺 寸,除 非 为 单 1 s 2 s 3

个字符串。

s 1 = {a ; b } s 1= a b s 2 = [c ; d ] s 2= c d s 3 = ef ;

连接 s 1,s 2,s 3:

str = strcat( s 1,s 2,s 3) str =


acef bdef iscellstr( str)

ans = 1

【注意】 s t r c a t与连接运算符[]都能连接字符数组,但它们有重要的区别: a)连接字符数组时, s t r c a t先将每个字符串尾部的空格去掉再连接;而[]会原封不动地将

字符数组连接起来。如: s 1= a ; s 2 = bc ; [ s 1s 2]

ans = abc strcat( s 1, s 2)

ans = abc

b)当 s 1,s 2,s 3,…中含有字符串单元数组时, s t r c a t不会 改 变 单 元 数 组 的 维 数,但[]会 将每个输入当做一个单元数组,然后增加维数。

ans = ab

ans = a b [{a },{b }] ans = a b

[{a }, b ]

[]增加单元数组的维数:

空 航

strcat({a }, b ) ans = ab strcat({a },{b })

s t r c a t不改变单元数组的维数:

c)[]可以连接行数或列数相等的矩阵: a= [ 12;34] a= 1 2 3 4 b= [ 56] b= 5 6 [ a;b] % 纵向连接 ans = 1 2 3 4


5 [ ab ] ans = 1 3

6 % 横向连接 2 4

5 6

2)s t r cmp。s t r cmp 函数的使用有以下 3 种情况: ① 比较字符串是否相同。相同,返回逻辑 1;否则,返回逻辑 0。例如: strcmp(ab , ab ) ans = 0

% 第 1 个字符串后面多一个空格

【注】 a)比较字符串是否相同还可以用i s equa l函数。上面的语句等价于:

isequal(ab , ab ) ans = 0

% 第 1 个字符串后面多一个空格

出 学 大 天 空 航

isequal(ab ,[ 979832]) ans = 1 strcmp (ab ,[ 979832]) ans = 0

s t r cmp 与i s equa l函数的区别在 于: i s equa l实 质 是 将 字 符 串 转 换 为 Un i c ode 码 后 再 进 行 比较。比较下面两条语句的结果:

b)查找字符串单元数组的单元内容,可使用 s t r cmp、 i smembe r或 s t rma t ch 函数。如:

a = dafei ; b = liuqin ; C= { a;b}; index_b = find( strcmp( C,b)) index_b = 2 [ true_falseindex]= ismember( b,C) true_false =

% 创建一个字符串单元数组 % 查找内容为字符串 b 的单元

% 查找内容为字符串 b 的单元

1 index = 2 strmatch( b,C) ans = 2

② 比较字符串与字符串单元数组。字符串与单元数组的每个单元相比较,返回一个逻辑 矩阵。例: strcmp({ab ; cd }, cd ) ans = 0 1


③ 比较两个单元数组。若一个单元数组尺寸为1×1,则将它与多维单元数组的每一维相 比较,返回一个逻辑矩阵;若两个单元数组都是 多 维,则 它 们 必 须 同 维,对 应 单 元 相 比 较,返 回 一个逻辑矩阵。 例如: strcmp({ab ;cd },{cd }) ans = 0 1 strcmp({ab ;cd },{ab ;cd }) ans = 1 1

3)sp r i n t f和 s s c an f。sp r i n t f和 s s c an f函数有些类似于 C 语言中的 p r i n t f和 s c an f函数。 [ s, errmsg]= sprintf( format, A,…):输出格式化的数据到字符串; A = sscanf( s,format)或 A = sscanf( s,format,size):按格式读字符串。

格式字符串f o rma t以初始化字符 % 开始,并依次包含以下可选或必要的元素:

① 标志位(可选); ② 宽度和精度域(可选);

空 航

③ 转换字符(必要)。 图 1. 4 所示为格式字符串示意图。

图 1. 4 格式字符串示意图

标志位 -

+

标志位控制输出的对齐方式,可能的取值见表 1. 22。 含

左靠齐 右靠齐

表 1. 22 标志位

%-5. 2d

%+5. 2d

标志位 0

前导零

%05. 2 f

域宽是指数字字符串打印的最少位数;精度是指数字字符串小数点后保留的位数。 有效的转换字符见表 1. 23。

转换字符 %c

%d

%e

%E

单个字符

表 1. 23 转换字符 转换字符

十进制记数

%G

指数记数法,小写字母 e

%o

指数记数法,大写字母 E

%s

%E 和 %f的紧凑模式,小数点后无意义的 0 不输出

无符号八进制记数 字符串


续表 1. 23 转换字符 %f %g

转换字符

浮点记数 %e和 %f的紧凑模式,小数 点 后 无 意 义 的 0 不输出

%u

无符号十进制记数

%X

十六进制记数,使用大写 A~F

十六进制记数,使用小写 a~f

%x

另外,还可使用转义字符,见表 1. 24。

表 1. 24 转义字符

转义字符

\b

转义字符 \ t

退格符

\ f

反斜线

换行符

\r

跳格符

\\

换页符

\n

单引号 %%

百分号

回车符

例如:

sprintf(6=\n%dx%d ,2,3) ans = 6= 2x 3 data = [ 85170524681035]; sprintf(%02X %02X %02X %02X %02X %02X %02X %02X %02X ,data)

空 航

ans = 55AA05020406080A23

4)eva l、 f eva l和 eva l i n。 MATLAB 提供了一种非常重要的特殊表达式:字符串计算表达 式。计算字符串有 3 个函数: eva l在 当 前 工 作 空 间 内 计 算 包 含 表 达 式 的 字 符 串; f eva l在 当 前

达式字符串。例如:

工作空间内执行字符串或函数 句 柄 代 表 的 函 数; eva l i n在当前空间或基本工作空间内执行表 t = 0 :. 1 :2*pi; x = sin( t); t)); y = eval(sin( z = feval(@sin,t); % 或 z = feval(sin ,t); evalin(base , u = sin( t);); % 在基本工作空间内执行 v = evalin(caller , sin( t)); % 在当前空间内执行

生成的变量 x、 z、 u 和 v 完全相同,如图 1. 5 所示。 y、

eva l调用 函 数 时(例 如 调 用 上 面 的 s i n 函 数)避 开 了 MATLAB 分 析 程 序 的 严 格 检 查,可 能产生不可捕捉的错误和不希望看到的结果,故不提倡使用。 【注意】 eva l的使用非常灵活: ① 从字符串中提取出变量。

eval(a = 2 ) a= 2


图 1. 5 p l o t( l o t( z)的运行结果 y)与 p

② 将字符串转换为数字。

n=eval(12345678 ) n= 12345678

③ eva l和f eva l只在当前工作空间 执 行 表 达 式 语 句。假 定 当 前 空 间 为 函 数 空 间:若 要 在 基本工作空间执行 MATLAB 语句,使用 eva l i n 函 数;若 要 在 基 本 工 作 空 间 执 行 赋 值 表 达 式, 除可使用 eva l i n 函数外,还可使用前面讲到的 a s s i i n 函数。 gn

5)f i nds t r和 s t r f i nd。f i nds t r和 s t r f i nd 函 数 都 只 能 对 一 维 字 符 数 组 (即 字 符 串)进 行 操 作。它们的区别就是f i nds t r会自动比较输入的两个字符串的长度,然后在长的字符串中搜索

空 航

短的字符串,对两个字符串的顺序没有要求;而 s t r f i nd 要求在第 1 个字符串中搜索第 2 个。 f i nds t r和 s t r f i nd 都区分大小写,如果没有找到匹配的字符串,就返回空矩阵。例如:

strfind(ilovematlab , love ) ans = 2 findstr(ilovematlab , love ) ans = 2 findstr(love , ilovematlab ) ans = 2 findstr(ilovematlab , Love ) ans = []

【注】 在未来的 MATLAB 版本中,将会移除f i nds t r函数。 6)i s s t r op。i s s t r op 函数使用非常灵活。其调用格式为: pr pr tf = isstrprop(str , category )

字符类型 c 25。 a t ego r y 的所有可能取值见表 1.


表 1. 25 i s s t rp r op 的字符类型取值 类型取值

a l phanum cn t r l

r i n t p

r aph i c g l owe r

数字,如 0

数字或字母,如 0 、a

控制字符,如 cha r( 0: 20)

图形字符,包括空格字符,即 cha r( 32)

图形字符,即不包括下列 字 符 的 任 意 其 他 字 符: una s s i c e,l i nes epa r a t o r,pa r ag r aphs epa r a gned,spa

t o r,c on t r o lcha r a c t e r s,Un i c odef o rma tc on t r o lcha r a c t e r s,p r i va t eus e r-de f i nedcha r a c t e r s,Un i c ode sur r oga t echa r a c t e r s,Un i c odeo t he rcha r a c t e r s 小写字母,如 a

uppe r

大写字母,如 A

wspa c e

空线间隔符,包括:

t punc

xd i i t g

标点符号,如 ,

\ t

有效的十六进制数,如 F

\n

\r

\v

\ f

d i i t g

字母,如 a

a l pha

类型含义

7)num2s t r、 s t r 2num 和s t r 2doub l e。num2s t r和s t r 2num 函数,在 GUI设计中经常使用, 必须重点掌握。如:

天 空 航

ans = 3. 1416 num 2str(dafei ) ans = dafei str 2num(3. 14159e 0) ans = 3. 1416 str 2num([12 ;34 ])

ans = 3. 142 num 2str( 4f ) pi,%7.

num 2str( eps) ans = 2. 2204e-016 num 2str( 3f ) pi,%7.

% 若输入本身就是字符串,直接返回所输入的字符串

ans = 1 2 3 4 str 2double(1. 1) ans = 1. 1000 str 2double(11 ) ans = NaN

【注意】 s t r 2num 与 s t r 2doub l e都可以将字符串转换为数值,但是 s t r 2num 为矩阵运算, 可以生成数值矩阵,而 s t r 2doub l e为标量运算,只 能 生 成 一 个 数 值。因 此,当 需 要 生 成 一 个 数


值时,虽然 s t r 2num 和 s t r 2doub l e都可以用,但是 s t r 2doub l e的运算速度要快些。

数据类型转换函数还包括一些进制转换函数,在 GUI设计中经常使用,见表 1. 26。 表 1. 26 进制转换函数

de c 2b i n de c 2hex de c 2ba s e b i n2de c

调用格式

s t r= de c 2b i n( d)

返回整数 d 的二进制表 示 为 字 符 串。d 为 小 于 252 的 非 负 整 数; n为

s t r= de c 2b i n( d, n)

返回的二进制表示最少的位数,高位补 0

s t r= de c 2hex( d)

转换十进制数 d 为 十 六 进 制 形 式, d 为 小 于 252 的 非 负 整 数; n为返回

s t r= de c 2hex( d, n)

的十六进制表示最少的位数,高位补 0

s t r= de c 2ba s e( d, ba s e)

转换非负整数 d 为指定的进制格式, ba s e为 d 为小于 252的非负整数;

s t r= de c 2ba s e( d, ba s e, n)

n为s t r的最少位数,高位补 0 s t r为字符串; 2 与 36 之间的整数;

b i n2de c( b i na r t r) ys

将二进制字符串转换为十进制数

o c t 2de c

d= o c t 2de c( c)

将八进制矩阵转换为同维的十进制矩阵; c为数字型

ba s e 2de c

ba s e) d = ba s e 2de c(s t r n,

将 ba s e进制的字符串转换为十进制

d = hex2de c(hex_va l ue )

将十六进制字符串转换为十进制浮点型整数, d<252

hex2de c

【注意】 b i n2de c、 hex2de c和 ba s e 2de c函数,会自动忽略输入字符串中的空格符。

下面对以上函数分别举例说明。

京 北

dec 2hex( 30) ans = 1E

② 十进制转换为十六进制:

③ 十进制转换为八进制: dec 2base( 30,8) ans = 36

④ 二进制转换为十进制: bin 2dec( 11110 ) ans = 30

⑤ 十六进制转换为十进制: hex 2dec(1e ) ans = 30

空 航

dec 2bin( 30) ans = 11110

① 十进制转换为二进制:


⑥ 八进制转换为十进制: a=11; oct 2dec( a) ans = 9

⑦ 二进制转换为八进制: dec 2base( bin 2dec(11110 ),8) ans = 36

先将二进制转换为十进制,再将十进制转换为八进制。 ⑧ 将八进制转换为十六进制:

dec 2hex( oct 2dec( 36)) ans = 1E

先将八进制转换为十进制,再将十进制转换为十六进制。

4.结构数组 与 C 语言类似,MATLAB 也具有结 构 类 型 的 数 据。结 构 数 组,也 称 为 结 构 或 结 构 体,是

空 航

一种用字段 来 容 纳 数 据 的 MATLAB 数 组。 结 构 数 组 的 字 段 能 包 含 任 何 类 型 的 数 据,如 图 1. 6所示。

图 1. 6 一个简单的结构体

创建结构有两种方法:

① 使用点号(.)运算符。如创建一个名为 da f e i的学生的成绩信息:

results. name= dafei ; results. rank=2; results. score= [ 889998]; results results = name: dafei rank:2 score:[ 889998]

结构也是一种数组,上例创建的 r e su l t s是一个 1×1 的结构数组。 访问结构的字段可以采用点号运算符:


results. name ans = dafei results.([ra ans = 2

nk ])

% 采用字符串作为字段名

如果要再添加一个名为l i uq i n 的 学 生 的 成 绩 信 息,就 将 结 构 r e su l t s 扩 展 为 1×2 的 结 构 数组: results( 2). name= liuqin ; results( 2). rank=1; results( 2). score= [ 988999];

results results = 1x 2structarraywithfields:

name rank score

对于多维结构数组,当输入 结 构 数 组 名 字 时,MATLAB 不 会 显 示 单 个 字 段 的 内 容,而 只

显示结构数组包含的各类信息概略。这些信息页可以通过f i e l dname s函数获取:

空 航

fieldnames( results) ans = name rank score

数组中所有的结构都有相 同 的 字 段。 扩 展 一 个 结 构 数 组 时,MATLAB 用 空 矩 阵 填 充 未

指定的字段。

② 利用 s t ruc t函数创建结构数组。s t ruc t函数调用格式:

1 ,{}, field 2 ,{},…) s = struct(field

用指定字段f i e l d1、 f i e l d2 等创建一个空结构。

如果要创建一个没有字段的结构数组,使用下列语句: 创建 0×0 的无字段结构数组: struct([]) ans = 0x 0structarraywithnofields.

创建 1×1 的无字段结构数组: struct() ans = 1x 1structarraywithnofields. s = struct(field 1 ,values 1, field 2 ,values 2,…)

f i e l d1、 f i e l d2 等为字段名, va l ue s 1、 va l ue s 2 等为对 应 的 字 段 数 据,必 须 是 同 样 大 小 的 单 元 数组或标量; s为生成的结构数组。


s t ruc t函数用指定的字段名和字段值创建一个结构数组。如果字段值均为同维的单元数

组, s的大小与单元数组的大小一样;如果字段值只是标量,不含单元数组,那么s为1×1 的结 构数组。如:

创建 1×1 的结构数组: 21]) s=struct(names ,{{dafei ,liuqin }},ranks ,[ s= names:{dafei liuqin } ranks:[ 21]

创建 1×2 的结构数组: s 2=struct(names ,{dafei ,liuqin },ranks ,{ 2, 1}) s 2= 1x 2structarraywithfields: names ranks

有关结构数组的函数见表 1. 27。

s t r uc t 2 f i e l dname s i s s t r uc t s t r uc t

s= rmf i e l d( s, FIELDS)

c e l l c= s t r uc t 2c e l l( s)

将输入的 X 分别分配给每个输出,即 Y1=X,Y2=X, Y3=

s= rmf i e l d( s,f i e l d)

空 航

rmf i e l d

t f=i s f i e l d( A,f i e l d)

i s f i e l d

[ Y1, Y2, Y3,…]= de a l( X)

[ Y1, Y2, Y3,…]= de a l( X1, X2, X3,…)

name s= f i e l dname s( s)

de a l

调用句型

… X,…或将 X1分配给 Y1, X2分配给 Y2, X3分配给 Y3, 检查结构数组 A 中是否含字段名为f i e l d 的字段

从结构体 s中移除指定的字段f i e l d;或 FIELDS 为一个字

段名组成的字符数组或字符单元数组,移除 s中多个字段 将结构数组 s转换为单元数组 返回结构数组的字段名,或对象的属性名

name s= f i e l dname s( ob j)

表 1. 27 有关结构数组的函数汇总

t f=i s s t r uc t( A)

检查 A 是否为 MATLAB 结构数组

s=s t r u c t(f i e l d 1, v a l u e s 1,f i e l d 2, v a l u e s 2,…)

创建结构数组

s=s t r uc t(f i e l d1 ,{},f i e l d2 ,{},…)

5.单元数组 单元数组是一种特殊数组,它为一个数组中 存 储 不 同 类 型 的 数 据 提 供 了 机 制。所 谓 单 元 数组,是 在 一 个 数 组 中 包 含 多 个 单 元( c e l l),每 个 单 元 作 为 一 个 独 立 的 存 储 单 元 存 储 数 据,如 图 1. 7所示。

图 1. 7 单元数组示意图


在结构数组中,从命名字 段 中 获 取 信 息;而 在 单 元 数 组 中,通 过 矩 阵 索 引 操 作 获 取 数 据。

如 A{ 2, 3}表示单元数组 A 第 2 行第 3 列的单元内容。

创建单元数组有使用大括号{}和使用 c e l l函数两种方法。

① 使用大括号赋值语句。此时有两种方法给单元数组赋值:单元索引和内容索引。 例如,创建一个如图 1. 8 所示的单元数组:第 1 个单元为一个 1×2 的单元数组,第 2 个单

元为一个 2×1 的字符数组,第 3 个单元为一个 2×3 的数字矩阵。

图 1. 8 单元数组举例

单元索引:赋值语句左边,像普通数组的索引一样,将单元的下标括在括号中;右边把单元 内容放在花括号中。

版 出 学

[ 2x 3double]

[ 2x 1char]

A A= { 2x 1cell}

clearA A( 1)= {{dafei ;liuqin }}; A( 2)= {[B ;A ]}; A( 3)= {[ 889998; 988999]};

clearB B{ 1}= {dafei ,liuqin }; { B 2}= [B ;A ]; B{ 3}= [ 889998; 988999]; B B= { [ 2x 1cell} 2x 1char]

空 航

内容索引:赋值语句左边,把单元的下标放在花括号中;右边,指定单元内容。

[ 2x 3double]

② 使用 c e l l函数初始化单元数组。c e l l调用格式见表 1. 28。 表 1. 28 c e l l函数调用格式

调用格式 c= c e l l( n)

c= c e l l( m, n)

c= c e l l([ mn])

c= c e l l( m, n, e l l([ mnp …]) p,…) c= c c= c e l l( s i z e( A))

例如: C=cell( 1, 3); C C=

格式说明 创建一个 n×n 的各单元为空矩阵的单元数组

创建一个 m×n 的各单元为空矩阵的单元数组

创建一个 m×n×p× …的各单元为空矩阵的单元数组 创建一个与 A 同维的各单元为空矩阵的单元数组


[] [] [] C( 1)= {{dafei ,liuqin }}; C( 2)= {[B ;A ]}; C( 3)= {[ 889998; 988999]};

C C= { 1x 2cell}

[ 2x 1char]

[ 2x 3double]cell

98 99

【思考】 单元数组占用的内存空间如何计算?

celldisp( C) C{ 1}{ 1}= dafei C{ 1}{ 2}= liuqin C{ 2}= B A C{ 3}= 88 99 98 89

如果想查看单元数组的全部内容,使用 c e l l d i sp 函数:

可以把每个单元数组想象成一个链表,而每个单元(即 链 表 的 节 点)想 象 成 一 个 类 或 者 结 构体。大家知道,链表不一定存储在连续的内存 块 中,但 每 个 节 点 为 一 个 数 据 结 构,必 须 存 储

在连续的内存中。因此,单元数组不一定存储在连续的内存块中,但单元数组的每个单元必须

空 航

存储在连续的内存中。

对于一个已定义且初始化了的单元数组,每个单元都附带了两个位置指针(类似于链表指

针,共 4 字节),来指明该单元所在位置,另外还有一块 56 字节的区域用来记录单元信息,比如单

元的长度,数值类型等。因此每个单元的长度应该等于单元内元素的实际长度,加上 60 字节。

对于一个仅定义而未初始化的单元数组,每个单元仅附带一个 4 字节的位置指针,即每个

未初始化的单元的长度应该等于 4 字节。 有关单元数组的函数,见表 1. 29。

表 1. 29 有关单元数组的函数汇总

c e l l

c e l l d i sp

c e l l 2s t r uc t c e l l f un

c e l l l o t p i s c e l l

num2c e l l ma t 2c e l l

c e l l 2ma t

调用格式 见表 1. 28

c e l l d i sp( C)

创建空的单元数组 c e l l d i sp( C, name)

s= c e l l 2s t r uc t( c, f i e l ds, d im) D =c e l l f un(f name , C)

D=c e l l f un(s i z e, C, k)

显示单元数组的内容 转换单元数组为结构数组 将函数应用到单元数组的每个元素

c e l l l o t( c) c e l l l o t( c,l egend ) hand l e s=c e l l l o t(…) p p p

显示单元数组的图形描述

c= num2c e l l( A)

转换数值数组为单元数组

t f=i s c e l l( A)

c= ma t 2c e l l( x,m,n) m =c e l l 2ma t( c)

c= num2c e l l( A, d ims)

检查数组 A 是否为单元数组 转换矩阵为矩阵单元数组 转换矩阵单元数组为单个矩阵


表 1. 29 中, num2c e l l、 ma t 2c e l l和 c e l l 2ma t需要重点掌握,使用方法举例如下:

( 1)num2c e l l

num2c e l l函数的调用格式为: C = num 2cell( a)

将数值数组 a转换为单元数组 C,且 C 的每个单元尺寸为 1×1。

a= [ 123; 456] a= 1 2 3 4 5 6 b = num 2cell( a) b= [ [ [ 1] 2] 3] [ ] [ ] [ 4 5 6] C = num 2cell( a,dim)

将数值数组 A 转换为单元数组 C。若 d im=1, C 的每个单元尺寸为 1×s i z e( A,d im);若

出 学

[ 2x 1double]

( 2)ma t 2c e l l

空 航

a= [ 123; 456]; c = num 2cell( a,1) c= [ [ 2x 1double] 2x 1double] ( , ) d = num 2cell a 2 d= [ 1x 3double] [ 1x 3double]

d im=2, C 的每个单元尺寸为 s i z e( A,d im)×1。

ma t 2c e l l函数的调用格式为:

C = mat 2cell( x,m,n)

将矩阵 x 转换成单元数组 C。矩阵 x 的行按向量 m 来依次分解, x的列按向量 n来依次

分解。单元数组 C 的尺寸与 m、 n 的关系为: s i z e( C)= ( sum( m),sum( n))。矩阵 x 可以是二 维数值数组、二维字符数组等。

a = [abc ; bca ; cab ] a= abc bca cab b = mat 2cell( a,[ 12],3) b= abc [ 2x 3char] b = mat 2cell( a,3,[ 12]) b= [ [ 3x 1char] 3x 2char]


( 3)c e l l 2ma t

c e l l 2ma t函数的调用格式为: m = cell 2mat( C)

将单元数组 C 转换为单个矩阵 m。要求单元数组 C 的每个单元列数必须相等。

a = {[ 12],[ 345];[ 67;12],[ 8910;345]} a= [ [ 1x 2double] 1x 3double] [ ] [ 2x 2double 2x 3double] ( ) b = cell 2mat a b= 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5

6.函数句柄 函数句柄是一种特殊的数据类型,它 提 供 了 间 接 调 用 函 数 的 方 法,类 似 于 C 语 言 中 的 指

针,只不过这里是指向一个函数而已。

函数句柄包含了函数的路径、函数名、类型以 及 可 能 存 在 的 重 载 方 法,必 须 通 过 专 门 的 定

义创建,而一般的图像句柄是自动建立的。

可使用函数句柄来调用 其 他 函 数,也 可 以 将 函 数 句 柄 存 储 在 数 据 结 构 中,方 便 以 后 使 用

(例如句柄图形的回调函数)。

创建函数句柄使用 @ 或者 s t r 2 f unc命令。采用 符 号 @ 创 建 函 数 句 柄,是 在 函 数 名 前 加 一

空 航

个“@ ”标志,并且不能附加函数的路径,即函数句柄 = @ 函数名。 MATLAB 映射句柄到指定的函 数,并 在 句 柄 中 保 存 映 射 信 息。 由 于 没 有 附 加 函 数 的 路

径信息,如果同一个名字的函数有多个,函数句柄映射到哪个函数呢?

这取决于函数调用的优先原则。函数调用的优先级从高到低排列如下:

搜索。

① 变量:调用 优 先 级 最 高。 MATLAB 搜 索 工 作 空 间 看 是 否 存 在 同 名 变 量,有 则 停 止

② 子函数( sub f unc t i on)。 ③ 私有函数( i va t ef unc t i on)。 pr

④ 类构造函数( c l a s sc ons t ruc t o r)。 ⑤ 重载方法( ove r l oadedme t hod)。

⑥ 当前目录中的同名函数。 ⑦ 路径中其他目录中的函数:调用优先级最低。

如果要查询同名函数中究竟哪个被调用了,用 wh i ch 函数查询。如: whichzoom D: \MATLAB 7\toolbox \matlab \graph 2d \zoom. m

当一个函数句柄被创建时,它将记录函数的详细信息。因此,当使用函数句柄调用该函数 时,MATLAB 会立即执行,不进行文 件 搜 索。 当 反 复 调 用 一 个 文 件 时,可 以 节 省 大 量 的 搜 索 时间,从而提高函数的执行效率。 函数句柄可用来标识子函数、私有函数和嵌套函数。一般这些函数对于用户来说都是“隐


藏”的,这些标识对于用户正确使用这些函数非常有用。例如,当编写一个含有子函数的 M 文 件时,可以为子函数创建一个句柄,并作为 主 函 数 的 一 个 输 出 参 数 提 供 给 用 户。 下 面 的 M 文 件函数框架演示了一个在主函数中返回子函数句柄的例子: functionout=myfunction( select) switchselect case case 1 out = @fun 1; case case 2 out = @fun 2; otherwise out = []; end functiona=fun 1( b, c) ……

functiond=fun 2( e, f) ……

MATLAB 中用函数句柄作为操作对象的函数,如表 1. 30 所列。

s ave

l oad i s a

i s equa l f eva l

空 航

s t r 2 f unc

s= f unc 2s t r( f hand l e)

函数说明

得到函数句柄的信息:函数名、类型、文件名等 由函数句柄构造函数名字符串

f hand l e= s t r 2 f unc(s t r)

由函数名字符串构造函数句柄

l oad(f i l ename )

从一个 . ma t文件加载函数句柄到当前工作空间

i l ename ) s ave(f

f unc 2s t r

S =f unc t i ons( f unhand l e)

K =i s a( ob l a s s_name ) j,c

f unc t i ons

调用格式

t f=i s equa l( A, B,…)

表 1. 30 用函数句柄作为操作对象的函数

[ eva l( f hand l e,x1,…,xn) y1,y2,…]= f

保存当前工作空间的函数句柄到一个 . ma t文件 检查变量是否包含函数句柄 检查两个函数句柄是否是相同函数的句柄 采用参数 x1,…,xn 来执行函数句柄

例如,创建一个正弦函数的函数句柄: h_sin=str 2func(sin );

执行 s i n 函数可使用f eva l函数: /2) feval( h_sin, pi ans = 1

再如,若在当前目录下新建一个 M 文件函数 p l o tFHand l e. m:

functionx = plotFHandle( fhandle,data) ( , ( ) ) plot data fhandle data

保存后,在命令行输入:


t=-pi: 0. 01: pi; t) plotFHandle(@sin,

结果显示如图 1. 9 所示。

【思考】 使用函数句柄有什么好处呢? ① 提高 运 行 速 度。 因 为 MATLAB 对 函数的调用每次都 是 要 搜 索 所 有 的 路 径,而 这些路径非常多,所 以 如 果 一 个 函 数 在 用 户 的程序中 需 要 经 常 用 到,则 使 用 函 数 句 柄, 会提高运行速度。 ② 使用可以与变量一样方便。比如说, 用户在某个目录运 行 后,创 建 了 该 目 录 的 一 个函数句 柄,当 用 户 转 到 其 他 目 录 下 时,创 建的函数句柄还是 可 以 直 接 调 用 的,而 不 需

要把那 个 函 数 文 件 复 制 过 来。 因 为 在 用 户 创建的函数中,已经包含了路径。

图 1. 9 使用句柄的一个实例

例如,对于上面创建 的 函 数 句 柄 h_s i n,

空 航

functions( h_sin) ans = function: sin type: simple file:

可以用f unc t i ons来查看这个f unc t i on:

7.日期和时间 MATLAB 中 表 示 日 期 和 时 间 信 息 有 3 种 格 式:日 期 字 符 串、串 行 日 期 数 ( s e r i a lda t e

函数相互转换。

numbe r s)和日期向量。用户可选择其中任何一种格式显示日期和时间,而且它们之间可通过 ( 1)当前的日期或时间

3 种 MATLAB 的日期或时间格式见表 1. 31。

表 1. 31 当前的日期或时间函数

日期和时间格式

当前日期与时间函数

日期字符串

da t e

串行日期数 日期向量

例如,要查看当前的日期: date ans = 18-Jan-2009

now

c l o ck

18-J an-2009 7. 3379e+005

[ 2009118

23

31

36]


( 2)日期与时间的格式转换

日期与时间的格式转换函数有以下 3 个:

① da t enum:将输入转换为串行日期数; ② da t e s t r:将输入转换为日期字符串;

③ da t eve c:将输入转换为日期向量。 最常用的是将输入转换为日期字符串,即 da t e s t r函数。有时用户需要获取当前的日期和

时间字 符 串,然 后 提 取 出 一 部 分,作 为 自 动 保 存 文 件 时 的 默 认 文 件 名,这 就 需 要 用 到 da t e s t r

函数。

da t e s t r函数的调用格式为: str = datestr( DT)

转换串行日期数或日期向量为日期字符串。例如:

datestr( date) ans = 12-Apr-2009 datestr( now)

ans = 12-Apr-200916: 28: 10 datestr( clock)

ans = 12-Apr-200916: 28: 15

str = datestr( DT,dateform)

空 航

转换串行日期数、日期向量或日期字符串 DT 为指定日期格式 da t e f o rm 的字符串s t r。指

1

2

3

4

5

6

0

日期格式的数字形式

定格式 da t e f o rm 可以为一个 0~31 的正整数或一个字符串,默认值为 0,见表 1. 32。

01/19/09

13

19 J an 2009

mmm

J an

mm

01

m

mm/dd

d

12

mm/dd/yy

dd mmm yyyy

9

11

19 J an 200900: 37: 26

dd

10

日期格式的字符串形式

dd mmm yyyyHH:MM: SS

7

8

表 1. 32 日期格式

ddd

J

01/19 19

Mon M

yyyy

2009

mmmyy

J an09

yy

HH:MM: SS

09

00: 37: 26


续表 1. 32 日期格式的数字形式

日期格式的字符串形式

14

HH:MM: SSPM

12: 37: 26AM

16

HH:MM PM

12: 37AM

HH:MM

15

00: 37

17

QQ YY

19

dd/mm

19/01

21

mmm. dd. SS yyyyHH:MM:

J an. 19. 200900: 37: 26

mm/dd/yyyy

01/19/2009

18

Q1 09

QQ

Q1

dd/mm/yy

20

22

19/01/09

mmm. dd. yyyy

23

24

dd/mm/yyyy

26

yyyy/mm/dd

J an. 19. 2009 19/01/2009

yy/mm/dd

27

09/01/19

25

QQ YYYY mmmyyyy

28

yyyy mm dd

31

SS yyyy mm ddHH:MM:

yyyymmddTHHMMSS

例如:

J an2009

2009 01 19

20090119T003726

2009 01 1900: 37: 26

datestr( now, 29) ans = 2009-05-21 datestr( now,HH: MM: SS ) ans = 11: 55: 21

Q1 2009

空 航

30

29

2009/01/19

( 3)其他与日期和时间相关的函数

除上面 介 绍 的 基 本 日 期 与 时 间 函 数 外,还 有 一 些 其 他 与 日 期 和 时 间 相 关 的 函 数,

见表 1. 33。 函

add t oda t e c a l enda r da t e t i ck eomday days d i f

表 1. 33 其他与日期和时间相关的函数 函数说明 修改日期数 返回指定年月的日历表 用日期作为坐标轴的标注 返回指定年月的最后一天 返回两个日期之间的天数

we ekday

函数说明 返回输入日期是一周的第几天

cpu t ime

返回 MATLAB 启动后使用的总 CPU 时间

e t ime

返回两个日期向量之间流逝的秒数

t i c, t o c

返回调用 t i c和 t o c函数之间流逝的时间


例如: calendar Jan2009 S M Tu W Th F 0 0 0 0 1 2 4 5 6 7 8 9 11 12 13 14 15 16 18 19 20 21 22 23 25 26 27 28 29 30 0 0 0 0 0 0 tic, sin( 0: 0. 1: 2*pi)), toc plot( Elapsedtimeis3. 031000seconds. weekday( now) ans = 7 a 1 = clock;pause( 1); etime( clock,a 1)

S 3 10 17 24 31 0 % 全局定时器 % 返回今天( 2010-08-14)是星期几

ans = 1. 0160 a = datestr( now,29)

a= 2010-08-14 b= [ a( 1:4),-01-01 ]

b= 2010-01-01 daysdif( b,a)

% 返回 2010-08-14 是 2010 的第几天

空 航

ans = 225

1. 1. 3 矩阵操作

上面程序中, we ekday( now)返 回 的 结 果 为 7,表 示 今 天 是 一 个 星 期 的 第 2 天 (在 西 方 国 家,星期日是一个星期的第 1 天),即今天星期六。 MATLAB 中最基本的数据结构是矩阵。矩阵的二维数据结构,能非常容易就成倍地存取 数据元素。数据元素可以是数字、字符、逻辑真假或其他类型的 MATLAB 结构。 MATLAB 采

用这种二维的矩阵存取单个的数,用 1×1 的维数表示;也存储向量,用 1×n 的维数表示, n是

向量的长度。 MATLAB 还支持 大 于 二 维 的 数 据 结 构,这 种 数 据 结 构 在 MATLAB 中 称 为 数 组,本节仅简要讨论矩阵操作方面的知识。 1.创建矩阵 在 MATLAB 中,建立矩阵最简单的方法,是利用矩阵构造操作符:方括号[]。 在方括号中写入元素,元素之间用空格或逗号隔开,能建立矩阵的一行。如:

a= [ 12, 3] a= 1 2

3

在方括号中,每行之间用分号隔开,这样就创建了一个矩阵。如:


b= [1 b= 123 456

2

3 ;456 ]

可见,字符矩阵的每一行字符可被看成一个字符串。 将上面生成的矩阵 b 与下面的矩阵 c比较: char( 13) 456 ]

c= [123 c= 123 456

回车符的 ASCI I码为 13,所以 cha r( 13)就等价于回车。b 与 c 形式上完全一样。但如果

用s i z e函数查看它们的大小:

ans = 1

size( b) ans = 2 3 size( c)

7

常用的特殊矩阵函数见表 1. 34。

可见,矩阵在 M 文件中创建新行不能采用回车符,只能用分号。当然,如果在命令行采用 回车( En t e r)键创建新行,是可以的。

空 航

表 1. 34 常用的特殊矩阵函数

函数说明

创建一个全 1 的矩阵或数组

eye

创建一个对角线为 1,其余位置为 0 的矩阵

d i ag

r and

r andn r and i

r andpe rm r ande r r

a c cuma r r ay mag i c

创建一个全 0 的矩阵或数组

z e r o s

one s

从一个向量中建立对角矩阵 创建一个随机数在[ 0, 1]区间均匀分布的矩阵或数组 创建一个随机数为标准正态分布的矩阵或数组 创建一个由均匀分布的整数组成的矩阵。该函数为 r and i n t的新版函数 创建一个将 1~n 之间的整数随机排列的 1×n 维向量

生成位误差形式,可指定数据二进制序列中 0 或 1 的个数

将输入矩阵元素分布到输出矩阵指定位置,元素值可累加 创建一个元素值从 1~n2的 n 维方阵,使得行、列和对角线的数加起来相等

如: ones( 1, 5) ans = 1 1 1 zeros( 2, 3,uint 8)

% 生成 1 行 5 列的全 1 矩阵 1 1 % 生成 2 行 3 列 uint 8 型矩阵


ans = 0 0 0 0 rand( 2, 3)

0 0

ans = 0. 5828 0. 5155 0. 4235 0. 3340 randn( 2, 3)

0. 4329 0. 2259 % 生成 2×3 阶,正态分布的随机数组

2

3

1

6

9

5

4

7

ans = 8

ans = 0. 1746 0. 7258 2. 1832 -0. 1867 -0. 5883 -0. 1364 randi([ 0,1],3, 4) % 生成 3×4 阶,元素值为[ 01]之间整数,均匀分布的随机数组 ans = 0 0 0 0 1 1 1 0 0 1 1 1 randperm( 9) % 将 1~9 的整数随机排列

【注意】 使用 z e r os或 one s函数为矩阵预分配内存,可加 快 程 序 的 执 行。重 复 扩 展 数 组 的尺寸,会影响程序的性能。因为每增加一次数 组 的 尺 寸,会 花 费 更 多 的 时 间 分 配 内 存,而 且

这些内存很可能是不连续的,这将减慢对该数组的 任 何 操 作。更 好 的 方 法 是 预 估 数 组 的 极 限

空 航 航

end toc

clearx tic x( 1)=1; fori=1: 10000 x( i+1)=2*x( i);

尺寸,使用 z e r os或 one s函数预分配一块连续的内存给该数组。例如,新建一个 M 脚本文件:

运行该脚本,命令行显示结果如下: Elapsedtimeis0. 184538seconds.

如果在上面脚本函数中加一条预分配指令: clearx tic x=zeros( 1, 10000); ( ) ; x 1 =1 fori=1: 10000 x( i+1)=2*x( i); end toc

运行该脚本,命令行显示结果如下: Elapsedtimeis0. 016057seconds.


可见,预分配内存后的执行时间不到之前的 10% 。

2.连接矩阵 连接矩阵最简单的方法就是使用 方 括 号 []。C= [ A B]是 横 向 连 接 矩 阵 A 和 B,要 求 A

与 B 有相同的行数; C= [ A; B]是纵向连接矩阵 A 和 B,要求 A 和 B 有相同的列数。如: a= [ 484950]; b= [ 9899100]; [ a; b]

ans = 48 98

49 99

50 100

【思考】 如果连接的两个矩阵的数据类型不一样,会出现什么情况呢? 构造矩阵时,如果包 含 了 不 同 数 据 类 型 的 元 素,MATLAB 会 将 其 转 换 为 同 一 种 数 据 类

型,这涉及数据类型的预设优先级,见表 1. 35。

逻辑型

字符

非法

整数型

整数型

表 1. 35 数据类型之间的转换

单精度

单精度

单精度

单精度

双精度

双精度

单精度

双精度

逻辑型

整数型

单精度

字符

字符

字符

字符

整数型

字符

整数型

整数型

单精度

字符

整数型

双精度

字符

整数型

逻辑型

非法

整数型

双精度

字符

数据类型

b= [ 98. 299. 6100. 9]; c= abc ; [ b; c]

空 航

由表 1. 35 可 知,如 果 矩 阵 A 为 doub l e 型 数 组, B 为 字 符 数 组,生 成 的 矩 阵 为 字 符 数 组。如:

ans = bcd abc

连接矩阵的函数见表 1. 36。 函

c a t

ho r z c a t

表 1. 36 连接矩阵的函数

函数说明 按指定的方向连接矩阵 横向连接矩阵

r epma t ve r c a t

函数说明 通过复制和拼接创建新矩阵 纵向连接矩阵

例如,[ r c a t( a,b),[ ab]等价于 c a t( 2, a, b)或 ho r z c a t( a, b), a; b]等价于 c a t( 1, a, b)或 ve [ a; a]等价于 r epma t( a,[ 21]),[ aa]等价于 r epma t( a,[ 12])。 3.重塑矩阵形状 获取矩阵的形状与大小信息,经常使用l eng t h、 s i z e、 nume l和 nd ims4 个函数。其说明见

表 1. 37。


表 1. 37 获取矩阵大小与形状的函数 函

函数说明

l eng t h

函数说明

s i z e

返回矩阵最长维的长度

nume l

返回矩阵的每一维长度

nd ims

返回矩阵的元素数

返回矩阵的维数

如:

重塑矩阵形状的函数,见表 1. 38。

a= [abc ;cde ] a= abc cde length( a) ans = 3 numel( a) ans = 6 size( a) ans = 2 3 ndims( a) ans = 2

空 航

表 1. 38 重塑矩阵形状的函数

函数说明

r e shape

重塑矩阵形状

f l i pud

沿纵轴左右翻转

f l i l r p

翻转矩阵 90 °

r o t 90

f l i im pd

t r anspo s e

c t r anspo s e

函数说明 按指定方向翻转 沿主对角线翻转 共轭转置

沿横轴上下翻转

下面重点讲解 r e shape函数。

r e shape函数常用的调用格式为:

B = reshape( A, m, n)或B = reshape( A,[ mn])

m、 n 为新矩阵的行数 和 列 数。A 为 原 矩 阵。矩 阵 在 内 存 中 是 逐 列 存 储 的, r e shape 函 数 先将原矩阵 A 排成一列数据,然后再构成[ m n]的矩阵 B。如果 A 的元素不是 m×n 个,将产 生错误。如:

a= [abc ;cde ] a= abc cde reshape( a,[ 3, 2]) ans = ad cc


be reshape( a, 3, 3) ??? Errorusing reshape ToRESHAPEthenumberofelementsmustnotchange. reshape( a,[ 2, 2]) ??? Errorusing reshape ToRESHAPEthenumberofelementsmustnotchange. B = reshape( A,…,[],…)

[]表示新矩阵的某一维长度待定,其长度由 r e shape函数计算。只能有一个[],而且也必

须保证新矩阵与原矩阵的元素个数相等。如: a= [abc ;cde ]; reshape( a, 1,[])

ans = acbdce reshape( a, 4,[]) ??? Errorusing reshape Productofknowndimensions,4,notdivisibleintototalnumberofelements,6.

【注】 重 塑 矩 阵 为 一 个 列 向 量,可 以 采 用“:”来 实 现;而 将 矩 阵 的 行 和 列 互 换,可 以 采 用

大 天 空 航 航 京 北

a = eye( 2) a= 1 0 0 1 b = a(:) b= 1 0 0 1 c= b c= 1 0

“”来实现。例如:

0

1

4.矩阵元素移位和排序 元素的排序,应用于矩阵、多维数组和字符串 单 元 数 组,能 对 任 何 一 维 的 元 素 按 升 序 或 降 序排列。元素的移位,只应用于矩阵。 矩阵元素移位和排序的相关函数见表 1. 39。

表 1. 39 矩阵元素移位和排序的相关函数

c i r c sh i f t

s o r t r ows

函数说明 循环移动矩阵的元素 按列值的升序或降序排列行

下面重点讲解 so r t和 s o r t r ows函数。

s o r t

i s s o r t ed

函数说明 对数组行或列进行升序或降序排列 确定数组元素是否排序


1)s o r t s o r t函数的调用格式为:

[ B,index]= sort( A,dim,mode)

对数组 A 的行或列进行升序或降序排列,返回排序后的数组 B,以及排序索引值i ndex。

若数组 A 为字符串单元数组,按字 符 的 ASCI I码 排 序;若 数 组 A 包 含 复 数,先 按 模 值 排

序,若模值相等则按相位排序;若数组 A 包含 NaN 元素, NaN 排在最后。

d im 可取值 1 或 2,默认值为 1。当 d im = 1 时,对矩阵 A 每列的 元 素 排 序;当 d im = 2 时,对矩阵 A 每行的元素排序。 mode 可取值 a s c end 或 d e s c e nd ,默认值为 a s c e nd 。mod s c e nd 为升序排列; mod e= e= a de s c end 为降序排列。 i nd e x 为排序的索引值。当 d im =1 时, i nd e x为 A 中元素在 B 中按列的索引值;当 d im =2

时, i ndex 为 A 中元素在 B 中按行的索引值。例如:

a= [ 157; 369; 246] a= 1 5 7 3 6 9 2 4 6 [ b,index]= sort( a)

5 6 4

1 3 2

大 天 空 航 航

ans = 7 9 6

1 4 6 2 5 7 3 6 9 index = 1 3 3 3 1 1 2 2 2 sort( a,2, descend )

b=

2)s o r t r ows s o r t r ows函数的调用格式为:

[ B,index]= sortrows( A,column)

对数组 A 的行,按列值的升序排列,返回排序后的数组 B,以及排序索引值i ndex。

若数组 A 为字符串单元数组,按字 符 的 ASCI I码 排 序;若 数 组 A 包 含 复 数,先 按 模 值 排

序,若模值相等则按相位排序。

c o l umn 为列向量,依次按 c o l umn 所指定的列,对数组 A 的行进行排序。 若c 某项值为正数, 按升序排列; 若c o l umn o l umn 某项值为负数,按降序排序。

i ndex 为排序的索引值。i ndex 满足恒等式: B == A( i ndex(:),:)。 例如: A = randi([ 0,100],6,7); A( 1: 4, 1)=95;

% 随机生成矩阵 A % 修正矩阵 A


A( 5: 6, 1)=76; A( 2: 4, 2)=7; A( 3, 3)=73

A=

95 4 55 37 49 82 35 95 7 29 63 44 80 94 95 7 73 78 45 65 88 95 7 19 8 30 38 55 76 65 69 93 51 81 62 76 45 18 78 51 53 59 B = sortrows( A,[ 12])% 先按第 1 列的升序对行排序;当列元素相等时,再按第 2 列的升序对行排序 B= 76 45 18 78 51 53 59 76 65 69 93 51 81 62 95 4 55 37 49 82 35 95 7 29 63 44 80 94 95 7 73 78 45 65 88 95 7 19 8 30 38 55 C = sortrows( A,-3) % 按第 3 列的降序对行排序

C=

空 航

95 7 73 78 45 65 88 76 65 69 93 51 81 62 95 4 55 37 49 82 35 95 7 29 63 44 80 94 95 7 19 8 30 38 55 76 45 18 78 51 53 59 [ D,index]= sortrows( A,[ 3 -2]) % 先按第3 列的升序对行排序;当列元素相等时,再按第2 列的 % 降序对行排序 D= 76 45 18 78 51 53 59 95 7 19 8 30 38 55 95 7 29 63 44 80 94 95 4 55 37 49 82 35 76 65 69 93 51 81 62 95 7 73 78 45 65 88 index = 6 4 2 1 5 3 isequal( D,A( index(:),:)) % 验证 index 恒等式 ans = 1

5.向量(数集)操作 行或列的维数为 1 的矩阵就是向量。数集在 MATLAB 中表现为元素互斥的向量。向量 和数集有一些特殊的操作函数,见表 1. 40。


表 1. 40 矩阵元素移位和排序的相关函数 函

函数说明

i n t e r s e c t

s e t d i f f

函数说明

s e t xo r

返回两个数集的交集

i smembe r i s s o r t ed

找出不在数集交集内的所有元素

un i on

检查数值是否为数集的元素 检查数集元素是否按序排列 找出在第 1 个向量内,不在第 2 个向量内的元素

返回两个数集的并集

un i que

去掉向量中重复的元素

假设存在两个数集(向量) A、 B 如下: A = 1 :10 A= 1 2 B = 6 :15 B= 6 7

3

4

5

6

7

8

9

10

8

9

10

11

12

13

14

15

空 航

数集 A 与 B 的关系如图 1. 10 所示。

由图 1. 10 可知:

图 1. 10 数集 A 与 B 之间的关系

A∩B= { 6,7,8,9,10}; 1,2,3,4,5}; A∩B= {

A∩B= { 1,2,3,, 4,5,11,12,13,14,15}; { , , , A∪B= 1 2 3 4,5,6,7,8,9,10,11,12,13,14,15}。

i n t e r s e c t( A,B)相当于集合运算 A∩B: intersect( A,B) ans = 6 7 8

9

10

s e t d i f f( A,B)相当于集合运算 A∩B: setdiff( A,B) ans = 1 2 3

4

5

s e t xo r( A,B)相当于集合运算A∩B: setxor( A,B)


ans = 1

2

3

4

5

11

12

13

8

9

14

15

un i on( A,B)相当于集合运算 A∪B: union( A,B) ans = 1 2 3

4

5

6

7

10

11

12

13

14

15

1. 1. 4 程序设计 1.函数参数 调用函数时,经常会有一些数据传递给被调 用 的 函 数,这 些 数 据 被 称 为 输 入 参 数;函 数 结 束时返回给调用函数的数据,称为输出参数。 MATLAB 按值传递参数,优化了任何不必要的 复制操作。

程序设计中,经常用到的函数见表 1. 41。

函数名

f unc t i on

定义 M 文件函数

va r a r i n g

na r t chk gou

验证输入参数个数 验证输出参数个数

na r gchk

i npu t name

返回函数输出参数个数

mf i l ename

na r t gou

va r a r t gou

返回函数输入参数个数

函数说明

接收函数的输入参数到单元数组 返回函数输出参数到单元数组

返回第 n 个输入参数的实际调用变量名 返回当前所执行 M 文件的文件名

空 航

na r i n g

函数说明

函数名

表 1. 41 函数文件相关函数

【注】 na rg i n 可以分解为 n+a r n,即 numbe r+a r t+i npu t,输入参数的个数。 g+i gumen 同理:

na r t可分解为 numbe r+a r t+ou t t; gou gumen pu na r r+a r t+ ( i npu t)+che ck; gchk 可分解为 numbe gumen

va r a r i n 可分解为 va r i ab l e+a r t+i npu t; g gumen va r a r t可分解为 va r i ab l e+a r t+ou t t。 gou gumen pu

1)f unc t i on 用来定义 M 函 数。 M 文 件 有 两 种 类 型:脚 本 与 函 数。 脚 本,是 包 含 一 系 列 MATLAB 语句的简单文件。它不能接受输入参数,输出结果显示在命令窗口,变量保存在基

本工作空间。而函数使用自己的局部变量,临时 建 立 自 己 的 函 数 空 间,接 受 输 入 参 数,也 能 返 回输出参数。 【注意】 ① 表 1. 41 中的所有函数,除 mf i l ename 能 用 于 所 有 M 文 件 外,其 他 函 数 均 只 能 用 于 M 函数中,而不能用于脚本中。

② 函数名必须由数字、字母或下画线 组 成,以 字 母 开 头。 例 如, a1.m,_1.m, 1a.m 等 都 是错误的函数名。 ③ 函数文件的文件名必须与函数名一 致。例 如,函 数 f un1. m,开 头 的 定 义 应 该 为: f unc ( ) 。 t i onva r a r o u t= f u n 1 v a r a r i n g g ④ 函数的输入参数可 以 是 数 值 数 组、字 符 数 组,但 不 能 是 单 元 数 组。 函 数 名、脚 本 文 件


名,甚至是 MATLAB 语句,都可以采用字符串的形式,传入另一函数。例如: run(f un1 )可以执行函数或脚本文件f un1. m; eva l(y = x ^ 2 )可以执行 MATLAB 语句

^ 2。 y= x 2)na r i n 与 na rgou t返回函数参数的个 数。函 数 体 中 的 na r i n 与 na r t函 数,能 够 在 g g gou 调用一个函数时,指明函数有几个输入和输出参数。调用格式: n = nargin

返回所在函数的输入参数个数。 n = nargin(fun )

返回函数f un 定义的输入参数个数;如果定义的输入参数个数不确定,返回 -1。

n = nargout

返回所在函数的输出参数个数。 n = nargout(fun )

返回函数f un 定义的输出参数个数。

例如,在当前目录下有一个 M 函数 my f un. m:

functionc = myfun( a,b) ; c= a+ b

在命令行键入:

myfun( 5,3) ans = 8

空 航

如果对函数 my f un. m 进行如下更改:

functionc = myfun( a, b) ifnargin 2 error(Notenoughinputarguments.); elseifnargin 2 error(Toomanyinputarguments.); else c=a+b; end

在命令行输入: myfun( 5, 3, 3) ??? Errorusing myfun Toomanyinputarguments. myfun( 5) ??? Errorusing myfun

Notenoughinputarguments.

3)va r a r i n 和 va r a r t传送或返 回 不 定 数 目 的 参 数。 有 一 些 函 数,输 入 的 参 数 或 返 回 g gou 到调用函数的参数个数不确定,这就需要用到 va r a r i n 和 va r a r t函数。调用格式: g gou functiony = bar( varargin)

如果在函数声明行将 va r a r i n 作为最后一个输 入 参 数,则 函 数 在 调 用 时 可 接 受 任 意 个 变 g


量。函数 ba r接受任意个输入参数,组成一个单元数组, va r a r i n 为 单元数组名。该单元数组 g

第i个单元就是从 v a r a r i n位置算起的第i个输入参数。例如,如果对于上面的函数 my f un. m, g 将其声明更改如下: functionc = myfun( varargin)

如果该函数采用 my f un( x, va r a r i n 包含两个单元,其中 y)的格式来调用,则在函数内部, g

va r a rg i n{ 1}由参数 x 组成, va r a r i n{ 2}由参数 y 组成。 g 如果某些参数在任何情况下都必须出现,可在函数声明时将其加在 va r a r i n 之前,但必须 g 保证 va r a r i n 作为最后的参数。如: g functionc = myfun( x, varargin)

如果调用格式为 my f un( a, b, c),则 va r a r i n 是长度为 2 的单元数组,并且 va r a r i n{ 1}= g g

b, va r a r i n{ 2}=c。 g

functionvarargout = foo( n)

从函数f oo 返回任意个输出 参 数,返 回 的 参 数 包 含 在 va r a r t中。va r a r t也 是 一 个 gou gou

预定义的单元数组,第i个单元是从 va r a r t位置算起的第i个输出参数。例如: gou

functionvarargout = myfun( x, y)

如果该函数采用[ ab]=my f un( c, d)的格式调用,则在函数内部, va r a r t由两个单元组 gou 成, va r a r t{ 1}的值赋给 a, va r a r t{ 2}的值赋给 b。 gou gou

function [ zvarargout]= myfun( x, y)

前,但必须保证 va r a rgou t作为最后的参数。如:

如果某些输出参数在任 何 情 况 下 都 必 须 出 现,可 在 函 数 声 明 中 将 其 加 入 到 va r a r t之 gou 使用 va r a rg i n 和 va r a r t函数,需要注意以下几点: gou

空 航

① 只能用在 M 文件函数中; ② 它们必须是小写字母;

③ 它们必须是输入参数或输出参数列表中的最后一个参数。 4)na rgchk 和 na rgou t chk 在函数体内使用,分别 用 于 验 证 输 入 参数和输出参数的个数是

数调用格式:

否在规定的范围内。它们经常与 e r r o r、 n a r i n和 n a r t函数一起用。n a r c hk 和 n a r t c hk 函 g gou g gou minargs,maxargs, numargs,string ) msg=nargchk( minargs,maxargs, numargs)或msg=nargchk(

其中, mi na rgs为输入参数个数的下限; maxa r numa r gs 为输入参数个数的上限; gs为输入 参数个数,一般为 na rg i n。当 numa r na r r r gs< mi gs或 numa gs> maxa gs时,返回错误信息字 符串;当 mi na rgs≤numa r r f un. m: gs≤ maxa gs时,返回空字符串。如对于函数 my functionc = myfun( a, varargin) error( nargchk( 2,3,nargin))

在命令行输入: myfun( 5) ??? Errorusing myfun Notenoughinputarguments. msg = nargchk( minargs,maxargs,numargs, struct )

其中, mi na rgs为输入参数个数的下限; maxa r numa r gs 为输入参数个数的上限; gs为输入


参数个数。当 numa r na r r r gs< mi gs或 numa gs> maxa gs时,返回错误信息组成的结构,该结 构包括错 误 信 息 字 符 串 和 错 误 信 息 的 标 识 符;当 mi na r r r gs≤numa gs≤ maxa gs 时,返 回 空 结构。

例如,当输入参数过少时,该结构内容为: message: Notenoughinputarguments. identifier: MATLAB: nargchk: notEnoughInputs

当输入参数过多时,该结构内容为: message: Toomanyinputarguments. identifier: MATLAB: nargchk: tooManyInputs t r i n msg=nargoutchk( minargs, maxargs, numargs)或m s a r o u t c h k( m i n a r s, m a x a r s, n u m a r s,s g) g=n g g g g

符串;当 mi na rgs≤numa r r gs≤maxa gs时,返回空字符串。 msg = nargoutchk( minargs,maxargs,numargs, struct )

其中, mi na rgs为输出参数个数的下限; maxa r numa r gs 为输出参数个数的上限; gs为输出 。当 参数个数,一般为 na rgou t numa r na r r r gs<mi gs或 numa gs> maxa gs时,返回错误信息字

其中, mi na rgs为输出参数个数的下限; maxa r numa r gs 为输出参数个数的上限; gs为输出 参数个数。当 numa r na r r r gs<mi gs或 numa gs> maxa gs时,返 回 错 误 信 息 组 成 的 结 构,该 结

构包括错 误 信 息 字 符 串 和 错 误 信 息 的 标 识 符;当 mi na r r r gs≤numa gs≤ maxa gs 时,返 回 空 结构。

例如,当输入参数过少时,该结构内容为:

空 航

message: Notenoughoutputarguments. identifier: MATLAB: nargoutchk: notEnoughOutputs

当输入参数过多时,该结构内容为:

message: Toomanyoutputarguments. identifier: MATLAB: nargoutchk: tooManyOutputs

5)i npu t name返回第 n 个输入参数的实际调用变量名。 inputname( argnum)

在函数体内使用,给出第 a r gnum 个 输 入 参 数 的 实 际 调 用 变 量 名。 假 如 这 个 参 数 没 有 名

字(比如是一个表达式或常数),那么返回空字符串。 例如,在当前目录有一个函数 my f un. m:

functionc = myfun( a, b) ( sprintf Firstcallingvariableis"%s "., inputname( 1))

在命令行输入: x = 5; y = 3; myfun( x, y)

Firstcallingvariableis"x ".

此时,如果将 my f un( x, f un( 5, 3)或 my f un( x+1, 3): y)换成 my


myfun( 5, 3) Firstcallingvariableis"". myfun( x+1, 3)

Firstcallingvariableis"".

2.f o r、 wh i l e循环结构 程序中总会有对某些量的迭代计算,或对某个过程的重复处理,这就需要使用循环来简化 程序。有两种循环:循环次数确定的f o r循环和依条件结束的 wh i l e循环。 ( 1)f o r语句

f o r语句用于循环次数确定的循环。调用格式为: forindex = start:step:end statements end

增量 s t ep 的默认值为 1。

fork=A

statements

end

假定 A 为 m×n 数组,则循环次数为 n 次,即数组按列循环。执行时,依次按列赋值给 k,

即f o rk=A(:, i), i为循环次 数,值 从 1~n。k 顺 序 从 列 向 量 中 取 元 素,每 取 一 个,执 行 一 次 循环。

空 航 航

fork=eye( 2), k, end k= 1 0 k= 0 1

f o r循环也可写在一行,语句用逗号隔开。如:

【注意】

①f o r循环是完全按照条件数组[ s t a r t:s t ep:end]或数组 A 中的值进行的,不能通 过 在

f o r循环中给循环变量赋值来终止f o r循环。如: fori=1: 5 ( /i); x i)=sin( pi ; i=5

end x x= 0. 0000

1. 0000

0. 8660

0. 7071

0. 5878

② 由于f o r循环频繁地访问并更 改 循 环 变 量 的 值,因 此 f o r循 环 会 占 用 系 统 大 量 的 运 算

时间。C 语言采用寄存器变量,将循环变量存 入 CPU 内 的 寄 存 器,很 好 地 解 决 了 循 环 频 繁 读

取内存的问题。而 MATLAB 并不提供寄 存 器 变 量,一 般 将 变 量 存 入 内 存 中。 解 决 此 问 题 可 取的方法是,尽量将循环运算替换为矩阵运算。


( 2)wh i l e语句

wh i l e语句是依条件结束的循环。调用格式为:

whileexpression statements end

由逻辑表达 式 expr e s s i on 控 制 循 环, exp r e s s i on 为 真,执 行 s t a t emen t s 语 句;否 则 退 出

循环。

与f o r循环类似, wh i l e语句也可写在一行,用逗号隔开。

如果 exp r e s s i on 的结果为数组,只有在该数组的所有元素为 t rue 时, wh i l e 循环才反复执

行;如果 exp r e s s i on 的结果为空数组, exp r e s s i on 为假,跳出 wh i l e语句。 3.i f、 swi t ch 条件分支结构 程序的分支语句,依据条件表达式的值选择执行的代码模块。 ( 1)i f语句

i f语句根据逻辑表达式的值选择执行一组代码。i f语句可任意 嵌 套。i f语 句 最 简 单 的 形

式为:

ifexpression statements;

end

如 果 逻 辑 表 达 式 expr e s s i on 的 值 为 真 ,执 行 s t a t emen t s 语 句 ;如 果 exp r e s s i on 的 值 为

假 ,直 接 跳 出 该 i f语 句 ;如 果 exp r e s s i on 为 数 组 ,只 有 exp r e s s i on 的 所 有 元 素 为 t r ue 时 ,

空 航

MATLAB 才执 行 s t a t emen t s 语 句;如 果 exp r e s s i on 为 空 数 组,直 接 跳 出 该 i f 语 句;如 果 exp r e s s i on包含多个逻辑子 表 达 式,MATLAB 将 采 用 捷 径 运 算,即 使 exp r e s s i on 中 并 没 有 使 用| |或 &&。

end

elseifexpression 2 statements 2;

ifexpression 1 statements 1;

先判断 逻 辑 表 达 式 exp r e s s i on1,如 果 exp r e s s i on1 为 真,执 行 s t a t emen t s 1 语 句;如 果

exp r e s s i on1为假,判断 exp r e s s i on2 的真假,若 exp r e s s i on2 为真,执行 s t a t emen t s 2 语句。 ifexpression 1 statements 1;

elseifexpression 2 statements 2; else statements 3; end

exp r e s s i on1 为 真,则 执 行 s t a t emen t s 1 语 句;否 则,如 果 exp r e s s i on2 为 真,执 行 s t a t e men t s 2 语句;否则,执行 s t a t emen t s 3 语句。 ( 2)swi t ch 语句

swi t ch 语句根据表达式的值执行相应的代码。常用的调用格式为: switchexpression


caseval 1 statements 1; caseval 2 statements 2; end

otherwise statementsn;

在 va l 1, va l 2,…中找出表达式 exp r e s s i on 的值,执行第 1 个匹配的 c a s e语句;如果没有找

到匹配的值,执行 o t he rwi s e语句。o t he rwi s e语句也可以省略。

表达式exp r e s s i on 的值必须为一个数值、字符或字符串; va l 1, va l 2,…, va l n 的值可以为数 ” 值、字符、字符串、多个数值的组合。多个数值之间用“ | 隔开,或用大括号括起来,值之间用逗 号隔开。例如:

a =1; switcha case1|2 1 case { 3,4} 2 otherwise 3 end

运行该脚本,命令行显示:

空 航

ans = 1

4.t r a t ch 结构 y…c 错误检查语句。当程序运行在复杂的环境下时,一些语句可能会产生错误,导致程序停止

执行,这时我们需要将这些语句放在t r a t ch 结构中。 y…c try

t r a t ch 结构的一般形式为: y…c 程序段 A; catch 程序段 B; end

逐行运行程序段 A,一旦运行出错,就跳过程序段 A 后面的语句,改为执行程序段 B,此时

命令行并不显示出错信息;

若程序段 A 运行完没有出现错误,则跳过程序段 B,继续执行后面的程序。 该语句结构也可以只包含t r a t ch 语句: y 语句,不含 c

try 程序段 A;

end

逐行运行程序段 A,若运行出错,就跳过程序段 A 后面的语句,继续执行后面的程序。

【注意】

① 只有程序段 A 出 现 错 误 才 会 跳 过 程 序 段 A 余 下 的 语 句,若 出 现 警 告 信 息,则 并 不


跳过。 ② 若运行程序段 B 时出错,则程序停止执行并在命令行显示出错误信息,除非程 序 段 B 中嵌套一个t r a t ch 结构。 y…c

③ 若程序段 A 运行出错,错误信息会存入一个结构体中。要获取该结构体可使用l a s t e r r o r ) 。该 函数( 可理解为 函 数 返 回 一 个 包 含 错 误 信 息 的 结 构 体, 字 段 名 分 别 l a s t e r r o r l a s t+e r r o r 、 , 为 me 和 出错信息包含在字段 s s agei den t i f i e r s t a ck me s s age中。 例如:

try

a= [ 123]; b= [ 12]; c=a*b catch s = lasterror; disp( s. message)

end

运行该脚本程序,命令行显示:

Errorusing mtimes Innermatrixdimensionsmustagree.

④ 在 M 文件编辑器中编辑程序时,对于上面的 f o r、 wh i l e 循环结构, i f、 swi t ch 分支结 构 或

将整段代码

空 航

和t r a t ch 结构,均可以单击f o r、 wh i l e、 i f、 swi t ch 或 t r y…c y 等关键字前的 进行隐藏或显示,如图 1. 11 所示。

图 1. 11 M 代码的显示与隐藏

5.c on t i nu e、 br e ak 和 r e t u r n ①c on t i nue:用于循环控制。当不想执行循环体的全部语句,只想在做完某一步后直接返

回到循环头时,在此处插入 c on t i nue。c on t i nue后面的语句将被跳过。

如果在嵌套循环中使用 c on t i nue之后的语句。 on t i nue,它只跳过所在层的循环里 c

②b r e ak:用在f o r或 wh i l e循环中,立即结束本层循环,而继续执行循环之后的下一条语 句。嵌套语句中,它只跳出所在层的循环。 ③r e t u rn:终止当前命令的继续执行,控制权交给调用函数或键盘。


6.其他常用函数 M 文件程序设计时,还经常用到表 1. 42 中的一些函数。 表 1. 42 其他常用函数

函数名

i npu t

函数名 ode pc

请求用户输入

e paus

l oba l g

更改或显示当前工作路径

d i sp l ay

显示字符串、数组、变量值

pwd

列出当前目录所有文件夹和文件

de l e t e

列出当前目录所有文件夹和文件名

c d

内存整理

d i r

命令行的操作记录

l s

定义全局变量

ck pa

回显执行中的 M 文件

d i a r y

运行一个脚本文件

删除文件或 GUI对象

创建伪码文件

e cho

暂停程序的执行

r un

显示当前工作路径

现对i npu t、 d i r、 l s、 cd、 pwd 等函数举例说明。

( 1)i npu t

i npu t函数提示 用 户 输 入 一 个 数 或 一 个 字 符 串,并 将 用 户 输 入 返 回 给 一 个 变 量。 调 用 格式:

user_entry = input(prompt )

r omp t为 屏 幕 的 提 示 字 符 串,用 户 输 入 一 个 数 值 或 变 量 名 后,返 回 给 变 量 us e r_ p en t r y。如:

空 航

\n ) a = input(pleaseentertheamountofmoney: pleaseentertheamountofmoney: 10000 a= 10000 b= [ 11; 34]; c = input(pleaseenterthevariablename: \n ) pleaseenterthevariablename: b c=

1 3

1 4

user_entry = input(prompt ,s )

返回用户输入的文本字符串给 us e r_en t r y 变量。如:

/N a = input(Doyouloveme? Y \n ,s ) /N Doyouloveme? Y Y a= Y

【例 1. 1. 1】 函数f( n)有以下递推公式: f( 1)=1; f( 2)=2;


( f( n)=f( n-1)+f( n-2)。 n>2) 编写一个脚本文件,用户输入一个大于 2 的整数 m,返回f( m)的值到命令行。 【解析】 先用i npu t函数提示用户 输 入 一 个 正 整 数,若 输 入 为 大 于 2 的 正 整 数,采 用 f o r 循环执行递归计算。下面给出两种计算方法。 程序一: m = input(请输入一个大于 2 的整数: \n ); ﹥ ( ) ( ( ) ) if m 2 && m == floor m f = zeros( m); ( [ , ] ) f 12 = [ 1, 2]; : forI = 3 m f( i)= f( i-1)+ f( i-2); end sprintf(f(%d)=%d ,[ mf( m)]) end

程序二:

出 学 大

空 航

end sprintf(f(%d)=%d ,[ mtemp])

end

m = input(请输入一个大于 2 的整数: \n );

if ( m ﹥ 2)&& ( m == floor( m)) a=1; b=2; forI = 3 :m temp = a + b; a = b; b = temp;

运行结果为:

请输入一个大于 2 的整数: 6 f( 6)=13

( 2)d i r、 l s、 cd、 pwd

这 4 个函数不仅在 MATLAB 命令窗口中经常用到,在其他与用户交互的终端中,也经常

用到。如 L i nux 终端 中 经 常 用 到 l s、 cd、 ndows 终 端 (即 DOS)中 经 常 用 到 cd、 d i r。 pwd,Wi 例如:

cde: \example \ ls . .. ls *. doc RS 485. doc a = ls

% 切换到指定目录 % 显示当前目录所有文件和文件夹的名称 数据结构( RS 485. doc C 语言版). pdf 新建文件夹 a 1. gif % 显示扩展名为 . doc 的文件名称 % 将当前目录下的所有文件和文件夹的名称存到字符数组 a 中


a= . .. RS 485. doc a 1. gif 数据结构( C 语言版). pdf 新建文件夹 cd 新建文件夹

% 进入目录 e: \example \新建文件夹 cd .. % 返回上一级目录 % 显示当前路径 pwd ans = e: \example dir % 列出当前目录所有文件和文件夹 数据结构( . RS 485. doc C 语言版). pdf 新建文件夹 .. a 1. gif dir *. % 显示扩展名为 . gif gif 的文件名称 a 1. gif a = dir(*. % 存储扩展名为 . gif ) gif 的文件的相关信息到结构体 a 中 a= name: a 1. gif date:22- 六月 -200914: 49: 07 bytes:42873 isdir:0 datenum:7. 3395e+005

空 航

【思考】 在上面的 a =l s语句中,返回的前两个字符串为“.”和“..”,这两个字符串代表 什么呢?

cd .. pwd ans = e: \example dir . . .. cd 资料 dir(..) . ..

% 更改目录为 e: \example \资料 % 设置目录为当前目录 % 显示当前完整路径

pwd ans = e: \example \资料

cde: \example \资料 cd(.)

“.”代表的是当前所在目录的名称,而“..”代 表 的 是 上 级 目 录 的 名 称。因 此,不 难 理 解 以 下这些命令:

% 返回上一级目录 % 显示当前完整路径

RS 485. doc a 1. gif

RS 485. doc a 1. gif

% 显示当前目录下的文件 数据结构( C 语言版). pdf 资料 % 进入目录 e: \example \资料 % 显示上一级目录下的文件 数据结构( C 语言版). pdf 资料


1. 2 重难点讲解 1. 2. 1 矩阵、向量、标量与数组 MATLAB 又称为矩阵实验室,是基于矩阵运算的操作环境。 MATLAB 中的所有数据都 是以矩阵或多维数组的形式存储的。向量和标量是矩阵的两种特殊形式。矩阵、向量、标量与 数组的概念如下: ① 矩阵是二维的,由行和列组成;空矩阵是一类特殊的矩阵,其行或列的长度至少有一个 为 0。如 z e r o s( m, 0)将产生一个 m×0 的空矩阵。

② 向量:一维长度为 1,另一维长度大于 1 的矩阵,称为向量。向量分为行向量和列向量, 行向量的每个数值用逗号或空格隔开,列向量的每个数值用分号隔开,例如:

3

a= [ 1, 23] a= 1 2

创建一个行向量:

创建一个列向量:

空 航

b= [ 1; 2; 3] b= 1 2 3

3

2

b ans = 1

也可通过转置将行向量与列向量相互转换:

③ 标量:两维长度都为 1 的矩阵,称为标量。标量就是一个实数或复数。当然,字符也可 被当成一个标量,因为它在 MATLAB 中是以整数形式存储的。

④ 数组:理论上,数组的维数可 为 任 意 非 负 整 数。数 组 包 括 数 值 数 组、字 符 数 组、结 构 数 组和单元数组。

如果矩阵不进行线性代数运算,而只进行 算 术 运 算,它 就 是 一 个 二 维 数 值 数 组。例 如,对

于矩阵 a和 b:

a=ones( 2, 2); [ , ; , b= 1 2 3 4];

若执行运算: a*b ans = 4 4

6 6


则 a与 b 被看成矩阵,因为它们执行的是线性代数运算。 若执行运算: a. *b ans = 1 3

2 4

则 a与 b 被看成数组,因为它们执行的是对应元素之间的算术运算。 若执行运算:

a+b ans = 2 4

3 5

则 a与 b 被看成数组或矩阵,因为此时可被看成线性代数运算,也可被看成算术运算。

1. 2. 2 数据类型转换

( 1)转换为字符、字符串

int 2str([ 2. 53. 1]) ans = 3 3

①i n t 2s t r:整数转换为字符串。如:

航 京

num 2str( 3. 145) ans = 3. 145

空 航

② num2s t r:数值转换为字符串。如:

③ ma t 2s t r:矩阵转换为字符串。如: mat 2str([ 12;34]) ans = [ 12; 34]

④ cha r:数值转换为字符(字 符 为 数 值 对 应 的 Un i c ode 值),或 者 单 元 数 组 转 换 为 字 符 数 组。如: char([ 109971161089798]) ans = matlab char({1 ,2 ,3 }) ans = 1 2 3

⑤ de c 2b i n:十进制转换为二进制字符串。如:


dec 2bin( 9) ans = 1001

⑥ de c 2hex:十进制转换为十六进制字符串。如:

dec 2hex( 30) ans = 1E

⑦ num2hex:转换单精度或双精度值为IEEE 标准的十六进制数。如:

num 2hex(-1) ans = bff 0000000000000

⑧ de c 2ba s e:十进制转换为任意进制。如:

dec 2base( 33,17) ans = 1G

cast( 123, char ) ans = {

⑨c a s t:数据类型强制转换。如:

空 航

( 2)转换为数值、数组

str 2num(1 2 ) ans = 1 2

①s t r 2num:字符串转换为数值。如:

②s t r 2doub l e:字符串转换为 doub l e值,或字符串单元数组转换为数值数组。如:

str 2double(1, 000. 3) ans = 1. 0003e+003 s= {1. 23 , ;3. 48 ,3. 88 }; d=str 2double( s)

d=

1. 2300 3. 4800

NaN 3. 8800

③ doub l e:字符转换为对应的 Un i c ode码,或者字符数组转换为数值数组。如:

double(a+1 ) ans = 97 43 49 double(大飞 ) ans = 22823 39134


④i n t 8、 u i n t 8、 i n t 16、 u i n t 16、 i n t 32、 u i n t 32、 s i ng l e:数值或字符转换为指定类型。例如:

int 8(a ) ans = 97 int 16(飞 ) ans = 32767

% 字符“飞”的 Unicode 码为 39134,数值溢出,返回 int 16 型数据的最大值

⑤ eva l:转换数值字符串为数值。如:

eval(3e 1) ans = 30

⑥ hex2num:十六进制字符串转换为对应的双精度浮点数。双精度浮点数共 64 位,位存 储格式参见表 1. 12。输入的十六进制字符串 转 换 为 二 进 制 后 不 足 64 位,在 低 位 补 0。例 如, 双精度数 -1 的十六进制值为 0XBFF0000000000000,那么:

hex 2num(bff ) ans = -1

⑦ hex2de c:十六进制字符串转换为十进制数。如:

空 航

hex 2dec(3ff ) ans = 1023

bin 2dec(010111 ) ans = 23

⑧b i n2de c:二进制字符串转换为十进制数。如:

⑨o c t 2de c:八进制数转换为十进制数。如:

oct 2dec( 12) ans = 10

⑩ ba s e 2de c:任意进制转换为十进制。如:

base 2dec(120 ,3) ans = 15

췍c e l l 2ma t:单元数组转换为矩阵。如:

cell 2mat({1 ;2 ;3 }) ans = 1 2 3


췍c a s t:数据类型强制转换。如: cast(123 , double ) ans = 49 50 51

( 3)转换为单元数组

① ma t 2c e l l:字符数组或数值数组转换为单元数组。如:

a = [abc ; bca ; cab ]; b = mat 2cell( a,[ 21],[ 12]) b= [ [ 2x 1char] 2x 2char] c

ab

② num2c e l l:数值数组转换为单元数组。如:

a= [ 12; 34]; ( num 2cell a,2) ans = [ 1x 2double] [ 1x 2double]

1. 3 专题分析

空 航

专题 1 编程风格

在学习 MATLAB 编程之前,大家有必 要 了 解 一 些 编 程 风 格 方 面 的 知 识。 代 码 格 式 要 正 确,表达要清晰、通用,这样才能写出具有共享性和容易维护的代码。良好的代码写作规范,使 1.命名规则 ( 1)变

得程序容易调试,便于修改。因此,从一开始就考虑代码风格是必要的。 量

1)变量名应该能够反映该变量的含义或用途,以小写字母开头,采用大小写混用模式或 下画线分割模式,如i sOpened、 s e r i a l_open 等。 【思考】 为什么要约定以小写字母开头呢?

大家采用 C++ 编程时,经常用到类 和 指 针,用 户 在 查 找 类 的 成 员 函 数 或 成 员 变 量 时,不

可能把所有的类成员记得清清楚楚,一般是先输入类成员的首字母或开始几个字母,然后根据 编辑器的提示下拉列表框,寻找需要的类成员。于 是,大 家 约 定,所 有 类 成 员 均 以 小 写 字 母 开 头,以方便类成员的查找。 2)临时变量的变量名尽量短小。习惯上, m、 n、 i、 k 表示i n t类型的临时变量(不推荐使 j、 用i、 c、 ch 等表示 字 符 类 型 的 临 时 变 量; a 表 示 临 时 数 组; x、 j,因为与虚数单位冲突); y 或 z表

示双精度临时变量。

3)前缀 m 或 n 通 常 用 于 申 明 数 值 对 象,m 代 表 ma t r i x, n 代 表 numbe r,如 mRows(或 nRows)、 nSegmen t s、 nF i l e s等。


4)前缀 p 表示指针;前缀 s t r表示字符串;前缀 s t表示枚举、结构或联合体;前缀 b 表示

布尔型变量。

5)表示对象与对象集合的变量名,不要仅仅只相差一个后缀“ s”,可以考虑多对象的变量 名后面添加一个 Ar r ay。例如, i n t表示一个点,而 po i n tAr r ay 表示一个点集。 po

6)尽量避免变量 名 以 数 字 区 别、以 大 小 写 区 别 或 以 后 缀 s 区 别。 例 如 Row 和 Rows、 Temp 和t emp、Va l ue 1 和 Va l ue 2 都 是 不 好 的 命 名 习 惯,因 为 变 量 名 太 相 似,容 易 混 淆 或 拼 写错。

7)只 表 示 单 个 实 体 数 据 的 变 量,可 以 添 加 前 缀 i或 后 缀 No(源 自 英 文 单 词 “ No.”),如 da t aNo、 iDa t a等。 8)循环变量应该以i、 j或 k 为前缀。当涉及复数运算时,应禁用i和j作为循环变量。对 于嵌套循环,循环变量应该以字母表的顺序命名。如: foriRow = 1 :mRows forjLine = 1 :nLines …

end

end

l i ne、 r ow 都可以翻译成“行”或“列”, c o l umn 翻译成“列”。本书中, l i ne 与 r ow 一起用时, r ow 理解为“行”, l i ne理解为“列”; r ow 或 l i ne 与 c o l umn 一 起 用 时, r ow 或 l i ne 理 解 为 “行”, co l umn 理解为“列”。

9)布尔变量禁止使用否 定 式 的 变 量 名。 例 如,使 用i sOpened,而 禁 止 使 用i sNo tCl o s ed。

空 航

这有两个原因:一是因为 ~i sNo tCl o s ed 相 当 于 是 双 重 否 定,看 起 来 很 别 扭;二 是i sOpened 比

i sNo tCl o s ed 更简洁。 10)缩写形式即使全部为大写字母,在变量命名时也应该与小写字母混合使用。如:可使

用 udpSoke t,而避免使用 UDPSoke t。

11)避免使用关键字或保留字作为变量名,如 c l e a r、 c l c、 wh i l e、 end、 l oba l等。 g 有人会问:为什么 nd ims、 nnz、 nva r a r i n 等,不写成 nDims、 nNz、 nVa rAr I n 呢? g g

原因很简单,因为 nd ims、 nnz、 nva r a r i n 等都不是变量名,而是函数名(可以在 MATLAB g 安装目录内搜索到 nd ims. m、 nnz. m 和 nva r a r i n. m 文 件)。 函 数 名 要 求 全 部 采 用 小 写 字 母, g 这点将在后面讲到。 ( 2)常

1)常数名、全局变量名、永久变量名应该全部采用大写字母,且用下画线分割单词。至于 为什么 p i不是 PI, t i c不是 TIC,原因也是因为 p i和 t i c 在 MATLAB 内 部 都 是 函 数 名(同 理, 可以在 MATLAB 安装目录内搜索到 p i. m 和t i c. m 文件)。 2)可以采用对象的类型名作为前缀。如: COLOR_RED、 POS_CENTER(或 POS ITION_

CENTER)等。

( 3)结构体

1)结构体命名应该以大写字母开 头。 如: Segmen t。 这 么 约 定 是 为 了 与 普 通 变 量 名 区 别

开来。

2)结构体的字段名不 需 要 包 含 结 构 体 名 的 含 义。 如:应 采 用 Segmen t. l eng t h而避免采


用 Segmen t. Segmen tLeng t h。 ( 4)函

1)函数名一般全 部 采 用 小 写 字 母 (MATLAB 定 义 的 函 数 都 是 以 小 写 字 母 作 为 函 数 名 的)。当然,也可以采用下画线或大小写字母混合使用的规则来命名。

2)函数名 应 该 具 有 意 义。 可 以 采 用 大 家 广 泛 使 用 或 约 定 俗 成 的 缩 写。 如:max、mi n、 d i sp、 s t d、 d i f f等。 3)所有的函数命名应该采用英文形式,禁止使用汉语拼音。因为英语是国际研发交流中 最适合的语言。

4)单输出参数的函数,可以根据输出参数的含义命名。如: me an、 sum 等。 5)前缀 ge t和 s e t作为访问 GUI对 象 的 保 留 前 缀;后 缀 ge t和 s e t作 为 位 运 算 的 保 留 后

缀。如: t appda t a、 s e t appda t a、 b i t t、 b i t s e t等。 ge ge 6)前缀f i nd 用于具有查询功能的函数,如f i ndob f i nda l l;前缀 c ompu t e用于具有计算功 j、

能的函数;前缀i s用于布尔函数,如i s c e l l s t r、 n i t i a l i z e用于具有初始化对象功能的函数;前缀i

i s c e l l、 i s cha r等。 2.文件与结构

1)模块化设计。不同的功能分成不能的模块,单独进行设计。 2)函数之间 尽 量 采 用 输 入 输 出 参 数 进 行 通 信。 当 输 入 参 数 较 多 时,考 虑 采 用 结 构 体。

如:每个 GUI回调函数都有一个 hand l e s结构体作为输入参数。

3)多处出现的代码块,要考虑封装在一个函数中,以提高代码的简洁性和复用性。 4)只被另外一个函数调用的函数,应该作为一个子函数,写在同一个文件中。

( 1)变

空 航

3.基本语句 总体原则:避免使用含糊代码。代码不是越简洁越好,而是越清楚越好。

1)在内存充足的情况下,变量尽量不要重复使用,赋予每个变量唯一的含义,可以增强代 码的可读性。

2)同种类型且意义相近的变量,可以在同一语句中定义;不同意义的变量,不要在同一语 句中定义。例如,可以这样定义: globalPOS_XPOS_Y globalCOLOR_REDCOLOR_BLUE

而不要这样定义: globalPOS_XPOS_YCOLOR_REDCOLOR_BLUE

3)在文件开始的注释中,为重要变量编写文档。 4)在常量定义处,为该常量编写注释。

5)尽量少地使用全局变量。全局变量过多,不利于代码的维护和阅读。 6)浮点数的逻辑运算要当心系统误差。如:


0. 05 ^ 2 == 0. 03 ^ 2 + 0. 04 ^ 2 ans = 0 a = 0. 01 :0. 01 :2; n = find( a == 0. 15)

% 浮点值的比较

% 查找数组 a 中值为 0. 15 的元素,产生系统误差

n = Emptymatrix:1-by-0 n = find( abs( a - 0. 15)﹤ =eps)

% 查找数组 a 中值为 0. 15 的元素

n = 15

( 2)常

1)尽量在表达式中少用数字,可能会改变的数字用常数代替,便于程序的修改。 2)浮点常数应该在小数点前写上 0。如: 0. 5 不要写成 . 5。 ( 3)循环语句

1)不要在循环语句中扩展数组的维数,而应该预先给数组分配内存。如:

result = zeros( 1,100); : fori = 1 100 result( i)= i ^ 2; end

2)循环中尽量少用 br e ak 和 c on t i nue,以增强代码的可读性。 3)嵌套循环时,应该在每个 end 后添加注释,注明该层循环完成什么功能。

空 航

( 4)条件语句 1)避免使用复杂的条件表达式,而采用临时逻辑变量代替。例如,避免使用如下格式:

end

value = upperLimit)&& (~isMenber( value,valueArray)) if ( value = lowerLimit)&& ( …

建议采用如下格式:

isValid = ( value = lowerLimit)&& ( value = upperLimit); isNew = ~isMenber( value,valueArray); if ( isValid)&& ( isNew) … end

2)在i f…e l s e结构中,频繁事件放在i f部分,偶尔发生的事件放在 e l s e部分。如: fid = fopen( fileName); ( if fid ~= -1) … else … end

3)swi t ch 语句应该包含 o t he rwi s e条件,以免出现不可预料的错误。


4)swi t ch 变量通常应该是字符串。 4.排版与注释 ( 1)排

1)每行代码控制在 80 列之内,代码分行采用符号“…”。 M 文件编辑器中第 75 列有一条

灰色的竖线,分行时尽量选择在该竖线附近。 2)代码分行显示的 3 条原则: ① 在一个逗号或者空格之后分行; ② 在一个操作符之后分行; ③ 分行时对齐表达式。 例如:

sum = a + b + c + ... d + e; str = [e: \example \ ... 新建文件夹 ];

% 在空格、操作符之后分行;对齐表达式

% 在空格之后分行;对齐表达式

3)代码的缩排一般为 3 个空格或 1 个“ Tab”,建议采用 MATLAB 默认的缩排格式。 4)一行代码应该只包 含 一 个 可 执 行 语 句。当 然,短 的 i f、 f o r、 wh i l e 语 句 可 以 写 在 一 行。

一行写多条执行语句,不仅影响代码的美观,更会减慢代码的运行速度。

5)合理使用空格。使用空格有以下 5 条原则: /、% 、&、 ① 在 = 、= = 、~ = 、> 、> = 、< 、< = 、:、+ 、- 、* 、 |、&&、 ||的 前 后 添 加

空格。

空 航

② 在~、 ^等符号 前 后 不 需 要 添 加 空 格。 冒 号 表 达 式 中 为 了 直 观 有 时 不 需 要 添 加 空 格。 总之,以代码的美观和直观为原则。例如, 2^x 建议写成 2 ^ x;~ a 建议写成 ~a; fori = 1 :

a= [ 1,2,3];

a/2 :c + d 建议写成 fori = 1 :( a/2):( c + d)或者 fori = 1 :a/2 :c+d。 ③ 在逗号、分号的后面添加空格,前面不添加空格。例如:

④ 关键字后面添加空格,而函数名后不能添加空格。据此可以区分关键字与函数。 ⑤ 块内部的 1 个逻辑组语句前后用空白行隔开;块之间用多个空白行隔开。

( 2)注

1)注释应该简洁易读。 2)函数头部的注释应该支持 he l ook f o r 对 该 函 数 的 查 询,因 此,该 行 注 释 中 应 尽 可 p 和l

能包含可能的搜索关键字。

3)函数头部的注释应描述该函数的功能,并列出输入参数不同时该函数的语法和功能。 4)在函数头部注释中,建议该函数的函数名全部大写。 5)在函数头部注释中,最后要加上版权申明和程序版本。 6)函数头部的注释建议全部用英文。

专题 2 代码优化

要优化 MATLAB 程序,加速程序的运行,可以考虑以下方法:


1.遵守 Pe r f o rmanc eAc c e l e r a t i on 的规则 具体简化为以下 7 条:

1)只 有 使 用 以 下 数 据 类 型,MATLAB 才 会 对 其 加 速: l og i c a l、 cha r、 i n t 8、 u i n t 8、 i n t 16、 、 、 、 。而 、 语 句 中 如 果 使 用 了 以 下 数 据 类 型 则 不 会 加 速: u i n t 16i n t 32 u i n t 32 doub l e nume r i cc e l l、 s t ruc t、 s i ng l e、 f unc t i onhand l e、 avac l a s s e s、 us e rc l a s s e s、 i n t 64、 u i n t 64。 j 2)超过三维的数组不会进行加速。 3)当使用f o r循环时,只有遵守以下规则才会被加速:

① 循环范围只用标量值来表示; ② 循环内部的每条语句都要满 足 上 面 的 两 条 规 则,即 只 使 用 支 持 加 速 的 数 据 类 型,只 使

用三维以下的数组;

③ 循环内只调用了内建函数( bu i l d i nf unc t i on)。 4)当使用i f、 e l s e i f、 wh i l e或 swi t ch,其条件测试语句中只使用了标量值时,将加速运行。

5)不要在一行中写入多条操作,这样会减慢运行速度。 6)当某条操作改变了原来变量的数据类型或形状(大小、维数)时将会减慢运行速度。

2.遵守 5 条规则 1)尽量避免使用循环。可以有 3 种改进方法:

7)应该这样使用复常量: x=1+3 i,而 不 应 该 这 样 使 用: x=1+3*i。 后 者 会 降 低 运 行 速度。

天 空 航 航

命令行输出:

tic; fori = 1 :10000 t( i)= i/100; ( t( i)); y i)= sin( end toc

① 优先考虑用向量化的运算来代替循环操作。例如:

Elapsedtimeis0. 128331seconds.

现将循环改为矩阵运算: tic; t = 0. 01 :0. 01 :100; t); y = sin( toc

命令行输出: Elapsedtimeis0. 000332seconds.

当然,新版的 MATLAB 在循环算法上做了较大优化和改进,如果向量化运算远比循环运 算复杂且调用 的 函 数 过 多,推 荐 还 是 用 循 环 方 式,而 不 要 强 行 用 矩 阵 运 算,毕 竟,“强 扭 的 瓜不甜”。

② 在必须使用多重循环时,循环次数少的放在外层,循环次数多的放在内层。


例如,将循环次数多的放在外层: clear; data = zeros( 1000,500); ; tic foriLine = 1 :1000 forjRow = 1 :500 data( iLine,jRow)= iLine + jRow; end end toc

命令行输出: Elapsedtimeis0. 005671seconds.

版 出 学 大

clear; data = zeros( 1000,500); ; tic foriRow = 1 :500 forjLine = 1 :1000 data( jLine,iRow)= jLine + iRow; end end toc

而将循环次数少的放在外层:

空 航

命令行输出:

Elapsedtimeis0. 003665seconds.

2)预分配数组空间,即先给数 组 分 配 好 空 间 再 使 用。给 数 值 型 数 组 分 配 空 间,优 先 使 用 z e r os和 one s;给单元数组分配空间,使用 c e l l;给结构体分配空间,使用 s t ruc t;扩充数组,使用 r epma t。

当要预分配一个非 doub l e型变量,或 扩 充 一 个 变 量 的 维 数 时,使 用 r epma t函 数 以 加 速。

例如:

A = zeros( 100,100, uint 8 ); B = repmat( A,2,2);

% 给数值型数组分配空间 % 扩充数组

避免使用下面的语句: A = uint 8( zeros( 100,100)); B= [ AA; AA];

3)优先使用 MATLAB 内建函 数,将 耗 时 的 循 环 编 写 成 MEX 文 件 ( C 语言处理循环更 快),以获得加速。

有关 MEX 文 件 如 何 编 写 请 参 考\ma t l ab\R2010b\ex t e rn\examp l e s\r e f book 目 录 下 的 f i ndnz. c、 c和 t ime s two. c等 C 文件,以及在 he l i l e 和 mex phonebook. p 中查阅一下 MEX F Func t i on 的相关内容。


MEX 文 件 编 译 成 MATLAB 可 以 直 接 调 用 的 共 享 库 文 件 (扩 展 名 为 mexw32 或 mexw64),方法为: mexmexFileNme. c

编译后的文件为 mexF i l eName.mexw32( 32 位 操 作 系 统)。 例 如,上 面 的 t ime s two. c编

译和调用方法为(假设已经将该文件拷贝到 e: \examp l e \目录下): cde: \example \ mextimestwo. c deletetimestwo. c 2) y = timestwo( y= 4

% 切换到 timestwo. c 所在目录 生成 % timestwo. mexw 32 % 删除 c 源文件 % 输出值为输入值的 2 倍

4)尽量使用函数而不要使用脚本。脚本文件转换为函数文件的方法很简单,就是在脚本 文件开头加一行无输入参数和输出参数的函数声 明 即 可。注 意 函 数 声 明 时,函 数 名 要 与 文 件

名一致。

5)认真检查代码中有波浪线提示的部分。新版 MATLAB 具有代码检查的功能,对于一 些常见的错误或需要优化的地方,都进行了提示。一定要仔细检查每个出现波浪线的地方。

【例 1. 3. 1】 自守数问题。

如果某个数的平方的末尾几位等于这个数,那么就称这个数为自守数。例如, 5和6是

空 航

一位自守数( 5×5=25; 6×6=36)而 25×25=625; 76×76=5776,所 以 25 和 76 是 两 位 自 守数。而 0 和 1 虽然其平方的个位数仍然是 0 和 1,但是由于研究它们没有意义,所以 0 和

1 不算自守数。 现要求分别采用循环和矩阵 运 算 的 方 式,分 别 计 算 出 5~100000 之 间 所 有 的 自 守 数。

并比较两种计算方法所花费的时间。

【解析】 思路 1:采用循环 计 算。假 设 某 个 数 为 x,其 十 进 制 位 数 为 n。根 据 自 守 数 的 定

义,只要对于每个数作如下判断: x2 对 10n 求模,如果所得的余数等于 x,则 x 为自守数。众所 周知,对于十进制数 x,对其求以 10 为底的对数,所得值的整数部分加 1,就等于 x 的位数。 程序如下:

tic; index = 0; data = zeros( 1,100); fori = 5 :100000 n = 1 + floor( log 10( i)); % 获取数值 i 的十进制位数 ifi== mod( i ^ 2,10 ^ n) % 若 i 等于其其平方的末尾几位,判断 i 为自守数,存入 data 数组中 index = index + 1; data( index)= i; end end answer = data( 1 :index) toc

% 命令行打印出查询到的所有自守数


命令行输出: answer = 5 6 25 Elapsedtimeis0. 709977seconds.

76

376

625

9376

90625

思路 2:采用矩阵运算。将 5~100000 之内的所有整数放在一个矩阵 x 中,同时计算出 x

中每个元素平方的尾数,放入矩阵 y 中。查找 x 与 y 中对应位置相等的元素即可。 程序如下:

tic; x = 5 :100000; x. ^ 2,10. ^( 1 + floor( log 10( x)))); y = mod( x( x == y) % 采用逻辑数组作为索引值,比 find 函数运算速度更快 toc

ans = 376

625

76

9376

90625

5 6 25 Elapsedtimeis0. 028646seconds.

命令行输出:

可见,采用矩阵运算,可以显著地提高代码的运算效率。

专题 3 M 文件编程小技巧

空 航

( 1)Tab 键右移整段代码

在编写 M 文件中,有以下几点小技巧经常用到:

选中一段代码或一段代码中的部分代码,将整段代码右移一个制表符长度( 4 个空格的长

度)。例如,可将图 1. 12 左图中的代码右移一个制表符长度,如图 1. 12 的右图所示。

图 1. 12 Tab 键右移整段代码

( 2)Sh i f t+Tab 组合键左移整段代码

选中一段代码或一段代码中的部分代码,将整段代码左移一个制表符长度( 4 个空格的长 度)。例如,可将图 1. 左图中的代码左移一个制表符长度, 如图 中的右图所示。 13 1. 13

图 1. 13 Sh i f t+Tab 组合键左移整段代码


( 3)Tab 键自动补全函数名

输入函数名的前几个字符后按 Tab 键,M 文 件 编 辑 器 会 试 图 补 全 该 函 数 名,弹 出 所 有 可

能的已有函数名列表。例如,想输入f i r e这 个 函 数,在 M 文 件 编 辑 器 内 输 入 f i然 后 按 Tab gu 键,得到图 1. 14 所示的列表。

图 1. 14 函数名自动补全

( 4)自动补全函数调用格式

空 航

输入函数名和左括号后,M 文件编辑器会提示该函数的所有调用格式,并根据用户输 入, 自动识别用户所选中的调用格 式,高 亮 显 示 当 前 要 输 入 的 参 数 项。 例 如,对 于 wa i t ba r 函 数,

输入左括号后停顿数秒,显示该函数的调用格式信息,如图 1. 15 所示。

图 1. 15 自动补全函数调用格式

继续输入 0. 5 和逗号,高亮显示当前要输入的参数,如图 1. 16 所示。

( 5)F1 键显示帮助信息, Ct r l+F1 组合键显示函数概要信息

鼠标点到函数名上的任何 位 置,然 后 按 F1 键,弹 出 该 函 数 的 帮 助 信 息 页 面。 例 如,鼠 标


图 1. 16 高亮显示 wa i t ba r函数的第 2 个输入参数

空 航

点到f i r e函数上,然后按 F1 键,得到如图 1. 17 所示的帮助信息。 gu

图 1. 17 显示帮助信息

若按 Ct r l+F1 组合键,显示函数的调用格式,如图 1. 18 所示。

( 6)采用代码分段符 %% 对代码进行分段高亮显示

在每个要分段的代码前后一行输入两个百 分 号,或 两 个 百 分 号 后 加 一 个 空 格,再 加 注 释,

可以对代码进行分段高亮显示,如图 1. 19 所示。

当然,也可以右键选择【 I ns e r tCe l lBr e ak】添加 %% 。

( 7)注意检查红色波浪线所选中的语法部分

MATLAB 会对 M 文件执行代码检查,并提供一些合理性的 建 议。在 需 要 优 化 的 语 法 部


空 航

图 1. 18 显示函数的概要信息

图 1. 19 代码的分段高亮显示

分下方添加红色波浪线,并在该行代码最右端添加一条红线(即消息指示器)。

例如,图 1. 20 中有三条红色波浪线,分别位于r and i n t、= 和 s t r 2num 的下方,M 文件编辑

器最右端同样有三个红色线段指示该行代码存在警告信息。

首先,鼠标停留在 r and i n t函数上数秒,或停留在右侧的红 色 线 段 上,会 提 示“该 函 数 将 被

移除,建议使用 r and i代替”的信息,如图 1. 21 所示。该行代码改为: a = randi([ 10100],50,100);

警告信息自动清除。

第 2 行代码的“= ”下方也有一条红色波浪线,鼠标停 留 在“= ”上 数 秒,会 提 示“该 行 代 码

将输出结果到命令行,在该行代码后添加分号终止输出”,如图 1. 22 所示。


空 航

图 1. 20 M 文件的语法检查

图 1. 21 语法检查的警告信息

图 1. 22 查看语法检查的警告信息

单击警告信息上的链接,弹出的信息窗口进一步解释“在脚本文件中有时需要打印信息”,

如果要忽略该警告信息,可以根据需要右键选择【禁止警告该条信息】、【禁止警告所有信息】或

【禁止警告该类信 息】。 选 择 【禁 止 警 告 该 类 信 息】选 项 后,不 再 提 示 表 达 式 后 未 加 分 号 的 警 告了。


第 3 行代码的s t r 2num 函数下方也有一条红色波浪线,鼠标停留在s t r 2num 函数上数秒,

会提示“ s t r 2doub l e函数运算更快,但 s t r 2doub l e只进行标量运算。请根据需要选择合适的函 数”,如图 1. 23 所示。

图 1. 23 s t r 2num 函数的警告信息

( 8)Sh i f t+F1 组合键或右键选择【 Func t i onBr ows e r】,打开函数浏览器

在 M 文件编辑器内空白位置按 Sh i f t+F1 组合键,可以打开函数浏览器;选中要查看的函

数然后按 Sh i f t+F1 组合键,可以打开函数浏览器并搜索该函数。例如,在 M 文件编辑器内输

空 航

入r and i,选中 r and i并按 Sh i f t+F1 组合键,打开函数浏览器并搜索 r and i,如图 1. 24 所示。

图 1. 24 打开函数浏览器

( 9)Ct r l+I组合键或右键选择【 Sma r tI nden t】,执行代码格式自动缩排 例如,缩排前的代码如图 1. 25 所示。

选中所有代码,按 Ct r l+I组合键缩排后的效果如图 1. 26 所示。


空 航

图 1. 25 未缩排的代码

图 1. 26 自动缩排后的代码

( 10)Ct r l+D 组合键或右键选择【 OpenSe l e c t i on】,打开该函数的源代码

例如,在 M 文件编辑器内输入 wa i t ba r,并 在 该 函 数 上 按 Ct r l+D 组 合 键,自 动 打 开 所 调 , 用的 wa 函数源代码 如图 所示。 i t ba r wa i t ba r. m 1. 27

图 1. 27 查看函数的源代码


( 11)Ct r l+R 组合键注释整段代码, Ct r l+T 组合键取消注释整段代码

选中要注释的代码段,按 Ct r l+R 组合键或右键选择【 Commen t】;选中要取消注释的代码

段,按 Ct r l+T 组合键或右键选择【 Unc ommen t】。 ( 12)采用 % {…… % }结构注释整段代码

这类似于 C 语言中的/* …… */结构,如图 1. 28 所示。

图 1. 28 M 代码的整段注释

1. 4 精选答疑

空 航

问题 1 单元数组占用的内存空间如何计算

【例 1. 4. 1】 有 3 个 2×2 的单元数组:数组 a仅定义而未初始化,数组 b 除第一个单元

初始化为字符 a 外,其余单元均未初始化,数组 c除第一 个 单 元 初 始 化 为 空 值 外,其 余 单 元

均未初始化。试计算数组 a、 b 和 c所占用的内存空间大小。

【解析】 对于一个已定义且初始化了的单元数组,每个单元都附带了两个位置指针(类似

于链表指针,共 4 字节),来指明该单元所在位置,另 外 还 有 一 块 56 字 节 的 区 域 用 来 记 录 单 元

信息,比如单元的长度,数值类型等。因此每个单 元 的 长 度 应 该 等 于 单 元 内 元 素 的 实 际 长 度, 加上 60 字节。

对于一个仅定义而未初始化的单元数组,每 个 单 元 仅 附 带 一 个 4 字 节 的 位 置 指 针。即 每

个未初始化的单元的长度应该等于 4 字节。

数组 a由于仅定义而未初始化,故每个单元占用 4 字节。

数组 b 的第 1 个单元初始化为字 符 a ,而 字 符 均 为 16 位 的 Un i c ode 编 码,占 用 2 字 节。 所以数组 b 的第 1 个单元占用空间 60 字节 +2 字节 =62 字节。后 3 个单元未初始化,共占用

3×4=12 字节。故数组 b 共占用 62 字节 +12 字节 =74 字节。 数组 c第 1 个单元初始化为空,所以第 1 个单元占用空间 60 字节 +0 字节 =60 字节。后 3 个单元共占用 3×4=12 字节。故数组 c共占用 60 字节 +12 字节 =72 字节。 程序代码如下:


clear a = cell( 2,2); b = a; b{ 1}= a ; c = a; c{ 1}= []; a, b, c

c=

[] []

a []

[] []

[] []

[] [] Size 2x 2 2x 2 2x 2

Bytes Class 16 cell 74 cell 72 cell

Attributes

whos Name a b c

b=

[] []

a=

问题 2 如何生成指定格式的常矩阵、字符串

【例 1. 4. 2】 产生如下矩阵:

空 航

éê 1+2 1+2 … 1+10 ùú ê 2+1 2+2 … 2+10 ú ê ︙ ︙ ︙ ú úú êê ë10+1 10+2 … 10+10û

要求使用函数生成。

【解析】 考 查 矩 阵 的 加 法 和 矩 阵 扩 展 的 方 法。 该 矩 阵 可 被 看 成 下 列 两 个 矩 阵 a 和 b

相加:

é1 1 … 1ù éê 1 ê ú … 2 2 2 ê ú ê1 , a= ê b= ê ú ︙ ︙ ︙ ︙ êê úú êê ë10 10 … 10û ë1 程序如下: temp = 1 :10; a = repmat( temp ,1,10); b = repmat( temp,10,1); c= a+ b

运行结果为:

2

2 ︙

2

… 10ù ú … 10ú 。 ︙ú úú … 10û


c= 2 3 4 5 6 7 8 9 10 11

3 4 5 6 7 8 9 10 11 12

4 5 6 7 8 9 10 11 12 13

5 6 7 8 9 10 11 12 13 14

6 7 8 9 10 11 12 13 14 15

7 8 9 10 11 12 13 14 15 16

8 9 10 11 12 13 14 15 16 17

9 10 11 12 13 14 15 16 17 18

10 11 12 13 14 15 16 17 18 19

11 12 13 14 15 16 17 18 19 20

【例 1. 4. 3】 批量产生字符串 001. 002. 003. 100. j pg, j pg, j pg,…, j pg。

【解析】 由表 1. 22 可知,字符串以数字前 填 零 的 方 式 输 出,格 式 字 符 串 可 以 使 用 %03d

的形式。程序如下:

str 1 = sprintf(%03d. 1: 100]); jpg ,[ str 2 = reshape( str 1,7,100); 2 picName = str

字符数组 p i cName为:

空 航

picName = 001. jpg 002. jpg 003. jpg … 100. jpg

提取字符串时采用 p i cName ( n,:)的方式。例如, i cName( 30,:)为 030. p j pg 。

更高?

【思考】 如果采用循环的方式批量产生这些字符串,如何 编 写 程 序? 哪 种 方 法 执 行 效 率

N = 100; tic;

代码 1(采用循环方式):

% 为字符数组 picNames 预分配内存 picNames = repmat( ,N,7); fori = 1 :N i,:)= sprintf(%03d. picNames( jpg ,i); end toc

命令行输出: Elapsedtimeis0. 001760seconds.

代码 2(仍然采用循环方式,不过是将字符串存入字符串单元数组中):

N = 100; tic;

N,1); picNames = cell(

% 为字符串单元数组 picNames 预分配内存


fori = 1 :N i}= sprintf(%03d. picNames{ jpg ,i); end toc

命令行输出: Elapsedtimeis0. 001593seconds.

代码 3(采用矩阵运算方式):

N = 100; tic;

str 1 = sprintf(%03d. 1: 100]); jpg ,[ ( , , ) ; str 2 = reshape str 1 7 100 2; picName = str toc

命令行输出:

Elapsedtimeis0. 000097seconds.

这个结果再次证明,矩阵运算的运行效率远远高于循环运算。

【例 1. 4. 4】 输出九九乘法表到命令行,输出格式如下:

1×3=3 2×3=6 3×3=9

空 航

1×2=2 2×2=4

1×1=1

1×4=4 2×4=8 3×4=1 2 4×4=1 6

1×5=5 2×5=1 0 3×5=1 5 4×5=2 0 5×5=2 5

1×6=6 2×6=1 2 3×6=1 8 4×6=2 4 5×6=3 0 6×6=3 6

1×7=7 2×7=1 4 3×7=2 1 4×7=2 8 5×7=3 5 6×7=4 2 7×7=4 9

1×8=8 2×8=1 6 3×8=2 4 4×8=3 2 5×8=4 0 6×8=4 8 7×8=5 6 8×8=6 4

1×9=9 2×9=1 0 3×9=1 5 4×9=3 6 5×9=4 5 6×9=5 4 7×9=6 3 8×9=7 2 9×9=8 1

【解析】 输出字符串到命令行,可以采用 d i s r i n t f函数。共 9 行,每行最多为 7×9= p和 s p

63 个字符。乘号“× ”可以从 Wo r d 里粘贴到程序文件中。程序如下:

N = 9; rows = [ 1 :N]; %行 ; lines = rows %列 ( ) ; strTemp = blanks 7*N % 将每行的字符串预存到字符数组 s t r T e m i s p 中,由 d p函数显示到命令窗口 : foriRow = 1 9 forjLine = 1 :iRow m = jLine * 7 - 6; n = m + 7; strTemp( 1,m :n)= sprintf(%d×%d=%2d , jLine,iRow,jLine*iRow); end disp( strTemp); end


运行结果如图 1. 29 所示。

图 1. 29 例 1. 4. 4 运行结果

问题 3 如何生成随机矩阵 【例 1. 4. 5】 产生一个随机矩阵: s i z e为 1×100,元素为区间[-5050]内的整数。查找

该矩阵中值在( 2040)范围内的元素,返回其下标。

【解析】 产生元素为整数的随机矩阵使用r and i函数,返回指定范围内的元素下标用f i nd

函数。

运行结果为: 36

40

42

50

63

67

72

75

77

78

85

87

31

b= 22

空 航

a = randi([-5050],1,100); b = find( a 20&a 40)

程序如下:

【例 1. 4. 6】 产生一个元素为 0 和 1、 s i z e为 100×5 的随机矩阵,返回元素全为 1 的行。

【解析】 元素全为 1 可以使用 a l l函数来判断。 程序如下:

a = randi([ 0,1],100,5); ( b=find all( a, 2))

运行结果为: b= 66

【例 1. 4. 7】 随机产生 10 个 12 位的 0、 1 二进制序列,要求每个序列中包含 7 个 1 和 5

个 0,形式如:

111111100000

111111000001

001110101110


【解析】 要指定一个位随机序列中 1 的个数,需要用到 r ande r r函数,其调用格式为:

out = randerr( mRow,nLine,nums)

随机产生一个尺寸为[ mRownL i ne]的 doub l e数组,数组元 素 为 0 或 1,其 中 每 行 1 的 个 。 数为 nums 程序如下:

N =10; data = randerr( N,12,7); data = data(:); str 1 = dec 2bin( data); str 2 = reshape( str 1,12,N); seque = str 2

运行结果为:

版 出 学 大 天 空 航

如何查找或删除数据中满足条件的元素

问题 4

seque = 100110100111 111101100010 001010011111 100011111100 010101101101 010101111100 101001011011 111001100011 100011110011 001110101101

【例 1. 4. 8】 产生一个随机矩阵: s i z e为 10×100,元素为区间[ 50100]内的整数。查找

该矩阵每行中值大于 80 的元素,返回其个数。

【解析】 产生元素为整数的随机矩阵用 r and i函数;查找每行中值大于 80 的元素虽然可 以轻松地用循环来解决,但是建议尽量少用循环而改用矩阵运算。 程序如下: N = 10; a = randi([ 50100],N,100); %%%%%%% 以下代码段为循环方式实现查找 %%%%%%%%% num 1 = ones( N,1); fori = 1 :N num 1( i)= nnz( a( i,:) 80);

end num 1

%%%%%%% 以下代码段为矩阵运算方式实现查找 %%%%%%% num 2 = sum( a 80,2)


【例 1. 4. 9】 有一个大小为 8×6 的数值型单元矩阵: [ 00][ 10][ 00][ 01][ 00][ 11] [ 00][ 00][ 11][ 00][ 11][ 00] [ 11][ 00][ 11][ 00][ 00][ 10] [ 10][ 00][ 00][ 10][ 00][ 00] [ 00][ 00][ 11][ 00][ 11][ 00] [ 11][ 00][ 00][ 00][ 00][ 00] [ 00][ 00][ 10][ 01][ 11][ 01] [ 00][ 00][ 11][ 00][ 00][ 00]

不使用循环语句,查找该矩阵中某一列的特定矩阵,返回该特定矩阵所在的行号。本例

假定查找第 1 列中的特定矩阵[ 1,1],并返回[ 1,1]所在的行号。 【解析】 有两种思路解决这个问题。

思路 1:将特定矩阵[ 1,1]的 行 扩 展,与 提 供 的 数 值 单 元 矩 阵 执 行 数 组 减 法 运 算,然 后 用

any 查找全零行; 思路 2:将数值单元矩阵 转 化 为 字 符 串 单 元 数 组,采 用 前 面 提 到 的 3 个 字 符 串 查 找 函 数

空 航

%%%%%%%% 生成已知量 %%%%%%%%% A = {[ 00][ 10][ 00][ 01][ 00][ 11] [ 00][ 00][ 11][ 00][ 11][ 00] [ 11][ 00][ 11][ 00][ 00][ 10] [ 10][ 00][ 00][ 10][ 00][ 00] [ 00][ 00][ 11][ 00][ 11][ 00] [ 11][ 00][ 00][ 00][ 00][ 00] [ 00][ 00][ 10][ 01][ 11][ 01] [ 00][ 00][ 11][ 00][ 00][ 00]}; nLine = 1; mat = [ 1,1]; a = cell 2mat( A(:,nLine));

i smembe r和 s t rma t ch 中的任何一个查找特定矩阵[ 1,1]所转化成的字符串。 s t r cmp、 程序代码如下:

%%%%%%%%% 直接数值比较 %%%%%%%%%%%%%%% % b = repmat( mat,size( A,1),1); % index 1 = find(~any( a - b,2)) %%%%%%%%% 转化为字符串比较 %%%%%%%% mLines = size( A,1); str_a = num 2str( a); str_b = num 2str( mat); cell_a = mat 2cell( str_a,ones( 1,mLines),length( str_b)); index 2 = find( strcmp( cell_a,str_b)) % 采用 strcmp 函数 index 3 = find( ismember( cell_a,str_b))% 采用 ismember 函数 index 4 = strmatch( str_b,cell_a) % 采用 strmatch 函数

思路 1 直接进行 数 值 比 较,速 度 最 快,其 次 是 思 路 2 的 s t r cmp 比 较、 s t rma t ch 查 找、 i s -

membe r判断。


【例 1. 4. 10】 有一个矩阵 A:

éê -5 -4 -3 -2ùú 0 1 2ú ê -1 ú ê ë 3 4 5 6û 将 矩阵 A 中小于等于 -2 的值替换为0,大于 -2 小于等于3 的值替换为1,大于3 的值替换 为 2。要求矩阵 A 中的每个值只进行一次替换。

【解析】 可以查找到满足条件的值的位置,将每次的替换值存入 1 个临时矩阵中,该矩阵

中除替换值外的其他元素均为 0。最后,将全部替换后得到 3 个临时矩阵直接相加即可。 程序如下:

A= [-5,-4,-3,-2;-1,0,1,2;3,4,5,6]; % 转换方法: a =-2 ---- 0; -2 a =3--- 1; a 3------- 2。其中 a 为 A 中的元素。 sizeA = size( A); ( a 1 = zeros sizeA); a 2=a 1; a 3=a 1; a 1( A = -2)= 0; % 采用逻辑数组作为索引值 a 2( A -2&A = 3)= 1; % 采用逻辑数组作为索引值 a 3( A 3)= 2; % 采用逻辑数组作为索引值

B= a 1+a 2+a 3

运行结果如下: 0 1 2

0 1 2

0 1 2

0 1 1

空 航

B=

éê2 2 2 0ù ú ê3 3 1 3ú ê ú êê2 1 1 3úú ë0 0 1 0û 矩阵 B 为:

【例 1. 4. 11】 有两个矩阵 A 和 B,矩阵 A 为:

éê2 1 1 0ùú ê2 3 1 2ú ê ú êê3 2 2 2úú ë0 1 2 3û 用矩阵 B 中第 1 行和第 1 列的元素,将矩阵 A 中第 1 行和第 1 列的元素替换掉,求 生

成的矩阵 C。

【解析】 逆向思考一下,题目的意思等价为:用矩阵 A 中位置为[ 2 :4,2 :4]的元素,将

矩阵 B 中位置为[ 2 :4,2 :4]的元素替换掉。 程序如下:


A= [ 2 2 2 0 3 3 1 3 2 1 1 3 0 0 1 0]; B =[ 2 1 1 0 2 3 1 2 3 2 2 2 0 1 2 3]; B( 2 :4,2 :4)= A( 2 :4,2 :4); C= B

运行结果如下: C= 0 3 3 0

1 1 1 1

如何给数组元素排序

问题 5

1 3 1 0

2 2 3 0

【例 1. 4. 12】 有一个 2×5 的矩阵:

空 航

éê1 5 9 8 7ùú ê ú ë2 6 4 3 0û 将其元素随机排列,生成一个新的 2×5 阶矩阵。

【解析】 采用 r andpe rm 函数对原矩阵的元素索引值进行随机排序,从而获得所求矩阵。

程序如下:

运行结果如下: data = 3 1

0 6

data = [ 15987;26430]; index = randperm( 10); ( data = data reshape( index,size( data)))

2 7

4 9

5 8

【例 1. 4. 13】 有一个大小为 1×26 的字符串单元数组,内容如下: 0-0-0. x l s

1-0-0. x l s

10-0-0. x l s 11-0-0. x l s 12-0-0. x l s

13-0-0. x l s 14-0-0. x l s 15-0-0. x l s 16-0-0. x l s 17-0-0. x l s

18-0-0. x l s 19-0-0. x l s 19-39-52. x l s 2-0-0. x l s 20-0-0. x l s 21-0-0. x l s 22-0-0. x l s 23-0-0. x l s 23-0-29. x l s 3-0-0. x l s

4-0-0. x l s 5-0-0. x l s 6-0-0. x l s 7-0-0. x l s 8-0-0. x l s 9-0-0. x l s 要求对该单元数组的单元进行排序,生成新的字符串单元数组如下:


0-0-0. x l s 1-0-0. x l s 2-0-0. x l s 3-0-0. x l s 4-0-0. x l s 5-0-0. x l s 6-0-0. x l s 7-0-0. x l s 8-0-0. x l s 9-0-0. x l s 10-0-0. x l s

11-0-0. x l s 12-0-0. x l s 13-0-0. x l s 14-0-0. x l s 15-0-0. x l s

16-0-0. x l s 17-0-0. x l s 18-0-0. x l s 19-0-0. x l s 19-39-52. x l s

20-0-0. x l s 21-0-0. x l s 22-0-0. x l s 23-0-0. x l s 23-0-29. x l s 注意,单元内容以 19、 开头的单元各有两个, 它们之间的排序也要考虑。 23

【解析】 每个单元的字符串依次包含 3 个数值,可以用 s t r t ok 函数 将 这 些 数 值 都 提 取 出

来。首先按第 1 个数值从小到大排序;当第一个 数 值 相 等 时,按 第 2 个 数 值 排 序;第 2 个 数 值 相等时,按第 3 个数值排序。

注意,不能采用 so r t函数排序,因为 s o r t函数虽然也可以对字符串单元数组排序,但是它

是完全按 ASCI I值排序的,不会分析每个字符串中包含的数值。 可以采用两种方法进行排序。

方法 1:直接用 so r t r ows函数对生成的 26×3 数值矩阵排序。

方法 2:将每个单元内的 3 个数 值,按 排 序 的 权 重 大 小 组 合 成 1 个 新 数 值,最 后 将 新 数 值

进行排序,得到最终的单元排序方案。

程序如下:

空 航

data = {0-0-0. xls 1-0-0. xls 10-0-0. xls ... 11-0-0. xls 12-0-0. xls 13-0-0. xls 14-0-0. xls ... 15-0-0. xls 16-0-0. xls 17-0-0. xls 18-0-0. xls ... 19-0-0. xls 19-39-52. xls 2-0-0. xls 20-0-0. xls ... 21-0-0. xls 22-0-0. xls 23-0-0. xls 23-0-29. xls ... 3-0-0. xls 4-0-0. xls 5-0-0. xls 6-0-0. xls ... 7-0-0. xls 8-0-0. xls 9-0-0. xls }; % 原始的字符串单元数组 remain = data; %remain 用于保存提取数值后的字符串,用于 % 再次提取其中剩余的数值 num = zeros( length( data),3); % 用于保存每次提取的数值 [ str_num 1,remain]= strtok( remain,- ); % 提取第 1 组数值 num(:,1)= str 2double( str_num 1); [ str_num 2,remain]= strtok( remain,- ); % 提取第 2 组数值 num(:,2)= str 2double( str_num 2); [ str_num 3,remain]= strtok( remain,.); % 提取第 3 组数值 num(:,3)= str 2double( str_num 3); num = abs( num); % 对数值取绝对值 %%%%%%%% 以下为方法 1 的实现代码 %%%%%%%%%%%%% [ num 2,index 1]= sortrows( num,[ 123]); % 依次按第 1 列、第 2 列、第 3 列的数值进行排序 data 2 = data( index 1) %%%%%%%% 以下为方法 2 的实现代码 %%%%%%%%%%%%% num 3 = num(:,1)* 10000 + num(:,2)* 100 + num(:,3); % 根据数值的权重,获得新数值 [ num 4,index 2]= sort( num 3); % 新数值排序 data 3 = data( index 2) % 获得最终字符串单元数组


运行结果如下:

空 航

data 2= Columns1through7 0-0-0. xls 1-0-0. xls 2-0-0. xls 3-0-0. xls 4-0-0. xls 50-0. xls 6-0-0. xls Columns8through13 7-0-0. xls 8-0-0. xls 9-0-0. xls 10-0-0. xls 11-0-0. xls 12-0-0. xls Columns14through19 13-0-0. xls 14-0-0. xls 15-0-0. xls 16-0-0. xls 17-0-0. xls 18-0-0. xls Columns20through25 19-0-0. xls 19-39-52. xls 20-0-0. xls 21-0-0. xls 22-0-0. xls 23-0-29. xls Column26 23-0-0. xls data 3= Columns1through6 0-0-0. xls 1-0-0. xls 2-0-0. xls 3-0-0. xls 4-0-0. xls 50-0. xls Columns7through12 6-0-0. xls 7-0-0. xls 8-0-0. xls 9-0-0. xls 10-0-0. xls 11 -0-0. xls Columns13through18 12-0-0. xls 13-0-0. xls 14-0-0. xls 15-0-0. xls 16-0-0. xls 17-0-0. xls Columns19through24 18-0-0. xls 19-0-0. xls 19-39-52. xls 20-0-0. xls 21-0-0. xls 22-0-0. xls Columns25through26 23-0-29. xls 23-0-0. xls


第 2章

/O 文件I

2. 1 知识点归纳 本章内容: /O 操作 ◆ 高级文件I ◇ 读写 MAT 或 ASCI I文件

◇ 读写 TXT 文件 ◇ 读写 Exc e l文件

◇ 读写图像文件 ◇ 读写音频文件

大 天

◇ 读写二进制文件 ◇ 控制文件位置指针

/O 操作 ◆ 低级文件I ◇ 打开文件和关闭文件

空 航

◇ 读写格式化的文本文件

2. 1. 1 高级文件I/O 操作

数据输入,是指从磁盘文件或剪贴板中获取数据,加载到 MATLAB 工作空间;数据输出, 是指将 MATLAB 工作空间的变量保存到文件中。

/O,针对不同的数据格式文件,提 供 不 同 的 文 件 I /O 函 数,有 现 成 的 函 数 供 使 高级文件I

/O,使用文件标识符访问任何类型的数据文件,更加灵活地完 用,仅需少量的编程;低级文件I

成相对特殊的任务,需要较复杂的编程。

文本用 Un i code码来表示字符。ASCI I码是 Un i c ode 码的 子 集。Un i c ode 码 不 仅 可 以 表

示字母和数字,还可以表示大部分 汉 字。例 如 字 符 “ 1”的 ASCI I码 是 49,而 汉 字 “飞”的 Un i 、 。文本格式的数据之间采用空线间隔( 码是 空格、 等) 来分隔。二 进 制 格 式 code 39134 \t \n 的数据长度可以是 8 位、 16 位、 32 位或 64 位。 /O 函数见表 2. 文件 I 1。

加载/保存 工作区

l oad

s ave

说 加载到工作区 保存工作区

/O 函数 表 2. 1 文件 I 明

加载/保存 工作区

l oad

s ave

说 加载到工作区 保存工作区


续表 2. 1 类

文件打开/ 关闭 /O 二进制 I

f open

f c l o s e f r e ad

fwr i t e

f s c an f

/O 格式化 I

f r i n t f p f t l ge

f t s ge

f e r r o r

打开文件

f eo f

关闭文件 文件

从文件中读取二进制数据

f s e ek

/O 低级 I

把二进制数据写入文件

f t e l l

f r ewi nd

从文件中读取格式化数据 把格式化数据写入文件

t empd i r

临时文件、 目录

读取文件的一行,忽略换行符 读取文件的一行,不忽略换行符

载入数据

/O 操作的错误情况 文件 I 检测文件的结尾 设置文件的位置 检查文件的位置 文件指针重定位 得到临时目录名

t empname 得到临时文件名

impo r t da t a 从磁盘文件中加载数据到结构体

【注】 打开 Wi ndows平台的应用程序,可以采用 wi nopen 函数。例如: % 切换到目录 e: \example \ % 显示当前目录下的文件

cde: \example \ a = ls a= . .. RS 485. doc a 1. gif winopen( a( 3,:)) b = dir(*. gif )

% 采用应用程序默认的打开方式打开文件 RS 485. doc % 查看当前目录下所有的 GIF 文件

b=

空 航

1. name: a gif date:22- 六月 -200914: 49: 07 bytes:42873 isdir:0 datenum:7. 3395e+005 winopen( b. name) % 采用应用程序默认的打开方式打开文件 a 1. gif

1.读写 MAT 或 ASCI I文件 MATLAB 提 供 一 种 特 殊 的 数 据 格 式 文 件 用 来 保 存 工 作 空 间 中 的 变 量:MAT 文 件。

MAT 文件是一种双精度、二进制的 MATLAB 格式文件,扩展名为 . ma t。 MAT 文件具有可移植性。一台机器上生成的 MAT 文件,在另一台装有 MATLAB 的机 器上可以正 确 读 取,而 且 还 保 留 不 同 格 式 允 许 的 最 高 精 度 和 最 大 数 值 范 围。 它 们 也 能 被 MATLAB 之外的其他程序(如 C 或 FORTRAN 程序)读写。 MAT 文件分为两部分:文件头 部 和 数 据。 文 件 头 部 主 要 包 括 一 些 描 述 性 文 字 和 相 应 的 版本标识;数据依次按数据类型、数据长度、数据内容三部分保存。

将数据输出到 MAT 文件使用 s ave函数,其调用格式见表 2. 2。 表 2. 2 s a v e函数调用格式

函数调用格式

函数格式说明

s ave

将工作空间中所有变量保存到当前目录下的文件: ma t l ab. ma t

s avef i l enamex1x2…xn

将变量 x1, x2,…, xn 保存到当前目录下的文件: f i l ename. ma t

s avef i l ename

将工作空间中所有变量保存到当前目录下的文件: f i l ename. ma t


续表 2. 2 函数调用格式

函数格式说明

s ave(f i l ename ,-s t r uc t ,s )

保存结构体 s的所有字段为文件f i l ename. ma t里的独立变量

s avef i l enames*

将工作空间中 s开头的变量全部保存到f i l ename. ma t中;* 为通配符

i l ename ,-s t r uc t ,s ,f 1 ,f 2 ,…) s ave(f

s ave(f i l ename ,…)

保存结构体 s的指定字段为文件f i l ename. ma t里的独立变量 s ave指令的函数格式用法

s ave(…,f o rma t)

按照不同的输出格式f o rma t来保存数据,见表 2. 3

表中,

s f i l e: ① 如果要查看f i l ename. ma t中已经保存了哪些变量,使用 who

whos -filefilename

空 航

clear str 1 = dafei ; str 2 = dafei 2; str 3 = dafei 3; savestrsstr* whos -filestrs % 查看文件 strs. mat 中保存有哪些变量 Name Size Bytes Class str 1 1x 5 10 chararray str 2 1x 6 12 chararray str 3 1x 6 12 chararray Grandtotalis17elementsusing34bytes

如:

② 如果要保存结构体,用户可选 择 保 存 整 个 结 构 体 或 每 个 字 段 为 独 立 变 量,或 只 保 存 指 定的字段为独立变量。例如,对于结构体 S:

S. a = 12. 7; S. b = {abc ,[ 45;67]}; S. c = Hello! ;

S S= a:12. 7000 b:{abc [ 2x 2double]} c: Hello!

若要保存整个结构体到 s 1. ma t: saves 1S % 将结构体 S 保存到 s 1. mat whos -files 1 Name Size Bytes Class S 1x 1 550 structarray Grandtotalis19elementsusing550bytes

若保存结构的每个字段为独立的变量:


saves 2 -struct S % 将结构的字段保存为独立的变量 whos -files 2 Name Size Bytes Class a 1x 1 8 doublearray b 1x 2 158 cellarray c 1x 6 12 chararray Grandtotalis16elementsusing178bytes

若只保存指定的字段为独立的变量: saves 2 -struct Sac % 保存结构 S 内的字段 a 和 c 为独立的变量 whos -files 2 Name Size Bytes Class a 1x 1 8 doublearray c 1x 6 12 chararray Grandtotalis7elementsusing20bytes

③ 扩展已存 在 的 MAT 文 件,使 用 -append 选 项。 覆 盖 MAT 文 件 中 已 存 在 的 同 名 变 量。如:

空 航

a = 1; b = 2; c = 3; saved 1ab % 保存变量 a 和 b 到 d 1. mat 中 – 覆盖 中原来的变量 saved 1c append % d 1. mat c whos -filed 1 Name Size Bytes Class a 1x 1 8 doublearray b 1x 1 8 doublearray c 1x 1 8 doublearray Grandtotalis3elementsusing24bytes

如果不使用 -append 选项,同名 MAT 文件中的所有内容丢失。

输出数据默认采用二进制的 MAT 格式。若要输出为 ASCI I格式,调用格式见表 2. 3。 表 2. 3 s a v e输出格式

调用格式

s avef i l ename a s c i i

8 位 ASCI I格式

s avef i l ename a s c i i doub l e

16 位 ASCI I格式

s avef i l ename a s c i i t abs

s avef i l ename a s c i i doub l e t abs

8 位 ASCI I格式,制表符定界 16 位 ASCI I格式,制表符定界

保存为任何 ASCI I值时,要注意:

① 被保存的变量要么是二维的 doub l e型数组,要么是二维的字符数组。如果 包 含 复 数, 会引起虚部丢失,因为 MATLAB 不能加载非数“ i”。 ② 为了能用l oad 函数读文件,必须保证所有变量有相同的列数。如果使用 MATLAB 以 外程序读,可放松这个限制。

③ 字符数组中的每个字符都被转换成等于其 ASCI I码的浮点数,以浮点数字符串的形式


写入文件;保存的文件中没有信息显示原来的值是数字还是字符。

④ 所有保存的变量值合并为一个变量,变量 名 就 是 ASCI I文 件 名(不 含 扩 展 名);建 议 一 次只保存一个变量。 从 MAT 文件中加载数据到工作空间使用l oad 函数,见表 2. 4。 表 2. 4 l o ad 函数调用格式

函数调用格式

函数格式说明

l oad

加载 MATLAB. ma t中所有变量,如果加载前已存在同名变量,覆盖

l oad(f i l ename , X , Y , Z )

加载f i l ename. ma t中变量 X, Y, Z;加载前已存在同名变量,覆盖

l oadf i l ename

加载f i l ename. ma t中所有变量,如果加载前已存在同名变量,覆盖

l oadf i l enames*

加载f i l ename. ma t中以 s开头的变量;加载前已存在同名变量,覆盖

l oad(-a s c i i ,f i l ename )

将文件当做 ASCI I文件加载;如果不是数字文本,返回错误

l oad(-ma t ,f i l ename )

将文件当做 MAT 文件加载;如果不是 MAT 文件,返回错误

S =l oad(…)

l oad 指令的函数格式用法

2.读写 TXT 文件 MATLAB 读写 TXT 文件使用的函数见表 2. 5。

【注意】 除非必须与非 MATLAB 程序进行数据交换,存 储 和 加 载 文 件 时,都 应 用 MAT 文件格式。这种格式高效且移植性强,保存了所有 MATLAB 数据类型的细节。

数据类型

c s v r e ad

定界符

数字

d lmr e ad

逗号

数字

t ex t r e ad

字母和数字

c s vwr i t e

数字

空 航

表 2. 5 读写 TXT 文件使用的函数

d lmwr i t e

数字

函数说明 读逗号定界的数值文件,返回数字矩阵

任何字符

读 ASCI I码定界的数值文件,返回数字矩阵

任何字符

按指定格式读整个文本文件,返回多个变量

逗号

写数字矩阵到逗号定界的数值文件 写数字矩阵到 ASCI I码定界的数值文件

任何字符

表 2. 5 中, t ex t r e ad 常用的调用格式为:

[ A, B, C,…]= textread(filename ,format )

采用指定格式f o rma t,从文件f i l ename中读取数据到变量 A, B, C,…,直至整个文件读取

完毕。该格式适合读格式已知的文件。 常用的格式字符串见表 2. 6。 格

%d

表 2. 6 常用的格式字符串 说

读一个带符号整数值

%u

读一个整数值

%s

读一个空线间隔或定界符隔开的字符串

doub l e数组

doub l e数组

%f

读一个浮点值

%q

读一个双引号字符串,忽略引号

字符串单元数组

读字符,包括空线间隔

字符数组

%c

doub l e数组

字符串单元数组


【注】 t ex t r e ad 在 以 后 的 MATLAB 版 本 中 将 被 t ex t s c an 取 代,所 以 对 t ex t r e ad 只 作 一 般的了解即可。 例如,有一个矩阵 a:

a= [ 123; 456] a= 1 2 3 4 5 6

用c s vwr i t e函数将矩阵 a写到文件f i l e 1 中: csvwrite(file 1, a)

用t i l e 1 的内容: ype函数查看文件f typefile 1 1, 2, 3 4, 5, 6

用c s v r e ad 函数读f i l e 1:

m=csvread(file 1) m= 1 2 3 4 5 6

用d lmwr i t e函数将矩阵 a写到文件f i l e 2 中,“:”为定界符:

空 航

dlmwrite(file 2, a,:)

京 北

typefile 2 1: 2: 3 4: 5: 6

使用t i l e 2 的内容: ype函数查看文件f

用d lmr e ad 函数读f i l e 2:

n=dlmread(file 2 ,:) n= 1 2 3 4 5 6

用t ex t r e ad 函数读f i l e 1 文件,返回三个列向量 m1、 m2 和 m3:

[ m 1m 2m 3]=textread(file 1 ,%d,%d,%d ) m 1= 1 4 m 2= 2 5 m 3=


3 6

【注】 读写 TXT 文件中的数据,也可以使用l oad 和 s ave函数。例如,若文件 a. t x t中存

储了一个如图 2. 1 所示的矩阵,将该数据提取出来,存到变量 b 中:

b = load(a. txt ) b= 1 2 3 4 5 6 7 8 9

空 航

将生成的变量 b 存入 b. t x t中:

图 2. 1 读取 TXT 文件中的数据

save b. txtb -ascii typeb. txt 1. 0000000e+000 2. 0000000e+000 3. 0000000e+000 4. 0000000e+000 5. 0000000e+000 6. 0000000e+000 7. 0000000e+000 8. 0000000e+000 9. 0000000e+000

3.读写 Ex c e l文件 读写 Exc e l文件的相关函数见表 2. 7。

表 2. 7 读写 Ex c e l文件的相关函数

x l s f i n f o

x l swr i t e

检查文件是否包含 Exc e l表格

写 Exc e l文件

x l s r e ad

读 Exc e l文件

x l s f i n f o 调用格式为:

type = xlsfinfo(filename )或 xlsfinfofilename

如果指定文件f i l ename能被 x l s r e ad 读 取,则 返 回 字 符 串 Mi c r o s o f tExc e lSp r e adshe e t; 否则返回为空。 [ type,sheets]= xlsfinfo(filename )

如果指定文件f i l ename能被 x l s r e ad 读取,则返回t c r o s o f tExc e lSp r e adshe e t; ype= Mi 否则返回为空。she e t s 为 字 符 串 单 元 数 组 名,它 包 含 文 件 中 每 个 工 作 表 的 名 称,如 She e t 1、


She e t 2 等。

x l swr i t e调用格式为: xlswrite(filename ,M)

将矩阵或字符串单元数组 M 写入 Exc e l文件f i l ename中。例如: 123; 456]) xlswrite(a 1 ,[

则当前目录下生成一个 Exc e l文件 a 1. x l s,文件内容如图 2. 2 所示。

图 2. 2 写 Ex c e l文件 xlswrite(filename ,M,sheet)

将矩阵或字符串单元数组 M 写入f i l ename中 she e t指定的页中。she e t可为一个 doub l e 型的正整数,表示工作页的序号; she e t也可以为一个带引号的字符串,表示工作页的名称。

若 she e t表示的工作页不存在,将新建一个工作页。此时,MATLAB 会显示警告信息:

Warning:Addedspecifiedworksheet.

xlswrite(filename ,M,sheet, range )

将矩阵或字符串单元数组 M 写入f i l ename中 she e t指定的工作页中r ange指定的矩形范 围, she e t省略时将 M 写入第 1 个工作页中。r ange为下列格式的字符串:左上角单元格名称:

空 航

右下角单元格名称,如 D2: F4。r ange指定的矩形范围大小应该等于 M 的尺寸大小。例如:

xlswrite(a 1 ,[ 2: F 4) 123;456;7, 8, 9],3, D

产生的数据如图 2. 3 所示。

图 2. 3 在指定位置写入矩阵

status = xlswrite(filename ,…)

返回写操作的完成状态。写操作成功时 s t a t us=1,否则 s t a t us=0。

[ status,message]= xlswrite(filename ,…)

返回写操作的完成状态和写操作过程中产生的警告或错误信息。

x l s r e ad 调用格式为:

num = xlsread(filename )

从 Exc e l文件f i l ename的第 1 个工作页中读取所有 的 数 值 到 doub l e 型 数 组 num 中。它

忽略头行、头列、尾行和尾列的所 有 单 元 为 文 本 的 行 列,其 他 单 元 中 的 文 本 全 部 读 取 为 NaN。

例如,文件 a 1. x l s如图 2. 4 所示。


图 2. 4 读取 Ex c e l文件中的数据

0 0 0 0 0 0 0 0

NaN NaN NaN NaN NaN NaN NaN NaN

5112101 5112103 5112105 5112107 5112109 5112110 5112111 4112201

63 73 88 82 80 70 72 0

63 73 88 82 80 70 72 0

M=xlsread(a 1) M= 1 51121 2 51121 3 51121 4 51121 5 51121 6 51121 7 51121 8 51122

读取 a 1. x l s中的数据到矩阵 M 中:

num = xlsread(filename ,-1)

num = xlsread(filename ,sheet)

手动框选要读取的数据块,返回到矩阵 num 中。

空 航

读f i l ename中指定页的数据到矩阵 N 中。

num = xlsread(filename , range )

读f i l ename中第 1 页指定区域的 数 据 到 矩 阵 N 中。 例 如,对 于 图 2. 4的文件a 1. x l s,读

取从单元格 A2 到 G2 的一行:

num = xlsread(a 1. xls , A 2: G 2) num = 1 51121 5112101

NaN

读取从单元格 G2 到 G9 的一列数据: num = xlsread(a 1. xls , G 2: G 9) num = 63 73 88 82 80 70 72 0 num = xlsread(filename ,sheet, range )

读f i l ename中指定页、指定区域的数据到矩阵 N 中。

0

63

63


num = xlsread(filename ,sheet, range , basic )

以基本输入模式,读 f i l ename 中 指 定 页 的 数 据 到 矩 阵 num 中,参 数 r ange 被 忽 略, she e t

必须为带引号的字符串且区分字 母 大 小 写。 这 种 模 式 限 制 了 数 据 输 入 的 能 力,不 将 Exc e l当 做一个 COM 服务器。

[ num,txt]= xlsread(filename ,…)

读f i l ename中的数据,返回数值数据到 doub l e型数组 num 中,文本数据到字符串单元数

组t x t中。t x t中对应数值数据的位置为空字符串。例如,对于图 2. 4 的文件 a 1. x l s:

期末成绩

总成绩

备注

平时成绩

63 73 88 82 80 70 72 0

63 73 88 82 80 70 72 0

0 0 0 0 0 0 0 0

NaN NaN NaN NaN NaN NaN NaN NaN

空 航

[ num,txt]= xlsread(a 1. xls ) num = 1 51121 5112101 2 51121 5112103 3 51121 5112105 4 51121 5112107 5 51121 5112109 6 51121 5112110 7 51121 5112111 8 51122 4112201 txt = 序号 班名 学号 姓名 陈 李 刘 任 苏 王 王

[ num,txt,raw]= xlsread(filename ,…)

读f i l ename中的数据,返回数值数据到 doub l e型数组 num 中,非数值的文本数据到字符

串单元数组t x t中,未处理的单元 数 据 到 字 符 串 单 元 数 组 r aw 中。r aw 中 包 含 数 值 数 据 和 文 : 本数据。例如,对于图 2. 的文件 4 a 1. x l s [ num,txt,raw]= xlsread(a 1. xls ); raw raw = 序号 班名 学号 姓名 [ 1] [ 陈 51121] [ 5112101] [ 2] [ ] [ ] 李 51121 5112103 [ 3] [ ] [ ] 刘 51121 5112105 [ 4] [ ] [ ] 任 51121 5112107 [ 5] [ ] [ ] 苏 51121 5112109 [ 6] [ ] [ ] 王 51121 5112110 [ 7] [ ] [ ] 王 51121 5112111 [ 8] [ ] [ ] 曹 51122 4112201

4.读写图像文件 读写图像文件的函数见表 2. 8。

平时成绩 [ 0] [ 0] [ 0] [ 0] [ 0] [ 0] [ 0] [ 0]

期末成绩 [ 63] [ 73] [ 88] [ 82] [ 80] [ 70] [ 72] [ 0]

总成绩 [ 63] [ 73] [ 88] [ 82] [ 80] [ 70] [ 72] [ 0]

备注 [NaN] [NaN] [NaN] [NaN] [NaN] [NaN] [NaN] 缺考


表 2. 8 读写图像文件的函数 函

调用格式

函数说明

A =imr e ad( f i l ename, fmt)

读图像文件 f i l ename。 如 果 文 件 不 在 当 前 目 录, f i l ename 中 应

[…]=imr e ad( f i l ename)

根据后缀名识别图像格式

[ X, map]=imr e ad( f i l ename, fmt)

imr e ad

包含文件路径。fmt为图像 文 件 格 式,如 果 缺 省,MATLAB 会

imwr i t e( A, f i l ename, fmt)

imwr i t e( X, map, f i l ename, fmt)

imwr i t e

imwr i t e(…, f i l ename)

以格式fmt写图像数据 A 到图像文 件 f i l ename。A 可 为 m×n

(灰度图像)或 m×n×3(彩 色 图 像)数 组。fmt缺 省,格 式 依 据

f i l ename后缀名识别

i n f o =imf i n f o( f i l ename, fmt)

imf i n f o

返回图像文件的信息

i n f o =imf i n f o( f i l ename)

imr e ad 读取图像的 RGB 值 并 存 储 到 一 个 M×N×3 的 整 数 矩 阵 中,元 素 值 范 围 为 [ 0, 255]。 M×N×3 的整数矩阵 可 以 想 象 成 3 个 重 叠 在 一 起 的 颜 色 模 板,每 个 模 板 上 有 M×N 个点。图像的像素大小为 M×N,每个像素点对应有 3 个在[ 0,255]范围内的值,分别表示该

点的 R、 G、 B 值。 常见的图像文件格式见表 2. 9。

i f g

包括 1、 8 和 24 位不压缩图像

8 位图像

bmp

格式说明

rj j pg o peg

空 航

表 2. 9 常见的图像格式

格式说明 8、 12 和 16 位基线的 JPEG 图像

例如,有一张名为 ha rb i n. \MATLAB7\下,查看图片信息使用imj pg 的图片位于路径 D:

f i n f o 函数:

imfinfo(D: \MATLAB 7\harbin. jpg ) ans = Filename: D: \MATLAB 7\harbin. jpg FileModDate:27-Apr-200520: 03: 08 FileSize:320204 Format: jpg FormatVersion: Width:1024 Height:768 BitDepth:24 ColorType: truecolor FormatSignature: NumberOfSamples:3 CodingMethod: Huffman CodingProcess: Sequential Comment:{}

将该图片读到 MATLAB 工作空间,存为矩阵 M: M = imread(D: \MATLAB 7\harbin. jpg );


将矩阵 M 另存为图片 c opy. bmp: imwrite( M, D: \MATLAB 7\copy. jpg ) ( , : imwrite M D \MATLAB 7\copy. bmp )

两张图片见图 2. 5。

图 2. 5 采用imwr i t e函数创建图片

【注意】

① 将图像数据写到图片文件中使用imwr i t e函数,而由f i r e 图像直接生成图像文件,用 gu 到函数 p r i n t和 s ave a s。

a)p r i n t函数用于f i e内图形输出,调用格式为: gur

h , format ,filename) print(

空 航

将句柄为 h 的f i r e界面输出到图像文件f i l e n ame,图像文件的格式由格式字符串f o rma t指 gu

定。一般输出为两种格式: BMP 和 JPEG,对应的格式字符串为:-dbmp 和 -d j peg。

pagesetupdlg

但是, r i n t函数输出的图像原本是用于打印输出的,因此输出图像大小与页面设置有关,在 p 输出前必须进行页面设置,否则输出的图像可能是不对的。输入以下命令调用页面设置对话框:

页面设置对话框如图 2. 6 所示。

图 2. 6 页面设置对话框


如果不输出界面上 的 u i c on t r o l对 象,而 只 输 出 坐 标 轴 内 的 图 像,可 以 选 中 图 2. 6中的

图 2. 7 只输出绘图区的设置

【 Axe sandF i e】标签,取消选择【 Pr i n tUICon t r o l s】,如图 2. 7 所示。 gur

h,-djpeg ,1. print( jpg ,-noui )

要取消 u i con t r o l对象的显示,也可以输入选项 -nou i(即 nou i c on t r o l的简写),例如:

【思考】 若只需要输出坐标轴区域,而不是整个f i r e图像,应该怎么办呢? gu

空 航

有一个办法:将要复制的 坐 标 轴 区 域 复 制 到 一 个 新 的 f i r e 内,然 后 输 出 新 f i r e的 图 gu gu

像。当然,这个新的f i e最好是隐藏的( v i s i b l e属 性 为 o f f)。 由 于 只 复 制 了 坐 标 轴,所 有 的 gur

u i c on t r o l对象没有复制过去,所以输出图像时不需要附加 -nou i选项。 假设当前要输出的坐标轴 Tag 值为 axe s 1,输出该坐标轴内的图像可以使用下面的程序:

hFigure = figure(visible , off ); copyobj( hAxes,hFigure); hFigure,-djpeg , mypic. print( jpg ); hFigure,-dbmp , mypic. bmp ); print( delete( hFigure);

% 创建隐藏的窗口 % 将坐标轴区域复制到隐藏窗口 % 输出到 mypic. jpg 图片 % 输出到 mypic. bmp 图片 % 删除隐藏的窗口

b)s ave a s函数也用于f i r e图像输出,调用格式为: gu saveas( h, filename. xxx )

将句柄为 h 的f i e的图像 输 出 到 文 件 f i l ename. xxx,文 件 格 式 由 MATLAB 根 据 后 缀 gur 名自动识别。 saveas( h, filename , format )

将句柄为 h 的f i e的图像输出到文件f i l ename,文件格式由 f o rma t指定。f o rma t可为 gur

以下值: bmp、 f i t i f、 eps、 a i、 emf、 m、 j pg、 g、 pbm、 pcx、 pgm、 png、 ppm。 ② 将图片写入坐标轴,可使用imshow 或image函数。imshow 和image都会产生一个图 像对象(就是后面要讲到的image对象),它们的区别如下: a)imshow 的两种用法:

imshow( filename):将指定的图片读入坐标轴内。


imshow( CData):将颜色矩阵 CData 映射到坐标轴内。

若当前窗口存在坐标轴, imshow 会将图像显示 在 当 前 坐 标 轴 内;若 当 前 窗 口 不 存 在 坐 标

轴, imshow 会产生一个隐藏的坐标轴,并将图像显示其中。 b)image的用法: colorData = imread( filename); image( colorData);

% 获取图片数据 % 将图像数据铺满坐标轴

c)imshow( f i l ename)等价于: colorData = imread( filename); ( ) ; imshow colorData

% 获取图像数据 % 将图像数据等比例缩放,显示到坐标轴

d)imshow 不会扩展图像数据,即不会拉伸图像使其铺满坐标轴,而是改变坐标轴宽高比 使其适应图像数据; image不会改变 坐 标 轴 的 大 小 尺 寸,而 是 扩 展 填 充 图 像 矩 阵,使 其 铺 满 坐

标轴区域。为避免图片失真,一般用imshow 比较多。

③ 如果要将图像数据写到坐标轴内,可使用image函数,调用格式为:

image( colorData)

将图像数据 c o l o rDa t a写到坐标轴内,作为坐标轴的背景图片。

例如,首先产生一个坐标轴( axe s函数将在后续章节详细介绍):

axes

将图像数据 c o l o rDa t a写入刚创建的坐标轴内:

空 航

colorData = imread(D: \MATLAB 7\harbin. jpg ); image( colorData)

京 北

axisoff

隐藏坐标轴:

得到的图像如图 2. 8 所示。

图 2. 8 读取图片到坐标轴


5.读写音频文件 读写音频 WAV 文件的函数见表 2. 10。

表 2. 10 读写音频 WAV 文件的常用函数

aud i odev i n f o aud i op l aye r aud i o r e c o r de r be ep

函数调用格式

函数说明

dev i n f o = aud i odev i n f o

获取音频设备(例如声卡)的相关信息

l aye r= aud i op l aye r( Y,Fs) p

麦克录音。Fs、 nb i t s和 nchans 分 别 为 所 录 制 音 频 的 采 样

be ep; be epon; be epo f f; s= be ep

驱动声卡发出“嘟”的一声

i o r e c o r de r( Fs,nb i t s,nchans) y = aud

wavp l ay

wavp l ay( y,Fs,mode)

wav r e ad

[ Y,Fs,nB i t s]= wav r e ad( f i l ename)

方式播放音乐采样数据 y。Fs为采样率

读 WAV 音乐文件,返回音乐采样数据 y。采样率 Fs和采

样位数 nB i t s

采集 PC 音频输入设备(例如麦克风)的数据

wavwr i t e( i l ename) y,Fs,f

s ound( Fs, b i t s) y,

s ounds c( s ounds c( Fs) y); y,

s ounds c( Fs, b i t s) y,

大 天

空 航

s ound( s ound( Fs) y); y,

由音频数据生成 WAV 音频文件

播放声音数据

归一化声音数据并播放

s ounds c

采用同步( mode为 s c ,缺 省 值)或 异 步( mo d e为 a s c) yn yn

wavwr i t e( i l ename) y,f

s ound

文件的采样数和声道数等信息

r e c o r d( n, Fs) y = wav

wavwr i t e( i l ename) y,Fs,N,f

率、每个采样值的位数和声道数

检查指定文件是 否 为 WAV 格 式 音 频 文 件,并 返 回 WAV

[ md]= wav f i n f o( f i l ename)

wavwr i t e

样率, nB i t s为每个采样值的位数

i o r e c o r de r y = aud

wav f i n f o

wav r e c o r d

创建一个音频播放器对象,用 于 控 制 音 频 的 播 放; Fs 为 采

l aye r= aud i op l aye r( Y,Fs,nB i t s) p

播放一个音频文件,主要用到 wav r e ad 和 aud i op l aye r这两个 函 数。wav r e ad 将 音 频 文 件

中的音频数据、采样率和采样位数等信息解读出来; aud i op l aye r根据音频数据、采样 率 和 采 样

位数来创建一个音频播放器对象,该对象可以对音乐进行播放、暂停播放、继续播放、停止播放 等操作。例如,若当前目录有一个 WAV 音 频 文 件 【莫 扎 特 - 土 耳 其 进 行 曲 . wav】,播 放 该 音 频文件播放器对象的方法如下:

属性

[ data,Fs,nBits]= wavread(莫扎特 - 土耳其进行曲 . wav ); % 解析 WAV 音频文件 data,Fs,nBits) % 创 建 音 频 播 放 器 对 象,并 查 看 其 player = audioplayer( BitsPerSample:16 CurrentSample:1 DeviceID:-1 NumberOfChannels:2 Running: off SampleRate:44100 StartFcn:[] StopFcn:[]


Tag: TimerFcn:[] TimerPeriod:0. 0500 TotalSamples:11215872 Type: audioplayer UserData:[] % 启动音频播放器,播放该音频文件 play( player);

在 MATLAB 命令行输入【 l aye r.】,然后 按 Tab 键,可 以 查 看 音 频 播 放 器 对 象 的 所 有 属 p 性和调用方法,如图 2. 9 所示。

音频播放器主要的属性和方法见表 2. 11。

图 2. 9 查看音频播放器的属性和方法

B i t sPe rSamp l e

音频数据播放的声道数,一般为单声道或双声道;只读

Samp l eRa t e

采样率,即每秒采样值的个数

Runn i ng

To t a l Samp l e s Tag

Type

Us e rDa t a

S t a r tFcn 回调属性

S t opFcn

Time rFcn

Time rPe r i od

t ge

方法

音频设备的 ID;值为 -1 表示采用默认的音频设备;只读

Numbe rOfChanne l s

属性

音频设备正在输出的采样点的索引号;只读

Dev i c e ID

每个采样值的位数。位数越多,量化误差越小;只读

Cur r en t Samp l e

空 航

属性或方法

表 2. 11 音频播放器的属性和方法

s e t

i sp l ay i ng e paus

表征播放器是否正在播放,值为“ on”或“ o f f”;只读 每个声道采样值的总个数;只读 播放器的标签 播放器所属的类,即 aud i op l aye r;只读 播放器额外存储的数据 播放器开始或继续播放时调用此函数或可执行字符串 播放器停止或暂停播放时调用此函数或可执行字符串 播放器在播放时定时执行的函数或可执行字符串 Time rFcn 执行的周期 获取播放器的属性列表或属性值 设置播放器的属性值 表征播放器是否正在播放,值为真或假 暂停播放


续表 2. 11 属性或方法

l ay p

播放音频数据

l ayb l o ck i ng p

播放音频数据,当播放完成时返回

r e sume 方法

继续播放

s t op

停止播放

c l e a r

从内存移除播放器对象

d i sp l ay

显示播放器对象的属性

i s equa l

比较多个播放器对象

c l o s e

释放播放器对象控制的音频设备

对于上面创建的音频播放器对象 p l aye r,可以执行以下操作: play( player) isplaying( player)

% 启动播放器对象,播放音乐 % 查看播放器是否正在播放音乐

ans = 1 get( player, Running )

% 查看播放器是否正在播放音乐

空 航

% 暂停播放 % 查看播放器是否正在播放音乐

ans = 0 resume( player) stop( player)

% 查看播放器是否正在播放音乐

clearplayerdata

% 查看播放器是否正在播放音乐

Running player. ans = off isplaying( player)

ans = on Running player. ans = on pause( player)

% 继续播放 % 停止播放 % 从内存移除播放器对象和音乐数据,释放内存

【注】 除了采用上面创建的播放器对象播放音 乐 数 据,还 可 以 创 建 一 个 模 拟 输 出 设 备 对 象来播放。 让声卡发出声音,实际是一 个 模 拟 信 号 输 出 到 硬 件 (声 卡)的 过 程。 MATLAB 有 一 个 模

拟输出设备函数库,位于数据获取工具箱( Da t aAc i s i t i onToo l box)中,它可以建立模拟输出 qu

对象和通道,并播放通道内 堆 放 的 数 据。 模 拟 输 出 设 备 对 象 由 ana l ogou t t函 数 创 建, Ana pu

l og Ou t t对象的使用方法如下(假定音乐文件名为 mus i c. wav): pu [ data,Fs,nBits]= wavread(music. wav ); ao = analogoutput(winsound ); nChannel = size( data,2); addchannel( ao,1 :nChannel); set( ao, SampleRate ,Fs)

% 获取音乐数据 % 建立声卡设备的对象 % 获取音乐数据的声道数 % 创建声音输出通道 % 设置采样率


set( ao, BitsPerSample ,nBits); ao,data); putdata( start( ao);

% 设置采样位数 % 往声卡堆音乐数据 % 输出音乐数据

此时还可以继续用 pu t da t a函数堆数,一旦堆的数据输出完, ao 自动停止。 当想让音乐停止时,只需要 s t op( ao)即可。 获取 Ana l og Ou t t对象的属性,可使用 ge t函数: pu ao) get( BufferingConfig = [ 40962912] BufferingMode = Auto Channel = [ 2x 1aochannel]

版 出 学 大

Tag = Timeout = 1 TimerFcn = []

空 航

SamplesOutputFcnCount = 1024 Sending = On StartFcn = [] StopFcn = []

MaxSamplesQueued = 1. 34152e+008 Name = winsound 0-AO RepeatOutput = 1 Running = On RuntimeErrorFcn = @daqcallback SampleRate = 44100 SamplesAvailable = 1. 19265e+007 SamplesOutput = 579697 SamplesOutputFcn = []

ClockSource = Internal EventLog = [ 1x 2struct] InitialTriggerTime = [ 201091311147. 3993]

TimerPeriod = 0. 1 TriggerFcn = [] TriggersExecuted = 1 TriggerType = Immediate Type = AnalogOutput UserData = [] WINSOUNDspecificproperties: BitsPerSample = 16 StandardSampleRates = Off

2. 1. 2 低级文件I/O 操作 1.打开文件和关闭文件 f open:打开文件便于随后的读写访问,或获取已打开文件的信息。调用格式见表 2. 12。


表 2. 12 f op en 函数调用格式 函数调用格式

f i d=f open( f i l ename)

打开f i l ename文件,便于随后的二进制读操作

f i d=f open( f i l ename, mode)

以特定模式 mode打开f i l ename文件

[ f i d, me s s age]= f open( f i l ename,mode) l l) f i ds= f open(a

按指定的模式 mode打开文 件 f i l ename。 操 作 成 功, f i d为 大 于 2的

非负整数, me s s age为空;操作失败, f i d=-1, me s s age为错误信息 返回一个由文 件 标 识 符 组 成 的 行 向 量。 它 获 取 所 有 用 f open 打 开 的文件的标识符,如果没有文件被打开,返回为空

[ f i l ename,mode]= f open( f i d)

返回标识符为f i d 的文件的文件名和存取模式

【注意】 f open 调用格式中, f i l ename包含文件后缀名。比如文件名为 a 1. da t与 a 1不是 同一个文件。

i l ename,并返回一个整数f i d( doub l e型),称为文件标识符 fid=fopen( filename):打开文件f ( ) ; , , , , …。如果当前目录下没有 f i l ei den t i f i e r 该格式返回的f i d 值可能为 -1 3 4 5 f i l ename 文 件,MATLAB 会搜索其安装目录。

文件标识符的所有可能取值见表 2. 13。

打开文件失败 标准输出(输出到屏幕),无需f open 打开

3, 4,…

标准错误,无需f open 打开 打开文件成功

% 打开文件,返回文件标识符

fig = fopen(a 1. dat ) fig = 3 fig = fopen(a 2. dat ) fig = 4

2

空 航

例如,打开文件 a 1. da t和 a 2. da t:

1

f i d值

-1

f i d值

表 2. 13 文件标识符的取值

% 打开文件,返回文件标识符

此时查看所有用f open 打开的文件的标识符:

fig = fopen(all ) fig = 3 4

以 mode模式打开 f i l ename,并 返 回 文 件 标 识 符 f i d。mode 由 fid = fopen( filename,mode): 。 两部分组成:读写模式 + 数据流模式。读写模式见表 2. 14 表 2. 14 文件读写模式

读写模式 r

打开文件,读操作;缺省值

w

打开或创建文件,写操作;覆盖原内容

a

展原内容

打开或创建 文 件,写 操 作;在 文 件 尾 部 扩

读写模式 r+

打开文件,读写操作

w+

打开或创建文件,读写操作;覆盖原内容

a+

扩展原内容

打开或创建 文 件,读 写 操 作;在 文 件 尾 部


【注意】 当读写模式为 r 或 r+ 模式时,如果打开的文件不存 在,MATLAB 并 不 会 创 建 该文件,此时打开文件失败,返回的文件标识符f i d=-1。例如: [ fid, message]= fopen(a 1 ,r ) fid = -1 message = Nosuchfileordirectory

表 2. 14 中后三种模式称为更新模式。当文 件 以 更 新 模 式 打 开 时,每 次 读 或 写 操 作 之 后,

文件位置指针并不返回到文件开头,需 要 用 f s e ek 或 f r ewi nd 函 数 来 重 新 定 位,这 点 稍 后 讲 解 文件位置指针时会详细介绍。

文件的数据流模式分为二进制模式和文本 模 式。数 据 流 分 为 两 种 类 型:文 本 流 和 二 进 制 流。文本流是解释性的,最长可达 255 个字符。如果以文本模式打开一个文件,那么在读字符

的时候,系统会把所有的\r \n 序列替换成\n ,在写入时把\n 替换成\r \n )。二进制流是 非解释性的,一次处理一个字符,且不转换字符。

通常,文本流用来读写标准的文本文件,或将 字 符 输 出 到 屏 幕 或 打 印 机,或 接 受 键 盘 的 输

入;而二进制流用来读写二进制文件(例如图形或字处 理 文 档),或 读 取 鼠 标 输 入,或 读 写 调 制

解调器等。如果用文本方式读二进制文件,会把“ 0D0A”自动替换成\n 来存在内存 中;写 入

的时候反向处理。而用二 进 制 方 式 读 取 的 话,就 不 会 有 这 个 替 换 过 程。 另 外,Un i c ode、UTF

和 UCS 格式的文件,必须用二进制方式打开和读写。

二进制模式为 b ,文本模式为 t ,默认采用二进制模式,如 r+b 、wb 、r t 、r+t 等。更

空 航

新模式的“+ ”可放到打开模式后面,如 r+b 也可写成 rb+ 。例如,打开模式为 wt,则存储为 文本文件,这样用记事本打开就可以正常显示了;若打开模式为 w,则存储为二进制文件,这样 用记事本打开会出现小黑方块,要正常显示的话,可以用写字板或 Ul t r aEd i t等工具打开。

s t a t us= f c l o s e( f i d)

表 2. 15 f c l o s e函数调用格式

打开模式

关闭一个或所有已打开的文件,见表 2. 15。 fclose : 说

关闭f i d 指定的已打开文件。 操 作 成 功, s t a t us =0;操 作 失 败, s t a t us = -1。 如 果 f i d等

于 0、 1 或 2,或f i d 不是一个已打开文件的标识符,均操作失败, s t a t us=-1

s t a t us= f c l o s e(a open 函数打开的文件。操作成功, s t a t us=0;操作失败, l l) 关闭所有用f s t a t us=-1

文件在进行读写操作后,应及时用f c l o s e关闭。

【注意】 f c l os e可关闭文件,使文件标识符无效,但并不能从工作空间清除文件标识符变 。如果要清除 量f i d f i d,可以使用: clearfid

2.读写二进制文件 二进制文件的读写,用到两个函数: f r e ad 和fwr i t e函数。f r e ad 函数读二进制文件的全部

或部分数据到一个矩阵中; fwr i t e函 数 用 指 定 的 格 式 将 矩 阵 的 元 素 转 换 精 度 后 写 到 指 定 文 件 里,并返回写的元素数。f r e ad 与fwr i t e函数调用格式见表 2. 16。


表 2. 16 f r e ad 与 fwr i t e函数调用格式 函

f r e ad

调用格式

A =f r e ad( f i d)

从标识符f i d 指定的文件中读二进制数据到矩阵 A

A =f r e ad( f i d,c oun t,p r e c i s i on)

从指定文件中读指定数据类型的数据到矩阵 A

[ A,c oun t]= f r e ad(…)

读数据到矩阵 A,返回成功读取的元素数到 c oun t

A =f r e ad( f i d,c oun t)

从指定文件中读 c oun t个二进制数据到矩阵 A

A =f r e ad( f i d,c oun t,p r e c i s i on,sk i p)

每读完指定数目元素,就跳过 sk i p 指定的元素数

[ c oun t,e r rms i t e( f i d, A,p r e c i s i on) g]= fwr fwr i t e

将矩阵 A 的元素按列顺序写到指定文件,元素值转换为

指定格式。c oun t中保存成功操作的元素数

将矩阵 A 的元素按列顺序写到指定文件,元素值转换为

[ c o un t,e r rms i t e( f i d, A, r e c i s i o n, s k i g]=fwr p p)

指定格式 p r e c i s i on。c oun t 中 保 存 成 功 操 作 的 元 素 数。

每跳过 sk i p 个元素写一个元素

s cha r

8 位带符号字符

i n t 8

8 位整数

格式定义符

32 位整数

i n t 64

64 位整数

64 位无符号整数

8 位无符号整数

f l oa t 32 f l oa t 64 doub l e

32 位无符号整数 32 位浮点数 64 位浮点数 64 位浮点数

u i n t 8

u i n t 64

学 天

16 位整数

i n t 32

16 位无符号整数

u i n t 32

空 航

i n t 16

8 位无符号字符。缺省值

u i n t 16

ucha r

格式定义符

表 2. 17 数据格式定义符

f r e ad 和fwr i t e函数的数据格式定义符 p r e c i s i on 的取值见表 2. 17。

还有一些格式定义符对应的数据位数与操作平台相关,见表 2. 18。

表 2. 18 数据位数与操作平台相关的格式定义符

格式定义符

格式定义符

cha r

8 位带符号字符

usho r t

16 位无符号整数

i n t

32 位整数

u l ong

32 位或 64 位无符号整数

sho r t l ong

16 位整数

u i n t

32 位或 64 位整数

f l oa t

32 位无符号整数 32 位浮点数

默认情况下, f r e ad 函数输出的是 doub l e数组。如果要输出其他类型的数字值,要定义输 出数据的格式。表 2. 19 列出了几个指定输出数据格式的例子。 表 2. 19 指定输出数据格式

输出数据格式 u i n t 8=>u i n t 8

*u i n t 8

格式说明 读进无符号整数,将它们保存在无符号 8 位整数数组中 u i n t 8=>u i n t 8 的简写形式


续表 2. 19 输出数据格式

格式说明

b i t 4=>i n t 8

读进带符号 4 位整数,输出带符号的 8 位整数

doub l e=>r e a l*4

读进双精度值,转换并保存在 32 位浮点数组中

有时需每隔几个数就读几个数,这时要用到格式: A = fread( fid,count,precision,skip)

sk i r e c i s i on 里 指 明,方 法 是 在 数 据 格 式 定 义 符 p 为跳过的数,连续读的数据 个 数 在 参 数 p ” 。如每隔 前加“ 个无符号 字 符 数 读 个 无 符 号 字 符 数,那 么 sk r e c i s i on 为 4* N* 3 4 i p p=3, ucha r。 例如,创建文件f i l e 3. da t,并获取文件标识符:

fid = fopen(file 3. dat , w ); % 以覆盖写模式创建或打开当前目录下的文件 file 3. dat

将数据[ 97: 106]写入该文件,并关闭文件:

count = fwrite( fid,97: 106) % 将一组数写入文件 file 3. dat count = 10 fclose( fid); % 关闭文件 file 3. dat

用t i l e 3. da t的数据内容,显示的是 ASCI I字符: ype函数查看文件f % 查看 file 3. dat 的内容

空 航

typefile 3. dat abcdefghij

打开f i l e 3. da t并读出其数据内容:

% 以读模式打开文件 file 3. dat % 读出文件 file 3. dat 的所有数据

fid = fopen(file 3. dat ); M = fread( fid) M= 97 98 99 100 101 102 103 104 105 106 fclose( fid);

转换输出的数据格式为字符: fid = fopen(file 3. dat ); N = fread( fid,uchar=>char ) N= a b

% 以读模式打开文件 file 3. dat % 将文件打开文件 file 3. dat 的数据转化为字符格式输出


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.