๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ
728x90

*์ด ๊ธ€์€ <์ด๊ฒƒ์ด C#์ด๋‹ค> ์ฑ…์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ณต๋ถ€ํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

 

 

 

1. ๊ฐ’์— ์˜ํ•œ ํ˜ธ์ถœ (Call by value)

 

ํ•จ์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ ์ „๋‹ฌํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ๋„ฃ์–ด ์ „๋‹ฌํ•ด ์ค€๋‹ค.

  • ๊ฐ’ ํ˜•์‹(Value type)์€ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ ์‹œ์— ํ•ด๋‹น ์ธ์ž์˜ ๊ฐ’์„ ๋ณต์‚ฌํ•ด์„œ ์ „๋‹ฌ
  • ํ•จ์ˆ˜์™€ ๋ฉ”์†Œ๋“œ์—์„œ ๊ฐ’์„ ๋ฆฌํ„ดํ•  ๋•Œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€
  • ์ด๊ฒƒ์„ ๊ฐ’์— ์˜ํ•œ ํ˜ธ์ถœ(Call by value)์ด๋ผ๊ณ  ํ•จ

 

๋‘ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„์„œ ์„œ๋กœ ๊ฐ’์„ ๋ฐ”๊พธ๋Š” Swap() ํ•จ์ˆ˜์—์„œ ์ด๋Ÿฐ ์˜ˆ์‹œ๊ฐ€ ์ž์ฃผ ๋‚˜์˜จ๋‹ค.

static void Swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}

 

๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ์„ ํ•ด ๋ณธ๋‹ค.

static void Main(string[] args)
{
    int x = 3;
    int y = 5;
    
    Swap(x, y);
    
    Console.WriteLine($"x = {x}");    // x = 3
    Console.WriteLine($"y = {y}");    // y = 5
}

 

๋ณ€์ˆ˜ x์™€ y์˜ ๊ฐ’์€ ์„œ๋กœ ๋ฐ”๋€Œ์ง€ ์•Š์•˜๋‹ค. ์›๋ณธ์„ ์ „๋‹ฌํ•œ ๊ฒŒ ์•„๋‹Œ, ๋ณต์‚ฌ๋ณธ์„ ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฆ‰, ์›๋ณธ์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค.

 

 


2. ์ฐธ์กฐ์— ์˜ํ•œ ํ˜ธ์ถœ (Call by reference)

 

๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๋ณ€์ˆ˜ ๋˜๋Š” ์ƒ์ˆ˜๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ๋ณต์‚ฌํ•˜๋Š” ๊ฐ’์— ์˜ํ•œ ํ˜ธ์ถœ๊ณผ ๋‹ฌ๋ฆฌ, ์ฐธ์กฐ์— ์˜ํ•œ ํ˜ธ์ถœ์€ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ฉ”์†Œ๋“œ์— ๋„˜๊ฒจ์ง„ ์›๋ณธ ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

 

 

ref ํ‚ค์›Œ๋“œ

 

Swap() ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋ณด์ž.

public static void Swap(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}

 

๋งค๊ฐœ ๋ณ€์ˆ˜์— ref ๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์—ˆ๋‹ค. ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๋„˜๊ฒจ๋ฐ›์€ ์›๋ณธ ๋ณ€์ˆ˜์— ์ง์ ‘์ ์œผ๋กœ ์ฐธ์กฐํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ Swap() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ๋‹ค.

static void Main(string[] args)
{
    int x = 3;
    int y = 5;
    
    Swap(ref x, ref y);
    
    Console.WriteLine($"x = {x}");    // x = 5
    Console.WriteLine($"y = {y}");    // y = 3
}

 

์›๋ณธ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜์—ฌ Swap() ํ•จ์ˆ˜๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

์ฐธ์กฐ ๋ฆฌํ„ด

 

๊ฐ’ ํ˜•์‹์ด๋ผ๋ฉด ๋ฉ”์†Œ๋“œ์˜ ๋ฆฌํ„ด ๊ฒฐ๊ณผ ๋˜ํ•œ ๋ณต์‚ฌ๋˜์–ด ๋ฐ˜ํ™˜๋˜๋Š” ํ˜•์‹์ด๋ผ๊ณ  ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋ฉ”์†Œ๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ์กฐ๋กœ ๋‹ค๋ฃจ๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ref ํ•œ์ •์ž๋ฅผ ์ด์šฉํ•ด์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ์„ ์–ธํ•˜๊ณ , return ๋ฌธ์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ณ€์ˆ˜ ์•ž์—๋„ ref ํ‚ค์›Œ๋“œ๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.

class Monster
{
    int hp = 100;
    
    public ref int Function()  // ๋ฉ”์†Œ๋“œ ์•ž์— ref ํ‚ค์›Œ๋“œ
    {
       ...
       return ref hp;          // return ๋ฌธ ์•ž์— ref ํ‚ค์›Œ๋“œ ๋ช…์‹œ
    }
}

 

๋งŒ์•ฝ ๊ฐ’์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ฆฌํ„ดํ•˜๋Š” ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด, ํ‰์†Œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

Monster monster = new Monster();
int hp = monster.Function();

 

ํ•˜์ง€๋งŒ, ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ํ˜ธ์ถœ์ž๊ฐ€ ์ฐธ์กฐ๋กœ ๋„˜๊ฒจ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

Monster monster = new Monster();
ref int hp = ref monster.Function();   // ref ํ‚ค์›Œ๋“œ ๋ถ™์ด๊ธฐ
// hp๋Š” ์ฐธ์กฐ ์ง€์—ญ ๋ณ€์ˆ˜

 

๋ฉ”์†Œ๋“œ์˜ ํŠน์„ฑ์ƒ, ๊ฐ’์„ ํ•˜๋‚˜๋งŒ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์„ฑ์ด ์žˆ๋‹ค.

(๋ฌผ๋ก  ํŠœํ”Œ(Tuple), ๋ฆฌ์ŠคํŠธ(List)๊ฐ™์€ ๊ฑธ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ ๋ฆฌํ„ดํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๊ฒƒ ๋˜ํ•œ ์–ด๋””๊นŒ์ง€๋‚˜ ํ•ด๋‹น ๊ฐ์ฒด ํ•˜๋‚˜๋งŒ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์€ ๊ฐ™๋‹ค.)

 

์ฐธ์กฐ๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ์›๋ณธ ๊ฐ’์„ ์—ฌ๋Ÿฌ ๊ฐœ ๋ฐ›์•„์™€์„œ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ์ ์„ ์ด์šฉํ•˜๋ฉด ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ๋” ์œ ์šฉํ•˜๊ฒŒ ์ž‘์šฉํ•  ๊ฒƒ์ด๋‹ค.

 

 

out ํ‚ค์›Œ๋“œ

 

ref ํ‚ค์›Œ๋“œ๋Š” ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์—์„œ ref ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š์•„๋„ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ์‹œ๋ฅผ ๋“ค๊ธฐ ์œ„ํ•ด, ๋‚˜๋ˆ—์…ˆ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ชซ(quotient)๊ณผ ๋‚˜๋จธ์ง€(remainder)๋ฅผ ์ฐธ์กฐ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฑธ ๋ณด์ž.

static void Divide(int a, int b, ref int quotient, ref int remainder)
{
    // ref๋กœ ์„ ์–ธ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š์•„๋„ ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    //quotient = a / b;
    //remainder = a % b;
}


static void Main(string[] args)
{
    int a = 20;
    int b = 3;
    int c = 1;
    int d = 2;

    Divide(a, b, ref c, ref d);
    Console.WriteLine("Quotient : {0}, Remainder : {1}", c, d);
}

 

 

์ด๋Ÿฐ ๋ถ€๋ถ„์€ ๋งŒ์•ฝ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์‹ค์ˆ˜ํ•˜์—ฌ ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์˜ค๋ฅ˜๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฒ„๊น…ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค. out ํ‚ค์›Œ๋“œ๋Š” ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

static void Divide(int a, int b, out int quotient, out int remainder)
{
    // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
    //quotient = a / b;
    //remainder = a % b;
}


static void Main(string[] args)
{
    int a = 20;
    int b = 3;
    int c;
    int d;

    Divide(a, b, out c, out d);
    Console.WriteLine("Quotient : {0}, Remainder : {1}", c, d);
}

 

์ฆ‰, ๋งˆ์น˜ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ถ”์ƒํด๋ž˜์Šค์˜ ์ถ”์ƒ ํ•จ์ˆ˜๊ฐ€ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๊ฐ•์ œ๋กœ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

 

๋˜ ํ•˜๋‚˜์˜ ์‚ฌ์‹ค์€ ref ํ‚ค์›Œ๋“œ๋กœ๋Š” ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š์€ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€๋งŒ, out ํ‚ค์›Œ๋“œ๋Š” ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š์€ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋„˜๊ฒจ์ค˜๋„ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๋Š”๋‹ค. ์–ด์ฐจํ”ผ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์—์„œ ๊ฐ•์ œ๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

out ํ‚ค์›Œ๋“œ๋Š” ์‚ฌ์‹ค ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก ์•ˆ์—์„œ ์ฆ‰์„์œผ๋กœ ์„ ์–ธํ•ด๋„ ๋œ๋‹ค.

static void Divide(int a, int b, out int quotient, out int remainder)
{
    quotient = a / b;
    remainder = a % b;
}


static void Main(string[] args)
{
    int a = 20;
    int b = 3;

    Divide(a, b, out int c, out int d);
    Console.WriteLine("Quotient : {0}, Remainder : {1}", c, d);
}

 

 

728x90
๋ฐ˜์‘ํ˜•