<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    java世界
    有些人注定要生活在彼岸,可以親近可以愛憐,甚至可以窮盡一生去思念,只是無法觸及有些距離,注定不能跨越只能倆倆相望,就像有些愛只能養在心里長在眼中,不能捧在手里放在身邊,注定只能邂逅無法遭遇!
    posts - 12,comments - 15,trackbacks - 0

    傳值?還是傳引用?

    (Wang hailong)

     

    關于編程的參數傳遞問題,總是存在著這樣的爭論。傳值?還是傳引用?(還是傳指針?還是傳地址?)這些提法,經常出現在C++, java, C#的編程技術文檔里面。這個問題也經常引起開發人員的爭論,徒耗人力物力。實際上,這根本不成為問題,只是由于人為加入的概念,混淆了人們的視聽。

    從程序運行的角度來看,參數傳遞,只有傳值,從不傳遞其它的東西。只不過,值的內容有可能是數據,也有可能是一個內存地址

    開發人員應該了解程序的編譯結果是怎樣在計算機中運行的。程序運行的時候,使用的空間可以分為兩個部分,棧和堆。棧是指運行棧,局部變量,參數,都分配在棧上。程序運行的時候,新生成的對象,都分配在堆里,堆里分配的對象,棧里的數據參數,或局部變量。

    下面舉一個C++的例子。

    public class Object{

      int i;

      public Object(int i){

           this.i = i;

      }

     

           public int getValue(){

                  return i;

           }

     

           public void setValue(int i){

                  this.i = i;

           }

    };

     

    class A {

           Void func1(int a, Object b){

                  Object * c = new Object( a );

                 

    b = c;

           }

     

    public      void main(){

           Object * param = new Object( 1 );

     

                  func1( 2,  param )

                 

                  // what is value of parram now ?

                  // it is still 1.

        }

    };

     

    我們來看一下,當調用到func1函數時,運行到Object * c = new Object( a ); 棧和堆的狀態。不同編譯器生成的代碼運行的結果可能會稍有不同。但參數和局部變量的大致排放順序都是相同的。

     

    這時候,我們來看,param變量被壓入運行棧的時候,只是進行了簡單的復制。把param里面的內容拷貝到b里面。這時候,b就指向了Object(1)。這里的參數傳遞,是把param的值傳遞給b

    下面我們來看,程序執行到b = c;時候的堆棧狀態。

     

    我們可以看到,b現在指向了Object(2)。但是對param的值毫無影響。param的值還是Object(1)

    所以,我們說,對參數的賦值不會影響到外層函數的數據,但是,調用參數的操作方法,卻等于直接操作外層函數的數據。比如,如果我們在func1()函數中,不調用b=c;而調用b.setValue(3),那么Object(1)的數據就會變為3param的數據也會改變為3

    javaC#中的情況,也都是一樣。

    C++還有一種變量定義方法,表面上看起來,不符合上面的說明,這里進行說明。

    Object * a = new Object(1);

    Object & * b = a;

    這里的b就等于是a的另外一個別名,b就是a。對b賦值就等于對a賦值。甚至作為參數傳遞時,也是如此。對這種類型的參數的賦值,就等于對外層函數數據的賦值。

    public class B{

    void func1(Object & * b){

           b = new Object(4);

    }

     

    public void main(){

           Object * a = new Object(1);

     

           func1(a);

     

           // a is changed to Object(4) now.

    }

     

    }

    當運行完func1(a);時,a的值變化為Object(4)。這是因為編譯器實際把參數Object & * b編譯為Object ** b_addrb_addr的值是b的地址,也就是a的地址。

    當調用func1()的時候,實際上是把b_addr作為參數壓到棧里,b_addr的值是a的地址。

    當執行b = new Object(4); 時,實際執行了 b_addr->b = new Object(4); 也就是執行了 b_addr->a = new Object(4); a的值當然變化了。

     

    還有一點需要說明,當使用COMCORBA等中間件規范進行開發時,我們需要定義IDL語言。參數的類型分為,[in][out][in, out],其中的RPC遠程調用的參數打包規范,就更復雜了,但原理卻是一樣的。

    posted on 2005-11-17 09:43 安德爾斯 閱讀(389) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 在线播放免费人成视频在线观看 | 亚洲视频一区二区| 亚洲av色香蕉一区二区三区| 国产四虎免费精品视频| 亚洲另类春色校园小说| 无人在线直播免费观看| 亚洲成av人片不卡无码| 足恋玩丝袜脚视频免费网站| 久久青青草原亚洲AV无码麻豆 | 三级网站免费观看| 国产亚洲日韩在线三区| 国产成人AV免费观看| 久久久久亚洲AV无码专区首| 69视频在线观看高清免费| 亚洲精品视频专区| 丁香花免费完整高清观看| 亚洲精品一卡2卡3卡四卡乱码| 噜噜嘿在线视频免费观看| 国产精品亚洲一区二区三区 | 亚洲人成网亚洲欧洲无码久久| 最近免费mv在线观看动漫 | 国产免费区在线观看十分钟| 亚洲人成色777777在线观看| 久艹视频在线免费观看| 亚洲精品亚洲人成在线麻豆| 天堂在线免费观看中文版| 国产亚洲福利精品一区二区| 亚洲欧洲自拍拍偷精品 美利坚 | 激情小说亚洲色图| 亚洲中文久久精品无码| 鲁大师在线影院免费观看 | 狠狠热精品免费观看| 亚洲自偷自偷图片| 蜜臀AV免费一区二区三区| 亚洲色成人WWW永久在线观看| 亚洲成A人片77777国产| 久久精品中文字幕免费| 亚洲熟妇AV一区二区三区浪潮 | 91精品国产亚洲爽啪在线观看| 成人影片麻豆国产影片免费观看| 视频一区在线免费观看|