MATLAB/Simulink/C语言/C++/VC++ 编程援助 联系方式: QQ:993878382 Email:993878382@qq.com 编程博客:http://top99.blog.hexun.com/46036333_d.html 如果我QQ不在线,请将问题发到我的邮箱,或者在我的博客留言, 第一时间答复你! 还可以为公司和科研单位设计各类算法,欢迎前来咨询! 郑重声明:本资源来源于网络,仅限交流使用,请勿用于商业用途! 大 天 航 空 航 北 京 社 版 出 学 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 的数据转化为字符格式输出