×
Crocus
공부한 내용을 정리하는 블로그로 시작한
Crocus는 2014년 1월 14일 부터 시작하여
현재 월 6만명, 총 2,101,710명의 방문자 수를 기록하고 있습니다.
Donation
이제 많은 사용자들이 이용하는 만큼
더 다양한 서비스 개발/제공을 위해 후원금을 모금하고자 합니다.
후원을 해주시는 분들은 Donators 명단에 성명, 후원금을 기입해드리며
Crocus 블로그가 아닌 다른 곳에 정리해둔 저만의 내용을 공유해 드리고자 합니다.
Account
예금주 : 고관우
신한은행 : 110-334-866541
카카오뱅크 : 3333-01-7888060

👉 후원 페이지 바로가기 Donators
익명 : 5000원(Crocus응원합니다.)
busyhuman: 5000원(유용한 지식 감사합니다.)
익명 : 5000원(알고리즘 학습러)
반응형

1. 참조


참조라는 것은 C++에 들어서서 생긴 문법(?)이다.


좀더 쉽게 참조를 생각해보자면 참조는 별명을 지어주는 것과 같다.


&라는 기호로 참조를 표현한다.




** &는 주소를 나타내는 기호가 아닌가요 ?? **


C에서 &는 주소를 나타내는 역할을 한다.


하지만 CPP에서는 다음과 같이 &를 쓰면 참조로 이용할 수 있다.


-> 변수명 앞에 &를 쓰면 참조이다.


예를들어 int &a = b;를 하면 b변수값을 a가 참조한다는 의미이다.


지금부터 a의 값을 변경시키면 b의 값도 변하게 된다.


왜냐면 a는 b의 별명이기에 a와 b는 같은 존재이다.


하지만 int &a = 2;는 선언이 되지 않는다.


왜냐면 2의 별명을 a라고 지을 수 없고 2의 값을 변경한다는건 말이 되지 않기 때문이다.




참조를 이용하여 swap 함수를 만들어보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cstdio>
 
using namespace std;
 
void swap(int &c, int &d)
{
    int tmp = c;
    c = d;
    d = c;
}
int main()
{
    int a = 2, b = 3;
    swap(a, b);
 
    cout << a << " " << b << endl;
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


위의 코드에서 보면 a와 b를 그냥 값으로 보냈는데 swap함수에서는 &c, &d라는 참조로(별명으로) 받고 있다.


따라서 c와 d는 각각 a와 b 자체를 보게되는 것이고 swap을 하게되면 a와 b의 값이 바뀌게 된다.





** 포인터와 참조가 그럼 무슨 차이가 있죠? 참조가 무조건 좋은것 아닌가요? **


이런 간단한 코드에서는 참조를 쓸 수 있지만 추후에 배울 자료구조에서는 참조개념으로 해결 할 수 없고 포인터 개념으로 해결해야하는 내용들이 있다.


즉, 지금은 같아 보여도 코딩을 다양하게 하다보면 참조와 포인터의 차이점을 자연스럽게 느끼게 된다. 





이제 그럼 참조를 이용하여 몇가지 문제를 풀어보자



문제 1.


int &a = b;라는 구문이 있다.


이때 a와 b의 주소는 같을까 다를까 한번 주소를 찍어보자.





문제 2.


아래 코드가 정상출력 되도록 compare의 ??를 작성해보시오.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cstdio>
 
using namespace std;
 
bool compare(const int &a, const int &b)
{
    // ??
}
int main()
{
    int num1, num2;
    cin >> num1 >> num2;
 
    if (compare(num1, num2))
        cout << "num1이 크거나 같다" << endl;
    else
        cout << "num2가 크다" << endl;
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus







2. template


템플릿은 여러 type에도 쓰일 수 있는 함수를 하나의 함수로 표현해주는 역할을 한다.


아래 코드를 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <cstdio>
 
using namespace std;
 
template <typename T>
void SWAP(T &a, T &b)
{
    T tmp = a;
    a = b;
    b = tmp;
}
 
void _swap(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
void _swap(char a, char b)
{
    char tmp = a;
    a = b;
    b = tmp;
}
 
int main()
{
    int v1, v2;
    cin >> v1 >> v2;
 
    cout << "v1 :: " << v1 << " v2 :: " << v2 << endl;
 
    SWAP(v1, v2);
 
    cout << "v1 :: " << v1 << " v2 :: " << v2 << endl;
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus



위 에서 _swap 두개의 함수를 보자.


하나는 int형이고 하나는 char형이 매개변수로 들어온다.


이렇게 int, char, double, ... 등등의 여러가지 형태로 들어올 때마다 여러가지 _swap을 만들면 불편할 나름이다.


따라서 위와 같이 template를 이용하여 하나의 함수로 합쳐주면 프로그램이 입력값에 따라 알아서 형변환을 통해 swap을 해주게 된다.


template 형식은 다음과 같다.


template <typename T>  // T는 타입 이름을 지정할 변수명이다.

함수명{

코드

}


이때 T가 int가 될지 , char이 될지 다른것이 될지 모르지만 매개변수의 타입과 실제 코딩할때 매개변수와 같은 타입인 코드라면

T라고 설정해준다.


예를들어


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <cstdio>
 
using namespace std;
 
template <typename T>
void SWAP(T &a, T &b)
{
    T tmp = a;
    a = b;
    b = tmp;
}
 
 
int main()
{
    int v1, v2;
    cin >> v1 >> v2;
 
    cout << "v1 :: " << v1 << " v2 :: " << v2 << endl;
 
    SWAP(v1, v2);
 
    cout << "v1 :: " << v1 << " v2 :: " << v2 << endl;
    
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


이 코드에서 SWAP함수를 보면 T tmp = a라고 되있는데 a는 cin 부분에서 int형으로 받으니 당연히 tmp도 a와 같은 타입이 되어야하니 T라고 설정해준다는 것이다.



** 함수 오버로딩 **


함수 _swap는 함수 오버로딩을 하고있다.

함수 오버로딩이란 ?


같은 함수명인데 매개변수가 어떻게 들어오냐에 따라 함수명이 같아도 서로 다른 함수에 들어가게 된다. 


예를들어 v1, v2가 'a', 'b'였다면 char 형인 _swap에 들어가게되고 v1, v2가 1, 2라면 int 형인 _swap에 들어가게 된다.


가령 이런 코드도 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cstdio>
 
using namespace std;
 
int func(int a, int b)
{
    return a + b;
}
 
int func(int a, int b, int c, int d = 0)
{
    return a + b + c + d;
}
 
int main()
{
    cout << func(12<< endl;
    cout << func(123<< endl;
    cout << func(1234<< endl;
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


첫번째 func(1,2)는 첫번째 func함수에 들어가게 된다.


두번째 func(1,2,3)은 두번째 func함수에 들어가게 된다.


이때 4번째 매개변수인 d에 아무 값이 들어오지 않는다면 d = 0으로 처리해버린다.


세번째 func(1,2,3,4)는 두번째 func함수에 들어가게 된다.


이러한 것들을 함수 오버로딩이라고 한다.







반응형

'Tutoring > C++' 카테고리의 다른 글

다양한 입/출력 방식  (0) 2018.03.07
operator  (0) 2018.03.07
참조, template  (0) 2018.03.02
class 및 상속  (0) 2018.02.27
입출력, namespace  (0) 2018.02.26