页数:55页文件大小:666.6 KB来源: MATLAB基础与应用ppt课件
本课件讲解MATLAB中以M文件和外部数据文件为对象的操作方法:介绍M脚本文件与M函数文件的建立、编辑与调用,说明主函数、子函数与函数句柄的用法,区分全局与局部变量的作用域,并给出文本文件与二进制文件的打开、读写和关闭流程。
本页为《MATLAB基础与应用》第6章 MATLAB文件操作的章节封面。
本章知识结构
6.1 M文件的建立与编辑
M文件有两种类型:M脚本文件(M-Script)与M函数文件(M-Function)。
脚本文件与函数文件的区别在于脚本文件没有函数定义行,且一般没有注释信息,当然也可以添加注释信息,即以%开头的内容。在使用方法、变量生存周期上也存在差异,见表6-1。
| 比较项目 | M脚本文件 | M函数文件 |
|---|---|---|
| 输入/输出参数 | 不接收输入参数,也不返回输出参数 | 接收输入参数,也可以返回参数 |
| 变量情况 | 处理工作空间中的变量 | 默认内部变量为局部变量,工作区间不能访问 |
| 适用情况 | 常用于需多次执行的一系列命令 | 常用于需多次执行且需要输入/输出参数的命令集合,常作为MATLAB应用程序的扩展编程使用 |
M脚本文件:M脚本文件包含一组由MATLAB语言所支持的语句。执行方式为:用户在MATLAB的提示符下输入该M文件的文件名,MATLAB就会自动执行该M文件的各条语句,并将结果直接返回到MATLAB的工作空间。
M文件的编辑和调试是在MATLAB的M文件编辑器(M-file Editor)中进行的,若需要对M文件进行调试,还需要MATLAB运行环境的支持。该编辑器既为基本文本文件的编辑提供了图形用户界面,又可以用于其他文本文件的编辑,同时还可以进行M文件的调试工作。
图6.1所示为打开后的编辑器界面。
M文件有两种运行方式:
M文件保存的路径一定要在搜索路径上,否则M文件不能运行;也可以选择运行程序的快捷图标来进行运行程序,或者按快捷键 F5。
在M文件中,当表达式后面接分号时,表达式的计算结果虽不显示但中间结果仍保存在内存中。若程序为命令文件,则程序执行完以后中间变量仍予以保留;若程序为函数文件,则程序执行完以后中间变量被全部删除。
例6-1:用M命令文件画出衰减振荡曲线及它的包络线,t的取值范围是[0,4π]。
建立M命令文件:打开MATLAB命令窗口,单击 File 菜单 New 子菜单中 M-file 命令(如图6.1所示)打开编辑窗,在编辑窗口逐行写下列语句:
t=0:pi/50:4*pi; y0=exp(-t/3); y=exp(-t/3).*sin(3*t); plot(t,y,'-r',t,y0,':b',t,-y0,':b')然后,保存M文件,并且保存在搜索路径上,文件名为 m_example.m;运行M文件。在命令窗口写 m_example,并按回车键 Enter,或者在编辑窗口打开菜单 Tools,再选择 Run 命令。运行结果如图6.2所示。
将需要运行的命令编辑到一个命令文件中,然后在MATLAB命令窗口输入该命令文件的名字,就会顺序执行命令文件中的命令。
例6-2:建立一个命令文件 achangb.m 将变量a与b的值进行互换。在M文件编辑窗口中编写以下命令,保存命名为 achangb.m:
a=1:7; b=[1,2,3;4,5,6;7,8,9]; c=a; a=b; b=c; a b在MATLAB的命令窗口中输入 achangb,将会执行该命令文件。
a = 1 2 3 4 5 6 7 8 9 b = 1 2 3 4 5 6 76.2 函数文件:函数文件是另一种形式的M文件,每一个函数文件都定义一个函数,MATLAB提供的标准函数大部分都是由函数文件定义的。MATLAB中M函数文件编写方式如下。
在编写M文件时,应当注重M文件的正确性、规范性和通用性。编写M文件需要注意的问题如下。
6.2.1 函数文件格式:函数文件由 function 语句引导,M函数文件的一般形式为:
function <输出形参表>=<函数名>(<输入形参表>) 注释说明部分 函数体其中函数名的命名规则与变量名相同。输入形参为函数的输入参数,输出形参为函数的输出参数。M函数文件可以有多个输入参数以及输出参数,当有多个输入、输出变量时用 [ ] 括起来。
例6-3:编写函数文件求小于任意自然数n的Fibonacci数列各项。
function f=ffib(n) % 求Fibonacci数列的函数文件 f=ffib(n) f=[1,1]; i=1; while f(i)+f(i+1)<n f(i+2)=f(i)+f(i+1); i=i+1; end将以上函数文件以文件名 ffib.m 存盘,然后在MATLAB命令窗口输入以下命令,可求小于200的Fibonacci数。
>> ffib(200) ans = 1 1 2 3 5 8 13 21 34 55 89 144例6-4:设可逆方阵为A,编写同时求矩阵的平方、逆矩阵以及转置的M函数文件。
function [a1,a2,inva,traa]=wym(x) % M函数文件comp4.m同时求矩阵x的4个值 % da为矩阵x的行列式 % a2为矩阵x的平方 % inva为矩阵x的逆矩阵 % traa为矩阵x的转置 da=det(x) a2=x^2 inva=inv(x) traa=x'保存M函数文件,并且保存在搜索路径上,文件名为 wym.m,然后在命令窗口执行下列语句:
>> A=[1,2;3,4]; % 输入矩阵A >> wym(A) % 调用wym.m函数计算矩阵A的平方、逆矩阵以及转置 a1 = -2 a2 = 7 10 15 22 inva = -2.0000 1.0000 1.5000 -0.5000 traa = 1 3 2 46.2.2 函数调用:函数调用的一般格式是 [输出实参表]=函数名(输入实参表)。
例6-5:利用函数文件,实现直角坐标(x,y)与极坐标(ρ,θ)之间的转换。函数文件 tran.m:
function [gama,theta]=tran(x,y) gama=sqrt(x*x+y*y); theta=atan(y/x);调用 tran.m 的命令文件 main1.m:
x=input('Please input x=:'); y=input('Please input y=:'); [gam,the]=tran(x,y); gam the>> main1 Please input x=:5 Please input y=:6 gam = 7.8102 the = 0.8761例6-6:利用函数的递归调用,求 n!。
function f=factor(n) if n<=1 f=1; else f=factor(n-1)*n; end return; % 返回编写命令文件 main2.m,并在命令文件 main2.m 中调用函数文件 factor.m:
for i=1:10 fac(i)=factor(i); end fac>> main2 fac = 1 2 6 24 120 720 5040 40320 362880 3628800程序运行结果是如上。
6.2.3 函数所传递参数的可调用性:MATLAB在函数调用上有一个与众不同之处——函数所传递参数数目具有可调性,凭借这一点一个函数可完成多种功能。
在调用函数时,MATLAB用两个永久变量 nargin 和 nargout 分别记录调用该函数时的输入实参和输出实参的个数。只要在函数文件中包含这两个变量,就可以准确地知道该函数文件被调用时的输入输出参数个数,从而决定函数如何进行处理。
例6-7:nargin用法示例。编写函数文件 charray.m:
function fout=charray(a,b,c) if nargin==1 fout=a; elseif nargin==2 fout=a+b; elseif nargin==3 fout=(a.*b.*c)/2; end编写命令文件 examp.m:
x=[1:3]; y=[1,2,3]; z=[3,3,3]; charray (x) charray (x,y) charray (x,y,z)执行 examp.m 后的输出是:
>> examp ans = 1 2 3 ans = 2 4 6 ans = 1.5000 6.0000 13.5000如果编写命令文件 examp2.m:
x=[1:3]; y=[1;2;3]; charray (x,y') charray (x,y,3执行 examp2.m 后的输出是:
>> examp2 ans = 2 4 6 ans = 216.2.4 函数句柄
函数句柄优点是方便实现函数间相互调用,兼容函数加载的所有方式,拓宽子函数包括局部函数的使用范围,提高函数调用的可靠性,减少程序设计中的冗余,提高重复执行的效率。
引入函数句柄的理由是:使 feval 及借助于它的泛函指令工作更可靠;使「函数调用」像「变量调用」一样灵活方便;提高函数调用速度,特别在反复调用情况下更显效率;提高软件重用性,扩大子函数和私用函数的可调用范围;可迅速获得同名重载函数的位置、类型信息。
创建函数句柄使用 @ 或者 str2func 命令创建:
h_fun=@fun; h_fun=str2func('fun');定义函数句柄只需要在提示符 @ 后面添加相应函数的函数名,函数句柄的内容通过 functions 函数显示,调用可通过 feval 函数进行,调用的格式如下:feval(函数句柄,参数列表)。
函数句柄与函数名字符串转换可以通过以下命令实现:
str2func('函数名字符串') 函数名字符串转换函数句柄func2str(函数句柄名) 函数句柄转换函数名字符串例6-6:运用 sin 函数建立句柄。
h_sin=@sin; h_sin=str2func('sin');执行 sin 函数 feval:
feval('sin',pi/2) ans = 1使用函数句柄可以与变量一样方便。例如,在这个目录运行后,创建了本目录的一个函数句柄,当转到其他的目录下的时候,创建的函数句柄还是可以直接调用的,而不需要把那个函数文件复制过来。因为创建的函数句柄中已经包含了路径,例如创建了一个 fun:
h_fun=str2func('rei');可以用 functions 来查看这个 function,结果已经包括了路径。
>> functions(h_fun) ans = function: 'rei' type: 'simple' file: '' >> f=@rand f = @rand >> functions(f) ans = function: 'rand' type: 'simple' file: '' >> feval(f,3) ans = 0.2028 0.2722 0.7468 0.1987 0.1988 0.4451 0.6038 0.0153 0.9318MATLAB中函数句柄的使用使得函数也可以成为输入变量,并且能很方便地调用,提高了函数的可用性和独立性。例如,新建M文件 f1.m:
function y=f1(X) x1=X(1); x2=X(2); y=x1^2+x1*x2;新建M文件 ftest.m:
function Y=ftest(f,X) syms x1 x2; F=f([x1,x2]); v=[x1,x2]; grad=jacobian(F,v); Y=subs(grad,v,X);在MATLAB命令窗口输入 Y=ftest(@f1,[2,1]),得到结果:
>> Y=ftest(@f1,[2,1]) Y = 5 2此处 @f1 即为函数 f1 的句柄,可以用 class(@f1) 判断变量的类型,得到 ans = function_handle 即函数句柄。函数 ftest 是求一个二维函数在指定点的梯度值,可以替换目标函数为 f2 或其他函数同样可以求得梯度,这样函数 ftest 就可以适用于任何二维函数而不必做改动。
6.3 全局变量和局部变量
例6-8:全局变量应用示例(1)。先建立函数文件 example_add.m,该函数将输入的参数加权相加。
function f=example_add(x,y) % add two variable global ALPHA BETA f=ALPHA*x+BETA*y;在命令窗口中输入:
>> global ALPHA BETA >> ALPHA=1; BETA=2; >> s=example_add(3,2) s = 7例6-9:全局变量应用示例(2)。在m文件中定义3个函数,函数中定义了全局变量X,主函数定义为:
function global_plot(s) global X % 定义X为全局变量 X=0:0.1:2*pi; plot_sin(s) plot_cos(s)子函数1定义为:
function plot_sin(a) global X % 使用全局变量X时也要用global定义 y=a*sin(X); figure plot(X,y)子函数2定义为:
function plot_cos(a) global X % 使用全局变量X时也要用global定义 X=-pi:0.1:pi; % 全局变量被修改 y=a*cos(X); figure plot(X,y)当在命令窗口输入:
>> global_plot(1)运行结果如图6.3所示:
6.4 文件的操作 6.4.1 fopen打开文件:fopen函数格式为 Fid= fopen(filename,permission),其中 filename 为文件名,permission 为文件格式,可以是下列格式之一。
6.4.2 fclose关闭文件:文件在进行完读、写等操作后,应及时关闭,以保证文件的安全可靠。关闭文件命令格式为 Sta=fclose(Fid);关闭 Fid 所表示的文件,Sta 表示关闭文件操作的返回代码,若关闭成功返回0,否则返回–1。
例6-10:关于数据输出。
>> a=[10 20 30;40 50 60]'; fid=fopen('out.txt','w'); fprintf(fid,'%d %d %d\n',a) fclose(fid);产生 out.txt 文件,文件内容为:
10 20 30 40 50 606.4.3 二进制数据文件读写:fread 读二进制数据文件,格式为 [A,COUNT]=fread(Fid,size,precision)。其中A为数据矩阵,COUNT返回所读取的数据元素个数。size 为可选项,若不选用则读取整个文件内容,若选用它的值可以是下列值。
precision 用于控制所读数据的精度格式,默认格式为 uchar,即无符号字符格式。例如:
Fid=fopen('std.dat','r'); % 以读数据方式打开数据文件std.dat A=fread(Fid,100,'long'); % 按长整型数据格式读取文件的前100个数据放入向量A Sta=fclose(Fid); % 关闭文件fwrite 函数以二进制格式向数据文件写数据,其格式为 COUNT=fwrite(Fid, A, precision)。例如:
Fid=fopen('magic5.bin', 'wb'); fwrite(Fid, magic,'int32');上述语句将矩阵 magic 中的数据写入文件 magic5.bin 中,数据格式为32位整型二进制格式。
6.4.4 文本文件读写:fscanf 读ASCII文本文件,其格式为 [A,COUNT]=fscanf(Fid, format, size)。其中A为数据矩阵,用以存放读取的数据,COUNT返回所读取的数据元素个数。format 用以控制读取的数据格式,由 % 加上格式符组成,格式符为:d、i、o、u、x、e、f、g、s、c 与 [...]。
s=fscanf(fid, '%s') % 读取一个字符串 a=fscanf(fid, '%5d') % 读取5位数的整数 b=fscanf(fid, '%6.2d') % 读取浮点数fprintf 写ASCII数据文件,其格式为 COUNT=fprintf(Fid, format, A,…)。其中A为要写入文件的数据矩阵,先按 format 格式化数据矩阵A,后写入到 Fid 所指定的文件。
例6-11:写文件命令示例。
x = 0: 0.1: 1; y = [x; exp(x)]; Fid = fopen('exp.txt', 'w'); fprintf(Fid,'%6.2f %12.8f\n',y); fclose(Fid);将相关数据写到文件中。如图6.4所示为 exp.txt 文件。
例6-12:MATLAB中如何读取文本文件。假定名为 test.txt 的文件中以下内容为文件内容,这样的文件怎么读入数据呢?
你好 欢迎来到 数据分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15在文件菜单中选择 File/Import Data,按照提示进行操作至结束。
>> whos Name Size Bytes Class data 3x5 120 double array textdata 2x1 142 cell array Grand total is 28 elements using 262 bytes >> data data = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >> textdata textdata = '你好欢迎来到' '数据分析在 command 窗口中输入以上命令查看。
文件内容形式二(假定文件名为 www.txt):
你好 1 2 3 4 5 欢迎来到 6 7 8 9 10 数据分析 11 12 13 14 15 Txt file operation说明:这种内容格式的文件用上面的方法是不行的。以下是文件提取数据的一种方法。
fidin=fopen('www.txt'); % 打开www.txt文件 fidout=fopen('mkMATLAB.txt','w'); % 创建MKMATLAB.txt文件 while ~feof(fidin) % 判断是否为文件末尾 tline=fgetl(fidin); % 从文件读行 if double(tline(1))>=48 && double(tline(1))<=57 % 判断首字符是否是数值 fprintf(fidout,'%s\n\n',tline); % 如果是数字行,写入txt文件中 continue % 如果是非数字继续下一次循环 end end fclose(fidout); MK=importdata('MKMATLAB.txt'); % 将生成的MKMATLAB.txt文件导入工作空间>> MK MK = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 156.4.5 数据文件定位
status=fseek(Fid, offset, origin)。Fid为文件句柄;offset表示位置指针相对移动的字节数;origin表示位置指针移动的参照位置。若定位成功 status 返回值为0,否则返回值为–1。position=ftell(Fid)。返回值为从文件开始到指针当前位置的字节数,若返回值为–1表示获取文件当前位置失败。例6-13:下述程序段说明了函数 fseek 和 ftell 的使用。
>> a=[1:5]; Fid=fopen('fdat.bin', 'w'); % 以写方式打开文件fdat.bin fwrite(Fid,a,'int16'); % 将a中的5个数据元素分别以双字节整型格式写入 status=fclose(Fid); % 关闭文件fdat.bin Fid=fopen('fdat.bin','r'); status=fseek(Fid, 6, 'bof'); % 文件数据指针从开始位置向尾部移动6个字节 four=fread(Fid,1,'int16'); % 读取当前数据,并移动指针到下一个数据 position=ftell(Fid); eight=fread(Fid, 1, 'int16'); % 读取第8个数据 status=fclose(Fid);本章小结
阅读材料:M文件编写技巧 1.MATLAB使用技巧技术
2.cell模式:在一个长长的脚本m文件中,可能需要对其中的一段反复修改、查看执行效果,这时 cell 模式就非常有用了。cell模式相当于将其中的代码复制到命令窗口中运行。
下载地址:{{downurl}}
{{{a}}}
{{#b}}{{{b}}}
{{/b}} {{/title}} {{#nolog}}登陆注册
{{/nolog}} {{#djsx}}点我刷新
{{/djsx}} {{#gocz}} {{/gocz}} {{#ffqr}} {{/ffqr}}