C : 매크로, C++ : 인라인함수
매크로의 종류는 단순, 함수형, 객체형이 있다. (참조)
#define MY_MECRO // 단순 매크로 선언
#define PI (3.14) // 매크로 상수 선언
#define PC "Personal Computer" // 매크로 상수 선언
#define PRN(x) printf("%d\n",x) // 매크로 함수 선언
C 매크로 함수
매크로로 변수/함수를 정의하여 매크로 함수를 통한 인라인을 한다.
전처리기에 해당하여 컴파일 전에 처리 그리고 치환된다.
함수 형식 매크로를 정의해서 함수 대신 사용할 수 있다.
함수 형식 매크로를 여러번 사용하면 프로그램 데이터 크기가 커지므로 단순하고 짧은 처리 시 사용한다.
#define 등... (더보기)
#include <iostream>
#define SQUARE(x) ((x)*(x))
int main(void){
std::cout<<SQUARE(5)<<std::endl;
// 전처리 과정을 거쳐 아래와 같이 변환
// std::cout<<((5)*(5))<<std::endl;
// 함수의 몸체부분이 함수의 호출문을 대체
return 0;
}
1. 매크로 함수의 전체를 괄호(())로 감싸야 합니다.
2. 매크로 함수의 인수들도 각각 괄호로 감싸야 합니다.
#define SQUARE(x) ((x)*(x))
매크로 함수 장점 : 실행속도 향상
함수 호출에 의한 성능 저하가 일어나지 않기 때문에 일반 함수에 비해 실행속도가 빠르다.
성능향상에 도움이 되는 상황 : 단순하고 짧은 처리 시 사용하기
단순 치환만 하여 인수 타입에 구애받지 않는다.
여러 개의 명령문을 동시 포함할 수 있다.
매크로 함수 단점 : 구현의 어려움, 디버깅
정의하기 어렵고, 복잡한 함수는 매크로로 표현하는데 한계가 있다.
오류 디버깅하기 어렵다.
함수 크기가 증가하면 괄호가 늘어나 가독성이 떨어져 간단한 함수 대체 시 권장
INLINE
인라인 함수 : 프로그램 실행 소스코드 라인(line) 안으로 (in) 함수 정의가 들어가 버린 함수
C++ 인라인함수는 매크로함수를 개선한 느낌
매크로를 이용한 함수의 인라인화 : 전처리기에 의해 처리
키워드 inline을 이용한 함수의 인라인화 : 컴파일러에 의해 처리
#include <iostream>
// 인라인 함수 정의
// 키워드 inline 선언으로 정의됨
inline int SQUARE(int x){
return x*x;
}
int main(void)
{
// 인라인 함수이므로 몸체부분이 호출문을 대신함
std::cout<<SQUARE(5)<<std::endl;
std::cout<<SQUARE(12)<<std::endl;
return 0;
}
C++의 인라인 키워드로 인라인화 : 함수 앞에 inline을 붙여준다.
컴파일러로 처리로 인해,
1. 매크로 함수보다 디버깅하기 좋다.
2. 구현하기 편하고 컴파일러로 최적화 기회 제공
함수의 인라인화가 해가 될 경우 키워드를 무시하거나 필요 시 일부 하수를 임의로 인라인 처리하기도 한다.
의존성이 적은 게 인라인 함수에 없는 매크로 함수의 장점
자료형에 의존적이지 않은 매크로 함수
#define SQUARE(x) ((x)*(x))
std::cout<<((12)*(12)); //int형 함수호출
std::cout<<((3.14)*(3.14)); //double형 함수호출
inline int SQUARE(int x){
return x*x;
}
std::cout<<((12)*(12)); //int형 함수호출
std::cout<<((3.14)*(3.14)); //double형 함수호출 //9가 출력
인라인 함수에서는 자동 변환이 되지 않아 데이터의 손실 발생
이를 막으려면 함수 오버로딩이 필요하나 함수 정의가 늘어나 간결하려는 원래의 목표와 멀어지므로
C++ 템플릿을 사용하면 자료형에 의존적이지 않은 함수 사용이 가능하다.
C++에서 typename 키워드와 class 키워드를 같은 것으로 생각한다.
#include <iostream>
template <typename T>
inline T SQUARE(T x){
return x*x;
}
int main(void)
{
std::cout<<SQUARE(5.5)<<std::endl;
std::cout<<SQUARE(12)<<std::endl;
return 0;
}
템플릿 : 여러 자료형으로 사용할 수 있도록 하는 틀
함수 템플릿과 클래스 템플릿으로 나누어진다.
타입마다 별도의 함수나 클래스를 만들지 않고도 여러 자료형으로 사용할 수 있도록 하는 틀
(여러 색을 모아두었다 그때마다 골라 쓰는 다색 볼펜)
#include <iostream>
using namespace std; //C++ std 생략
template <typename T>
void Swap(T& a, T& b);
int main(void)
{
int c = 2, d = 3;
cout << "c : " << c << ", d : " << d << endl;
Swap(c, d);
cout << "c : " << c << ", d : " << d << endl;
string e = "hong", f = "kim";
cout << "e : " << e << ", f : " << f << endl;
Swap(e, f);
cout << "e : " << e << ", f : " << f << endl;
return 0;
}
template <typename T>
void Swap(T& a, T& b)
{
T temp;
temp = a;
a = b;
b = temp;
}
앞장에서 작성했던 swap을 좀 더 간결하게 할 수도 있을 것 같다.
'C, C++ > 열혈 C++ 프로그래밍' 카테고리의 다른 글
02-1 챕터 02의 시작에 앞서 (0) | 2021.08.19 |
---|---|
01-5 이름공간 (0) | 2021.08.19 |
01-3 매개변수의 디폴트 값 (0) | 2021.08.18 |
01-2 함수 오버로딩 (0) | 2021.08.18 |
[윤성우 열혈 c++] 01-1 printf, scanf를 대신하는 입출력 (0) | 2021.08.17 |