IDL 全局变量

来源:互联网 发布:站长工具js格式化 编辑:程序博客网 时间:2024/06/10 06:06

在IDL语言中没有全局变量的概念,所有的变量都是局部变量,只在当前的程序中有效。但是在实际的编程中,大部分情况下全局的变量又是必须的,那如何处理
IDl中的所需的全局变量呢?本文探讨IDL使用中常用处理方法。

1 common----定义公共区
在程序中用common命令定义一个公共区,在公共区中保存程序中所需的公共变量。具体形式如下:
COMMON Block_Name, Variable1, Variable2, ..., Variablen 
其原理是,在内存中定义一个公共区来存储变量,需要这些变量的程序,只要引用这个公共区的名称(Block_Name)就可,公共区中可以存放多个变量,支持
IDl中所以的变量类型。
例子:
RO    vartest 
common vart , a,b,c    ;定义所需的公共区
a=2&b=3&c=4
print,(a*b*c)
vartest2            
End
Pro vartest2
common vart            ;引用公共区
print,(a+b)
End


注意:

common的方式来定义全局变量,是早期IDl程序使用方法,

用这种方法来处理全局变量,变量管理很混乱而且程序维护性差。

现在程序已经不使用这种方法,不推荐使用。

--------------------------------------------------------------------------------------------------------------

2 DEFSYSV ---定义系统变量
在程序中用defsysv来定义用户自己的系统变量。具体形式如下:
DEFSYSV, Name, Value
IDL的的系统都以!开头,IDl有很多已定义好现成的系统变量(详细细节请看帮助System Variables ),如:!DPI ,!MAP,!PI ,!CPU 。。。
它们都可以直接使用,如!DPI表示双精度圆周率的值。
用户自定义系统变量后,就可以直接使用,支持所有的变量类型

例子 :
Pro vartest2
c=!sysvar_a+!sysvar_b
print,c
End

PRO    vartest 
a=2
b=3
defsysv,'!sysvar_a',a
defsysv,'!sysvar_b',b
c =!sysvar_a * !sysvar_b
print,c
vartest2
End

注意:
1)DEFSYSV 程序一次只能定义一个系统变量;
2)所有的系统变量名称只能以!开头;
3)用DEFSYSV 的系统变量 的存在周期和编译器一样,除非关闭编译器或reset才能使系统变量无效;
4)一般在系统变量中保存一些使用频率很高的差数,如:程序系统路径,draw大小。
5)不存储数据量很大的数组,无法销毁,生命太长;
6)一般只在程序开始时定义,随意使用会使程序很混乱,很难维护;

-----------------------------------------------------------------------------------------------------------------------

3 用uvalue 来储存变量
uvalue是个好东西,里面可以存放各种数据类型,在IDL中有两个地方有uvalue,一个是所有界面组件中,有uvalue关键字可以存放变量,二是在所有图型类(IDlgr开头的类)中
有uvalue属性,可以存储变量,具体形式如下:
组件:
定义:
可以在初始化中定义    wtlb=widget_base(uvalue = var)
用widget_control对已有的组件进行设置    widget_control,wtlb,set_uvalue=var
引用:
    widget_control,wtlb,get_uvalue=var
类:
定义:
初始化中定义    omodel = obj_new('IDLgrmodel',uvalue=var)
已有类进行定义     omodel->setproperty,uvalue=var
引用:
omodel -> getproperty,uvalue=var
一般类中只存储与它功能相关的数据或差数。程序中所需的全局变量一般存储在tlb(顶级base)的uvalue中。因为tlb的值就是事件结构体中的event.top,可以直接获得。
根据tlb的值,用widget_control,wtlb,get_uvalue=var,就可以直接获得存储的全局变量var
例子:

pro testbar_cleanup,base
;清空内存
widget_control,base,get_uvalue=pstate ; 获取全局变量
for i=0,n_tags(*pstate)-1 do begin
   case size((*pstate).(i), /tname) of
    'POINTER':$
     ptr_free, (*pstate).(i)
    'OBJREF':$
     obj_destroy, (*pstate).(i)
    else:
endcase
end
ptr_free,pstate
end


pro testbar_event, event
print,event
help,event
widget_control, event.top, get_uvalue=pstate   ; 获取全局变量
uname =widget_info(event.id,/uname)
case uname of
   'quit':begin
    widget_control, event.top,/destroy
    end
   'open':begin
    print, 'widget user uname = ' + uname
    print, 'open'
    file = dialog_pickfile(/read, filter = '*.jpg',title='读取数据')
    if file eq '' then return
    print, file
    read_jpeg, file, image, /true
    image = congrid(image,3,600,450)
    (*pstate).oimage = obj_new('idlgrimage',image)
    (*pstate).omodel->add, (*pstate).oimage
    (*pstate).owin->draw, (*pstate).oview
   end
   else:
endcase
end
;-----------------------------------------------------------------------
pro testbar
;组件系统
base = widget_base(title = 'qqz_练习',$
       mbar=bar_base,$
       xsize=600,$
       ysize=450,$
       /kill_notify)
   file_menu = widget_button(bar_base, value='file', /menu)
    file_bttn1 = widget_button(file_menu, value='open', uname='open')
    file_bttn2 = widget_button(file_menu, value='file item 2', uname='file 2')
    file_bttn3 = widget_button(file_menu, value='file item 3', uname='file 3')
    file_bttn4 = widget_button(file_menu, value='quit', uname='quit')

   opt_menu = widget_button(bar_base, value='options', /menu)
    opt_bttn1 = widget_button(opt_menu,value='options item 1', uname='file1')
    opt_bttn2 = widget_button(opt_menu,value='options item 2', uname='file2')
    opt_bttn3 = widget_button(opt_menu,value='options item 3', uname='file3')
    opt_pr = widget_button(opt_menu,value='options pull-right', /menu)
     pr_bttn1 = widget_button(opt_pr, value='options pull   item1', uname='pr 1')
     pr_bttn2 = widget_button(opt_pr, value='options pull   item2', uname='pr 2')
    opt_bttn5 = widget_button(opt_menu,value='options item 5', uname='file5')
   help_menu = widget_button(bar_base,value='help', /menu)
    help_buttn1 = widget_button(help_menu,value='help item 1', uname= 'help 1')
    help_buttn2 = widget_button(help_menu,value='help item 2', uname= 'help 2')
   wdraw = widget_draw(base,graphics_level=2,$
         retain=2,$
         xsize=600,$
         ysize=450)
widget_control, base, /realize
;
widget_control, wdraw, get_value=owin
;对象系统
oview = obj_new('IDlgrview', viewplane_rect=[0,0,600,450],dimension=[600,450])

omodel = obj_new('IDlgrmodel', name='topmodel')

oview->add, omodel
;全局变量
state = {owin:owin    ,$
     oview:oview   ,$
     omodel:omodel   ,$
     oimage:obj_new() ,$
     wdraw:wdraw    $
     }
;把全局变量结构体的指针付给顶base
widget_control, base,set_uvalue=ptr_new(state, /no_copy)
xmanager, 'testbar', base,cleanup='testbar_cleanup',   /no_block
end

注意:
1)用tlb的uvalue来存储全局变量,是IDL全局变量处理最主要的手段。
2)uvalue中也只能存放一个变量,存放多个全局变量,一般采用在uvalue中存放一个结构体的指针。
例如:
state ={a:a,b:b,c:c,d:d }
widget_control,wtlb,set_uvalue=ptr_new(state,/no_copy)
3)面向对象的程序设计,大部分的变量都可以存在各功能类或子base的uvalue里,真正需要存在tlb的全局变量不多。

---------------------------------------------------------------------------------------------------------------------------
4 用sav来存储系统参数
一个完善的软件,涉及到的系统各种差数很多,参数模块也很多,留给用户交换配置的参数也很多,就像IDL编译器分file-prefercences。
原理是:对于与主模块非常独立的模块之间参数传递,定义一个结构体,存储需要传递的参数。然后在把结构体以sav文件的形式存在指定的路径下。
需要这些参数是把这个sav文件,restore了就可以了。著名的IDL开源软件dave就采用的这种手段
例子:

Pro vartest2
;从指定目录还原sav文件 
restore,!sysfile
(*sys).a=3
(*sys).b=3
(*sys).c=obj_new('IDlgrmodel')
;改变后数据在存储
save,filename=!sysfile,sys
print,'*sys'
help,*sys,/str
obj_destroy,(*sys).c
ptr_free,sys
End
PRO   vartest 
;定义系统结构体
     sys_define={         $
     a:1    ,$  
     b:2    ,$
     c:obj_new()   $   
         }
;
print,'sys_define'        
help,sys_define,/str
;
defaults_file = 'C:\.defs.sav'
;自定义系统参数,保存路径名
defsysv, '!sysfile', defaults_file
sys=ptr_new(sys_define)
;把参数保存在自定目录下
save,filename=!sysfile,sys

ptr_free,sys
vartest2
End

注意:适用多模块,大型系统,一般程序不推荐使用。

---------------------------------------------------------------------------------------------------------------------------
5 完全面向文件变量存储
这种方法比较落后,不推荐使用,仅让大家有所了解。一些古老或对IDL不太了解的研究者,会用到这种方法
这种方法没有所谓的全局变量,所有生成的变量或数据,都把它们写成txt文件文件或dat的数据。别的程序需要调用的时候,在读这些txt或dat。这种程序
bug率非常高。程序很难控制。

后记:
一般程序设计会使用一种或几种相结合。常用的方法用defsysv和uvalue。

大型软件会用到sav。

全局变量中是在内存中常驻的,所以尽量减少变量冗余,和
大型数组。

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 cf天赋点多了怎么办 cf天赋点点错了怎么办 警用记录仪丢了怎么办 被伪基站覆盖了怎么办 加热包的水喝了怎么办 剩米饭放硬了怎么办 肉罐头拉环断了怎么办 5大战区拥兵自重怎么办 买的期房停工了怎么办 怀孕后长了副乳怎么办 耳朵冻的红肿了怎么办 吃螃蟹吃柿子了怎么办 吃了螃蟹和柿子怎么办 螃蟹与柿子同吃怎么办 手被鞭炮炸伤了怎么办 索尼l36h变砖了怎么办 oppor9s手机忘记解锁图案怎么办 索尼z5刷死机了怎么办 魅蓝note3被锁定怎么办 oppo图案锁忘了怎么办 手机图案锁忘w怎么办输 手机图案解锁密码忘了怎么办 忘记htc手机锁屏怎么办 我手机密码忘了怎么办 小米5x忘记密码怎么办 oppo忘记手机解锁图案怎么办 手机解锁图案忘了怎么办 苹果id给锁了怎么办 苹果手机忘了ld怎么办 4s忘记开机密码怎么办 取卵22个肚子胀怎么办 夜神模拟器很卡怎么办 夜神模拟器卡顿怎么办 入职体检有痔疮怎么办 泰迪鼻子干怎么办恢复 泰迪幼犬鼻子干怎么办 狗狗呕吐没精神怎么办 狗狗鼻子干拉稀怎么办 狗狗鼻子干呕吐怎么办 肛门直肠环断了怎么办 原房主欠取暖费怎么办