함수
이 사진을 보면 함수가 무엇인지 이해하기 쉬울 것이다.
다르게 설명하자면 내가 만든 일종의 공식이라고
할 수 있다.
예를 들어, 삼각형의 넓이를 구하는 공식은
(가로길이) X (세로길이) / 2
이다.
이 공식에 가로길이 값을 넣어주고
세로길이 값을 넣어주면 우리는 쉽게 삼각형의 넓이를 구할 수 있다.
함수가 바로 내가 임의로 만드는 공식과 같다고 할 수 있다.
먼저, 내가 입력받아야 하는 값(가로길이와 세로길이)이 바로 파라미터(매개변수)라 하고
계산 결과 나온 값을 리턴 값 (반환 값)이라고 한다.
위에 설명한 삼각형 넓이 구하는 공식을 함수로 만들어보면 다음과 같다.
static int AAA(int a, int b)
{
int c = a * b / 2
return c
}
여기서 int a와 int b가 내가 입력해야할 가로길이와 세로길이가 된다.
c는 넓이가 된다.
AAA는 내가 만든 함수의 이름이 된다.
그렇다면 이 함수를 써보자
static int AAA(int a, int b)
{
int c = a * b / 2
return c
}
int num1 = 10;
int num2 = 30;
int result = AAA(num1, num2)
Console.WriteLine(result)
이렇게 하면 함수 AAA에 각각 10과 30이라는 숫자가 들어가고
그 결과값이 result에 저장될 것이다.
모든 함수가 파라미터와 리턴이 존재하는 것은 아니다.
파라미터가 없는 함수도 있고 리턴이 없는 함수도 있고 둘 다 없는 함수도 있다.
리턴이 없는 함수는 void를 써주어야 한다.
Call by Value와 Call by Reference
Call by Value는 값에 의한 호출로 함수에서 값에 영향을 주지 않는다.
Call by Reference는 주소에 의한 호출로 함수에서 값에 영향을 준다.
주소에 의한 호출을 사용하고 싶다면 파라미터의 자료형 앞에 ref를 붙여주면 된다.
아래 예제를 참조하자
static public void ValueSwap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
static public void RefSwap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
int num1 = 100;
int num2 = -100;
ValueSwap(num1, num2);
Console.WriteLine(num1, num2);
RefSwap(ref num1, ref num2);
Console.WriteLine(num1, num2);
}
메인함수를 포함하여, 총 3개의 함수가 있다.
맨 처음 ValueSwap는 값에 의한 호출로 파라미터 값을 서로 스위핑 해주고
RefSwap는 참조에 의한 호출로 파라미터 값을 서로 스위핑 해준다.
Main 함수를 보면 num1 은 100, num2는 -100로 되어있다
ValueSwap 함수 내에서, num1과 num2의 값은 서로 바뀌겠지만
그것은 어디까지나 함수 내에서만 발생하는 것이며, 함수 밖의 값은 전혀 영향이 가지 않는다.
그러나 RefSwap 함수 내에서, num1 값과 num2 값은 서로 바뀌고 그것이 함수 밖의 원본에까지
영향을 끼친다.
out
out은 ref와 사용방법이 같은 키워드로 전달하는 변수 초기화 없이 사용 가능하다
보통 out을 쓰는 경우, 리턴이 없는 경우가 꽤 있다.
static void InitNum(out int addNum)
{
addNum = 100;
}
static void InitRefNum(ref int addNum)
{
refNum = 100;
}
static void Main(string[] args)
{
int a;
int b;
InitNum(out a);
Console.WriteLine(a) // 출력 결과는 100
InitRefNum(ref b); // 에러!! b를 초기화 하지 않고 사용할 수 없음!!
Console.WriteLine(b)
}
메인함수의 InitNum을 보자, 초기화가 안 된 변수 a가 out 키워드와 함께 파라미터로 들어갔다.
그리고 그렇게 들어간 파라미터는 주소에 의한 호출값이므로
원본 값 a의 값을 변화시킨다.
반면 InitRefNum 같은 경우, 위 코드대로 하면 에러가 발생한다.
b값이 초기화 되지 않았기 때문에 사용할 수 없기 때문이다.
즉 ref과 out의 차이는 초기화가 필요한가 아닌가로 나눌 수 있을 것이다.
파라미터 초기화
파라미터는 뒤에서 순서대로 초기화 된다.
static void AAAA(int a, int b, int c = 100, int d = 0)
{
Console.WriteLine(a, b, c, d);
}
static void Main(string[] args)
{
AAAA(0, 0, 0, 0);
}
AAAA라는 함수를 정의했고, Main함수에서, AAAA함수에 0, 0, 0, 0을 넣었다.
이 경우, AAAA 함수 내에서, a, b, c, d의 값은 전부 0을 받고 Console.WriteLine을 통해, 0 0 0 0이 출력된다.
그렇다면 파라미터에서 int c = 100은 무슨 역할을 하느냐
만약 AAAA(10, 2) 를 Main 함수에 넣을 경우, int c와 int d는 파라미터를 받지 못하게 된다.
이럴 경우, 기본 값으로써 c는 100, d는 0을 받게 되는 것이다.
파라미터는 반드시 뒤에서 순서대로 초기화 된다.
때문에 아래 구문처럼 작성할 수 없다.
static void AAAA(int a, int b = 50, int c, int d = 0)
{
Console.WriteLine(a, b, c, d);
}
c는 기본 값이 주어지지 않았는데, b에 기본값을 넣어줄 수 없다.
즉 기본값은 반드시 뒤에서부터 순서대로 와야 한다.
메소드 오버로딩
메소드 오버로딩이란 메소드 이름이 중복되는 것을 말한다.
C#에서는 함수의 이름을 동일하게 사용할 수 있다.
물론 이 경우, 엄청난 에러가 발생할 수 있지만, 나름대로 구분법이 있으니
이름은 같아도, 파라미터의 수나 타입이 다르면 별개의 함수로 인식한다.
아래 예시를 보자
static int AAAA(int a, int b)
static int AAAA(int a, int b, int c)
static int AAAA(float a, float b)
AAAA라는 이름의 함수가 3개나 선언되었지만 파라미터가 전부 따로 노는 만큼 각자 다른 함수로 인식한다.
이것이 바로 오버로딩이다.
그러나 이는 다음과 같은 상황에서 심각한 부작용을 초래할 수 있다.
static void AAAA(int a, int b, int c)
{
return (a + b + c + d)
}
static void AAAA(int a, int b, int c, int d = 23)
{
return (a + b + c + d) * 2
}
static void Main(string[] args)
{
Console.WriteLine(AAAA(11,22,33))
}
자, AAAA 함수가 두 개가 선언되어 있다.
두번째 AAAA함수의 파라미터 d는 디폴트 값 23 을 가진다.
Main함수에서, AAAA함수에 파라미터를 3개를 넣었다.
이때, 과연 어떤 함수가 실행될지 예상할 수 있는가?
당연히 모호성으로 인한 오류가 발생하게 된다.
때문에 위 코드는 아래와 같이 수정해줄 필요가 있다.
static void AAAA(int a, int b, int c)
{
return (a + b + c + d)
}
static void AAAA(int a, int b, int c, int d) //기본값을 제거
{
return (a + b + c + d) * 2
}
static void Main(string[] args)
{
Console.WriteLine(AAAA(11,22,33))
}
두 번째 AAAA 함수에서 기본값을 제거하였으니
Main함수의 AAAA 함수는 첫 번째 것이 실행된다.
params
파라미터를 무한정 받고 싶을 때 사용하는 키워드다.
아래 예시를 참조하자
static void AAAA(params int[] a)
{
return (a.Length)
}
static void Main(string[] args)
{
Console.WriteLine(AAAA(11,22,33,44))
}
위 코드에서, 함수 AAAA는 정수형 파라미터를 무한정 받는다.
이때, 파라미터는 배열의 형태로 받게되고 이 배열의 이름은 a다.
return에서는 배열 a의 길이를 리턴하라고 되어 있는데
이는 곳 a 가 받은 파라미터의 수를 뜻한다.
Main 함수를 보면 AAAA함수에 파라미터를 총 4개 넣은 것을 알 수 있다.
물론 4개가 아니라 더 적게, 더 많이 넣어줄 수도 있다.
'Language > C#' 카테고리의 다른 글
C# 공부정리 - 배열 2 (0) | 2023.01.01 |
---|---|
C# 공부정리 - 배열 1 (일차원 배열, 다차원 배열, 가변 배열, foreach) (0) | 2023.01.01 |
C# 공부정리 - 기초문법 2 (변수, 조건문, 반복문) (0) | 2022.12.31 |
C# 공부정리 - 기초문법 1 (연산자) (0) | 2022.12.30 |
C# 공부정리 - 데이터 3 (형 변환) (0) | 2022.12.29 |