iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Software Development

C#世界初探險系列 第 15

2022鐵人賽 Day 15 引數的傳遞方式

  • 分享至 

  • xImage
  •  

今天要談談引數傳遞的方式~
當使用return敘述時,一次只能回傳一個值或不傳回值返回到原呼叫處。若方法A某個敘述呼叫另一個方法B時,需要一次傳回兩個以上的值時,使用return敘述便無法做到,此時就必須使用參考呼叫或傳出參數來完成。引數傳遞方式有下列三種:

  1. 傳值呼叫(Call by Value)
    是只當呼叫方法時,此時實引數會複製一份給虛引數,因此實引數與虛引數兩者佔用不同的記憶體位址。當虛引數被修改時,不會影響對應的實引數。此種引數傳遞方式稱為傳值呼叫
    C#預設為傳值呼叫,適用於希望方法內的結果不會影響方法外的變數時使用,有保護變數不被修改的功能。呼叫中,實引數可為變數、常數或運算式。
    範例:

        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;
            Console.WriteLine("CallByValue前\ta={0},b={1}", a.ToString(), b.ToString());
            CallByValue(a, b);
            Console.WriteLine("CallByValue後\ta={0},b={1}", a.ToString(), b.ToString());
    
        }
        private static void CallByValue(int x, int y)
        {
            x = 30;
            y = 40;
            Console.WriteLine("CallByValue內\tx={0},y={1}", x.ToString(), y.ToString());
        }
    

    Call by Value

  2. 參考呼叫(Call by Reference)
    方法A呼叫方法B時,若希望B執行結果回傳給A,使用傳值呼叫是無法做到的。若能將實引數和虛引數彼此對應的引數設成佔用相同的記憶體位址,此時虛引數一變,對應的實引數也會跟著變,便可將B的結果回傳給A,此種方法稱為參考引數。操作方式只要將虛引數及實引數宣告為ref,即可成為參考呼叫,但要注意參考呼叫的實引數必須是變數、陣列或物件,不可為常數或運算式,且必須給初值才能使用。
    範例:

        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;
            Console.WriteLine("CallByRef前\ta={0},b={1}", a.ToString(), b.ToString());
            CallByRef(ref a, ref b);
            Console.WriteLine("CallByRef後\ta={0},b={1}", a.ToString(), b.ToString());
    
        }
        private static void CallByRef(ref int x, ref int y)
        {
            x = 30;
            y = 40;
            Console.WriteLine("CallByRef內\tx={0},y={1}", x.ToString(), y.ToString());
        }
    

    Call by Reference

  3. 傳出參數(Output parameter)
    傳出參數和參考呼叫的實引數和虛引數都是共同佔用相同記憶體位址。兩者差異在於傳出參數的實引數變數不必設定初值即可做參數傳遞。若在呼叫敘述及被呼叫方法的引數串列參數前面加上out,即可成為傳出參數。
    範例:

        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;
            Console.WriteLine("CallOut前\ta={0},b={1}", a.ToString(), b.ToString());
            CallOut(out a, out b);
            Console.WriteLine("CallOut後\ta={0},b={1}", a.ToString(), b.ToString());
    
        }
        private static void CallOut(out int x, out int y)
        {
            x = 30;
            y = 40;
            Console.WriteLine("CallOut內\tx={0},y={1}", x.ToString(), y.ToString());
        }
    

    CallOut

那最後要如何在方法間傳遞陣列呢?
一樣很簡單,在使用者自定方法中的虛引數必須在資料型態之前加上ref,以及在該資料型態之後加上[]和陣列名稱即可,但[]內不要設定陣列大小,至於實引數內,只要在陣列名稱之前加上ref即可,陣列名稱後面不用加[]。由於陣列名稱即代表陣列的起始位址,因此實引數和虛引數內陣列名稱前面的ref可以同時省略並不會發生錯誤,但如果只有一方有寫ref則程式編譯時會發生錯誤。
直接遞上範例:

        static void Main(string[] args)
        {
            int[] tAry = new int[] { 15, 10, 50, 75, 65, 55 };
            Console.WriteLine("陣列內容如下:");
            for (int i = 0; i <= tAry.GetUpperBound(0); i++)
                Console.Write("{0} ", tAry[i]);
            Console.WriteLine("\r\n最大值:{0}", GetMax(tAry));
        }
        static int GetMax(int[] ary)
        {
            int i, max;
            max = ary[0];
            for(i = 1; i <= ary.GetUpperBound(0); i++)
                if (ary[i] > max)
                    max = ary[i];
            return max;
        }

方法間傳遞陣列

還有一個叫做方法多載
方法多載是允許在類別中,建立多個相同名稱的方法,做法是以虛引數的引數個數或引數資料型態的不同來區別名稱的方法。如此可減少使用者命名的困擾,如下面sum()有四個方法多載。

  1. 當x和y都是整數時呼叫:

    static int sum(int x, int y)
    {
        return (x + y);
    }
    
  2. 當x、y、z都是整數時呼叫:

    static int sum(int x, int y, int z)
    {
        return (x + y + z);
    }
    
  3. 當x和y都是字串時呼叫:

    static string sum(string x, string y)
    {
        return (x + y);
    }
    
  4. 當x、y、z都是字串時呼叫:

    static string sum(string x, string y, string z)
    {
        return (x + y + z);
    }
    

程式執行時:

  1. 執行sum(2,3)時,呼叫第一個方法
  2. 執行sum(2,3,4)時,呼叫第二個方法
  3. 執行sum("2","3")時,呼叫第三個方法
  4. 執行sum("2","3","4")時,呼叫第四個方法

好啦~~今天就到這邊結束啦~
大家掰掰~


上一篇
2022鐵人賽 Day 14 方法的使用
下一篇
2022鐵人賽 Day 16 區塊變數、區域變數、靜態變數和類別欄位
系列文
C#世界初探險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言