zoukankan      html  css  js  c++  java
  • [转]IDL中全局变量的处理

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

    1 common—-定义公共区
    在程序中用common命令定义一个公共区,在公共区中保存程序中所需的公共变量。具体形式如下:
    COMMON Block_Name, Variable1, Variable2, …, Variablen
    其原理是,在内存中定义一个公共区来存储变量,需要这些变量的程序,只要引用这个公共区的名称(Block_Name)就可,公共区中可以存放多个变量,支持IDl中所以的变量类型。
    例子:
    PRO 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
    类:
    定义:
    初始化中定义 model = 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。

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

  • 相关阅读:
    17. Letter Combinations of a Phone Number
    16. 3Sum Closest
    15. 3Sum
    14. Longest Common Prefix
    13. Roman to Integer
    12. Integer to Roman
    11. Container With Most Water
    10. Regular Expression Matching
    9. Palindrome Number
    8. String to Integer (atoi)
  • 原文地址:https://www.cnblogs.com/rocklele/p/1510523.html
Copyright © 2011-2022 走看看