声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 1204|回复: 1

[综合讨论] 昨晚看到的好东西,拿来分享

[复制链接]
发表于 2006-10-19 00:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
[matlab]函数结构与参数传递(by simwe cwit)
  

作者: 猎鹰  发布日期: 2006-1-06    查看数: 166   出自: http://www.bylm.net

  
某个函数的子函数,可能具有复用性,而我又不想改变原来的函数,怎样才能调用这个子函数呢?那就是给每一个函数加一个壳。例如这个函数结构:

function varargout = test_function( varargin )
% ....................

if nargin == 0
% 创建界面。
% 即使不创建界面,也可以采用这种函数结构。
figurehandle = test_generatefigurecontent;

% 初始化函数,可以用于创建初始化数据。
test_initfiguecontent(figurehandle);

if nargout > 0
varargout{1} = figurehandle ;
end

elseif ischar( varargin{1} )

try
if nargout > 0
[varargout{1:nargout}] = feval( varargin{:} ) ;
else
feval( varargin{:} ) ;
end
catch
disp( lasterr ) ;
end
end

% -------------------------------------------------------------------------
function figurehandle = test_generatefigurecontent;

.....................................
handles = guihandles( figurehandle );
guidata( figurehandle, handles ) ;

% --------------------------------------------------
function test_initfiguecontent( h )

handles = guidata( h ) ;

DefaultData = test_GetDefaultData ;

........................................

% --------------------------------------------------
function DefaultData = test_GetDefaultData ;

DefaultData.ParaName = {'height'; 'width';} ;
DefaultData.ParaKanaName = {'高度'; '宽度';} ;
DefaultData.height = 20 ;
DefaultData.width= 5 ;

% --------------------------------------------------
function test_Uicontrol_Callback( h ) ;

handles = guidata( h ) ;
........................................

% return ;

-------------------------------------------------------------------------
如果你要得到test_function里面的默认数据,就可以在其他函数中使用如下调用方式就能够得到:
DefaultData = test_function( 'test_GetDefaultData' ) ;
程序会通过这个转换器进入子函数:
elseif ischar( varargin{1} )
try
if nargout > 0
[varargout{1:nargout}] = feval( varargin{:} ) ;
else
feval( varargin{:} ) ;
end
catch
disp( lasterr ) ;
end
end
===================================================================
cwit:
这种结构还便于传递参数,同时varargin,varargout的使用,便于定制不同的输入方式。曾经写了一个函数,可以支持3到8个输入参数,实现详细的输入参数定制。

关于参数传递
1. 尽量在内存中提取:方法有三种:① 采用function的varargin和varargout传送,② 存在handle的ApplicationData中,③保存在handles里面。当然还有其他方法。
2.存在硬盘上,采用save和load。
3.用全局变量,最次的办法,有时却是最好的办法。

关于nargin,nargout,varargin,varargout
nargin:输入参数的个数,主要用于两个方面:①判断输入参数的个数,如果输入参数个数不对,可以警告或其他处理;②根据参数个数的不同可以做不同的处理。如:
if nargin == 0
error;
elseif nargin == 1
…………
elseif nargin == 2
…………
else
warndlg( '……‘, ’‘,‘modal')
return ;
end

nargout:输出参数的个数,用法同上。
varargin:输入参数的总和,保存为cell结构。提取方式如下:
A = varargin{1} ;
B = varargin{2:end} ;
varargout 输出参数。见到的最常见的用法是:
if nargout > 0
varargout{1} =figurehandle ;
end
=======================================================================
cwit:
关于handles:
实际上这个handles是MATLAB中GUI编程中最常用的一个句柄管理变量。
handles的生成:handles = guihandles( figurehandle );将figure中所有对象中“Tag”属性有值的句柄的handle采集在一起。handles是结构名,每个“Tag”域名里保持此对象的句柄。
handles的保存:guidata( figurehandle, handles );handles将保存在figure对象的“ApplicationData”的一个域名里。
handles的使用:handles = guidata( h );其中为figure中任意一个对象的句柄。
handles.SpeechSourceGui可能是一个figure的句柄,“userdata”是一个对象的属性,可以在其中存取任何数据。但是我不怎么用它,一则它只能存一个变量;二则它无法存入变量的名字,很难区分。
====================================================================
cwit:
关于feval
feval,首先我们可以把它理解为一个函数转换器。执行到feval时,系统将首先寻找内部函数,如果没有找到,再尝试找外部函数。
feval也是一个函数封装器,在执行时它能够调用某个函数;但是在编译时,又可以不将这个函数编译到当前模块中。
feval还有一个很强大的功能,如果结合了这个函数结构,就可以在函数外部调用一个函数的内部函数或子函数
===================================================================
cwit:
关于setappdata,getappdata
setappdata,将数据保存在对象的“ApplicationData”属性中。
getappdata,从对象的“ApplicationData”属性中提取数据,如果没有定义,就为空。
setappdata和getappdata操作的对象,最好为figure_handle,便于管理和扩展。
Matlab的高级编程和对象控制,将大量使用这两个函数
====================================================================
nostalgica:
受教了。
不过要调用一个函数的子函数,可以设法得到子函数的句柄。
不过程序执行时是看不到其他函数子函数的。这就要在主程序运行之前把要用的子函数“注册”一下,就像这样

function func1
k=@aa;
save subfunction k

%own codes
function aa
a=1

这样就把aa的句柄存了下了,当然也能存到GUI里。
然后load subfunction;feval(k)

不过感觉这样用似乎不大方便,因为其他函数要在此函数调用之前就想调用它的子函数便不可行了。是否可以设置一个programmestarted的标识,在所有函数调用之前把它们都执行一下,注册其子函数
if programmestarted==0
k=@aa;
save subfunction k
return
end
不过这样又增加了不少无谓的代码。
=======================================================================
cwit:
关于function_handle
function_handle在matlab环境下还是可以用的,但是不能支持编译,也就是说无法脱离matlab环境安全运行。在构建程序时,一定要考虑到扩展性,有些在某些条件下属于技术缺陷的方法,尽量不要用
====================================================================
snow_man_0:
"就是某个函数的子函数,可能具有复用性,而我又不想改变原来的函数,怎样才能调用这个子函数呢?"
我的办法是将子函数升级,函数多加了一个参数action
function fun(varargin,action)

switch action
case 'fun1'

case 'fun2'

end

另外,handles = guihandles( figurehandle );
这个函数要谨用,
1、由于其中用的是for循环,界面上的对象多了后会影响运行速度;
2、由于使用结构体,不支持中文'tag'。

建议还是使用内置函数findobj
=====================================================================
nostalgica:
fucntionhandel,feval,eval在R13中不支持编译。在R14中呢是否可以了呢。?
===================================================================
cwit:
R14的Compiler 4,应该不叫编译吧。所以fcuntion_handle,eval这些问题不存在。
所以R14的路应该是另外一条道路,前面没有声明,我的理解主要是基于Matlab 6.1,这个版本的compiler比较好用。
关于try...catch...end
昨晚给他们做培训,for和if结构讲了一个小时,下次有时间整理一下。
在函数结构里面用到了try...catch...end结构,这个东西虽然保险,但还是尽量少用。因为它屏蔽了很多警告信息,无法很好的调试程序。
=================================================================
bzzz:
记得以前读
matlab混合编程那本书上当时谈到try...catch...end结构
说最正式的应该是每写一个功能(函数?),就要用try...catch把它包一次
不过这个很麻烦因而很多时候不需要(?)
忘了这段话是在讲matlab基础部分还是混编中提到,似乎是后者,介绍怎么用C
math library的时候
当时看过也没太注意-____-|||
回复
分享到:

使用道具 举报

 楼主| 发表于 2006-10-19 00:02 | 显示全部楼层
感觉看得不是很懂,欢迎讨论!
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-11-12 16:17 , Processed in 0.081076 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表