欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中按引用傳遞與按值傳遞的區(qū)別,以及ref與out關(guān)鍵字的用法詳解

 更新時間:2013年07月26日 09:48:36   作者:  
以下是對C#中按引用傳遞與按值傳遞的區(qū)別,以及ref與out關(guān)鍵字的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下

復(fù)制代碼 代碼如下:

/給三個整數(shù)從小到大排序并求和及其平均值
//其中,三個待求整數(shù)及其排序的結(jié)果由引用參數(shù)傳遞;其和由輸出參數(shù)傳遞;平均值由返回值返回。
//在Main()方法中實(shí)現(xiàn)三個待求整數(shù)的輸入及結(jié)果的輸出
//目的:定義方法;調(diào)用方法;;理解形參和實(shí)參的引用傳遞關(guān)系;熟悉引用參數(shù)和輸出參數(shù)的使用。
using System;
class Class1
 {
   //x,y,z是形參,按值傳遞
   static void Sort(int x, int y, int z)
    {
      int temp=0;
      if(x>y)
       {
         temp=x;
         x=y;
         y=temp;
       }
      if(y>z)
       {
         temp=z;
         z=y;
         if(x>temp)
          {
            y=x;
            x=temp;
          }
         else
          {
            y=temp;
          }
       }
       Console.WriteLine("The sorted list is {0},{1},{2}",x,y,z);
       x=x+y+z;
    }

   //i,j,k,total是形參,按引用傳遞(ref參數(shù),out參數(shù),都是按引用傳遞的方式)
   static double Average(ref int i, ref int j, ref int k, out int total)
    {
      double l = 0;
      total = i+j+k;
      i=total;
      l=(double)(total/3.0);
      return l;
    }

   static void Main()
    {
      //a,b,c是實(shí)參,將要賦值給形參i,j,k,total;
      int a, b, c;

      //聲明out參數(shù)result,可以不用初始化它
      int result;

      Console.Write("Please enter the first number a =");
      a = Convert.ToInt32(Console.ReadLine());
      Console.Write("Please enter the second number b =");
      b = Convert.ToInt32(Console.ReadLine());
      Console.Write("Please enter the third number c =");
      c = Convert.ToInt32(Console.ReadLine());     

      Sort(a,b,c);

      //Sort(int x, int y, int z)函數(shù)中,形參x,y,z是按值傳遞的,所以即使函數(shù)中有x=x+y+z;函數(shù)      //執(zhí)行后實(shí)參a值不變。
      Console.WriteLine("The original value of /"a/" is {0}, it hadn't been changed in spite "+"of manipulating the Sort() method, because it is transmitted by a Value para /"x/"!",a);

      //Average(ref int i, ref int j, ref int k, out int total)函數(shù)中,形參a,b,c,result都是        //按引用傳遞的,執(zhí)行后實(shí)參a值改變。
      Console.WriteLine("The average result is {0}",Average(ref a,ref b,ref c, out result));
      //ref參數(shù)在調(diào)用方法前必須幾經(jīng)初始化。
      //而out參數(shù)在調(diào)用方法前可以沒有初始化,他們都以引用傳遞方式傳遞

      Console.WriteLine("The value of /"a/" has been changed due to the Average() method"    +" is manipulated, and it is transmitted by a ref para /"ref i/"! now it is {0}!",a);

      Console.ReadLine();
    }
 }


問題與解答:

1,值傳遞時,為什么被調(diào)用的方法中的形參值的改變不會影響到相應(yīng)的實(shí)參?
答:因?yàn)榘粗祩鬟f時,系統(tǒng)首先為被調(diào)用的方法的形參分配內(nèi)存空間,然后把實(shí)參中的值按位置一一對應(yīng)“復(fù)制”給形參。形參中存儲的值只是一份實(shí)參的拷貝,因此被調(diào)用方法中形參值的任何改變都不會影響到相應(yīng)的形參。

2,值傳遞和引用傳遞有什么不同,什么是值參數(shù),它以什么方式傳遞?
答:值傳遞時,系統(tǒng)首先為被調(diào)用方法的形參分配內(nèi)存空間,并將實(shí)參的值按位置一一對應(yīng)地復(fù)制給形參,此后,被調(diào)用方法中形參值得任何改變都不會影響到相應(yīng)的實(shí)參; 而引用傳遞時,系統(tǒng)不是將實(shí)參本身的值復(fù)制后傳遞給形參,而是將其引用值(即地址值)傳遞給形參,因此,形參所引用的該地址上的變量與傳遞的實(shí)參相同,方法體內(nèi)相應(yīng)形參值得任何改變都將影響到作為引用傳遞的實(shí)參。

3,什么是形參,什么是實(shí)參?
答:
形參:
在定義函數(shù)中指定的參數(shù)就是形參,在未出現(xiàn)函數(shù)調(diào)用時,他們并不占內(nèi)存中的存儲單元,只有在發(fā)生函數(shù)調(diào)用時,函數(shù)中的形參才被分配內(nèi)存單元。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。

實(shí)參:實(shí)參可以是常量、變量和表達(dá)式,但要求有確定的值。在調(diào)用時將實(shí)參的值賦給形參。在內(nèi)存中,實(shí)參單元和形參單元是不同的單元。在調(diào)用函數(shù)時,給形參分配存儲單元,并將實(shí)參對應(yīng)的值傳遞給形參,調(diào)用結(jié)束后,形參單元被釋放,實(shí)參單元仍保留原值。

理解:
實(shí)參就是送進(jìn)去方法中的東西~~行參就是把送進(jìn)來的東西在方法中進(jìn)行拷貝加工,加工完后方法就返回一個東西--返回值。

值傳遞的時候,實(shí)參是不變的~形參是隨著計(jì)算而變化的~~
指針/引用傳遞的時候~~行參怎么變~實(shí)參就怎么變.... 

參數(shù)的傳遞分為:1.值方式參數(shù)傳遞,2.引用方式參數(shù)傳遞。
1)按值傳遞(不能改變實(shí)參)
實(shí)參是變量,表達(dá)式等數(shù)值。

函數(shù)調(diào)用的時候,實(shí)參和形參存在于內(nèi)存中2快不同的區(qū)域,實(shí)參先自己復(fù)制一份拷貝,再把拷貝傳給形參。由于是傳遞的是拷貝,所以實(shí)參不會受形參的影響,實(shí)參值不會被改變。

2)按地址傳遞(可以改變實(shí)參)
實(shí)參是指針/引用。

函數(shù)調(diào)用的時候,指針傳給你,形參和實(shí)參指針都一樣,對形參的任何操作就等于對實(shí)參的操做。實(shí)參的值就可以被改變。

對參數(shù)的影響:
2種數(shù)據(jù)類型:值類型+引用類型
2種傳參方式:值傳參+引用傳參(ref與out關(guān)鍵字);

以上的四種參數(shù)的組合 除了值傳參方式傳遞值類型數(shù)據(jù),其他的組合方式對參數(shù)的操作都會影響參數(shù),都會改變!

值類型:簡單類型(int,float,double,long,char,bool)+結(jié)構(gòu)+枚舉
存儲結(jié)構(gòu):數(shù)據(jù)存放在棧中(棧:先進(jìn)后出;單入口,單出口);效率高
賦值方式:傳的是值

引用類型:除去簡單類型(int,float,double)+結(jié)構(gòu)+枚舉以外的類型都是引用數(shù)據(jù)類型。如string;object;類;數(shù)組;委托;接口...
存儲結(jié)構(gòu):棧中存地址;堆中放數(shù)據(jù);
賦值方式:傳的是數(shù)據(jù)的地址。

形參:全稱為"形式參數(shù)"是在定義函數(shù)名和函數(shù)體的時候使用的參數(shù),目的是用來接收調(diào)用該函數(shù)時傳入的參數(shù).
實(shí)參:全稱為"實(shí)際參數(shù)"是在調(diào)用時傳遞個該函數(shù)的參數(shù).

形參和實(shí)參的類型必須要一致,或者要符合隱含轉(zhuǎn)換規(guī)則,
當(dāng)形參和實(shí)參不是指針類型時(即不是按引用傳遞,而是按值傳遞時),
在該函數(shù)運(yùn)行時,形參和實(shí)參是不同的變量,
他們在內(nèi)存中位于不同的位置,形參將實(shí)
參的內(nèi)容復(fù)制一份,在該函數(shù)運(yùn)行結(jié)束的時候形參被釋放,
而實(shí)參內(nèi)容不會改變.

而如果函數(shù)的參數(shù)是指針類型變量(按引用傳遞),在調(diào)用該函數(shù)的過程
中,傳給函數(shù)的是實(shí)參的地址,在函數(shù)體內(nèi)部使用的也是
實(shí)參的地址,即使用的就是實(shí)參本身.所以在函數(shù)體內(nèi)部
可以改變實(shí)參的值.

按引用傳遞最大的用途是實(shí)現(xiàn)“操作符”重載!

ref參數(shù)與out參數(shù)的區(qū)別在于:ref參數(shù)在調(diào)用方法前必須幾經(jīng)初始化。而out參數(shù)在調(diào)用方法前可以沒有初始化,他們都以引用傳遞方式傳遞

C++有了“引用傳遞”后,“形參的改變不影響實(shí)參”被判無效。因?yàn)閭鬟f給函數(shù)的并不是一個值,而是變量自身。在函數(shù)中定義的形參雖然還是局部變量,但卻是一個引用。雖然這個引用的作用域僅限于函數(shù)內(nèi)部,但是由于它與實(shí)參就是同一回事,所以對它的操作完全等同于對實(shí)參的操作。比如你叫“黑旋風(fēng)”去買魚,或者叫“鐵?!比ベI魚,去的都是同一個人。

C++為什么要有“引用傳遞”這回事?一種說法是只有引用才能達(dá)到操作符重載的目的,這個以后再談。但是,撇開這個不談,形參是不是引用,直接影響了程序執(zhí)行的效率。前面提到過,函數(shù)調(diào)用時要用實(shí)參的值去初始化形參,初始化的過程包含了定義一個變量、然后給它賦一個值兩個過程,如果這個變量并不是內(nèi)部變量,而是一個類對象,那么,定義一個類對象可能很復(fù)雜,而初始化這個對象一樣會很復(fù)雜。而引用只是給對象取一個別名,不涉及定義與初始化,離開作用域時也不用釋放。

相比之下,用指針傳遞可以避免類對象的定義、初始化與釋放。只需要付出指針變量的定義、初始化與釋放的代價。但是,指針的殺傷力太大。即使是熟練的程序員,也不能保證絕不出現(xiàn)“野指針”,野針的代價幾乎無一例外是程序崩潰。

引用也不是吃素的,如果說指針傳遞是“幫你配了一把我家的鑰匙”,那么引用傳遞就是直接把我家的財(cái)產(chǎn)都交給了你。有時,我們使用引用傳遞僅僅是為了效率,而不希望實(shí)參被修改,那就要記得把形參標(biāo)記為const,如“UINT GetLength(const CString&)”。

順便說一句,指針傳遞也可以這樣做。把形參定義為指向const對象的指針(而不是const指針),可以降低殺傷力,保護(hù)實(shí)參所對應(yīng)的內(nèi)存。如果是普通的值傳遞,那么有沒有const對函數(shù)外部并不影響。但是,我個人認(rèn)為,有時候加上const也是一件好事。如果程序的邏輯并不需要改變參數(shù),而實(shí)際上誤寫了代碼,加上const可以讓編譯器幫我們找出BUG。

相關(guān)文章

  • C#實(shí)現(xiàn)打造氣泡屏幕保護(hù)效果

    C#實(shí)現(xiàn)打造氣泡屏幕保護(hù)效果

    本文是介給大家介紹一個很好玩的小程序:氣泡屏幕保護(hù)!類似于windows的屏保功能,有需要的朋友可以參考一下。
    2016-10-10
  • C#多線程TPL常見操作誤區(qū)與異常處理

    C#多線程TPL常見操作誤區(qū)與異常處理

    本文詳細(xì)講解了C#多線程TPL常見操作誤區(qū)與異常處理,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • C#判斷指定文件是否是只讀的方法

    C#判斷指定文件是否是只讀的方法

    這篇文章主要介紹了C#判斷指定文件是否是只讀的方法,涉及C#中Attributes屬性的使用技巧,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-04-04
  • C# 封裝HtmlHelper組件:BootstrapHelper

    C# 封裝HtmlHelper組件:BootstrapHelper

    這篇文章主要介紹了C# 封裝HtmlHelper組件之BootstrapHelper 的相關(guān)資料,需要的朋友可以參考下
    2016-08-08
  • C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例

    C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例

    本文主要介紹了C#連接藍(lán)牙設(shè)備的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C#實(shí)現(xiàn)圖片切割、切圖、裁剪

    C#實(shí)現(xiàn)圖片切割、切圖、裁剪

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)圖片切割、切圖、裁剪,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C#+RedisSearch實(shí)現(xiàn)高性能全文搜索

    C#+RedisSearch實(shí)現(xiàn)高性能全文搜索

    Redis?Search是一個Redis模塊,它使用壓縮的倒排索引來實(shí)現(xiàn)快速的索引和低內(nèi)存占用,本文主要介紹了C#如何使用RedisSearch實(shí)現(xiàn)高性能全文搜索,希望對大家有所幫助
    2023-07-07
  • C# 9.0 新特性之模式匹配簡化的實(shí)現(xiàn)

    C# 9.0 新特性之模式匹配簡化的實(shí)現(xiàn)

    這篇文章主要介紹了C# 9.0 新特性之模式匹配簡化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • C#創(chuàng)建SQLite控制臺應(yīng)用程序詳解

    C#創(chuàng)建SQLite控制臺應(yīng)用程序詳解

    這篇文章主要為大家詳細(xì)介紹了C#創(chuàng)建SQLite控制臺應(yīng)用程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Unity3D實(shí)現(xiàn)待機(jī)狀態(tài)圖片循環(huán)淡入淡出

    Unity3D實(shí)現(xiàn)待機(jī)狀態(tài)圖片循環(huán)淡入淡出

    這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)待機(jī)狀態(tài)圖片循環(huán)淡入淡出,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評論