1. 인라인 함수
1) 함수 호출에 따른 시간 오버헤드
- 함수 호출 시 발생하는 오버헤드를 줄이기 위해서 함수를 호출하는 대신 함수가 호출되는 곳마다 함수의 코드르 복사하여 넣어주는 특별한 함수
- 작은 크기의 함수를 호출하면, 함수 실행 시간에 비해 호출을 위해 소요되는 시간이 상대적으로 커짐
#include <iostream>
using namespace std;
int odd(int x)
{
return (x%2);
}
int main()
{
int sum = 0;
// 1에서 10000까지의 홀수의 합 계산
for(int i=1; i<=10000; i++)
{
if(odd(i))
sum += i;
}
cout << sum;
}
- 위 코드의 경우 10000번의 함수 호출에 따른 엄청난 오버헤드 시간이 소요됨.
2) 인라인 함수
- 정의
- 함수의 선언이나 정의에 inline 키워드를 지정하여 선언된 함수
- 목적
- 프로그램 실행 속도 향상
- 자주 호출되는 짧은 코드의 함수 호출에 대한 시간 소모를 줄임
- 프로그램 실행 속도 향상
- 처리
- 인라인 함수를 호출하는 곳에 인라인 함수 코드를 확장 삽입
- 매크로와 유사
- 코드 확장 후 인라인 함수는 사라짐
- 인라인 함수 호출
- 함수 호출에 따른 오버헤드는 존재하지 않음
- 프로그램의 실행 속도 개선
- 인라인 함수를 호출하는 곳에 인라인 함수 코드를 확장 삽입
- 제약 사항
- recursion(재귀), 긴 함수, static, 반복문, goto 문 등을 가진 함수는 컴파일러에서 수용하지 않음
- 단점
- 인라인 함수 코드의 삽입으로 컴파일된 전체 코드 크기 증가
- 통계적으로 최대 30%가 증가
- 따라서 짧은 코드의 함수만을 인라인으로 선언하는 것이 좋음
- 인라인 함수 코드의 삽입으로 컴파일된 전체 코드 크기 증가
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
for(int i=1; i<=10000; i++)
{
if((i%2)) sum += i; //인라인 함수
}
cout << sum;
}
3) 인라인 함수 vs 매크로 함수
- 매크로 함수
- 선행처리기에 의한 문자열 대치 방식
- 연산자 우선 순위 문제 발생
- 인자의 타입을 검사 X
- 따라서 인라인 함수를 사용하는 것이 좋
- 인라인 함수
- 컴파일러에 의한 코드 대치 방식
2. 디폴트 인자(Default Parameter)
- 인자에 값이 넘어오지 않는 경우, 디폴트 값을 받도록 선언된 인자
- '인자 = 디폴트 값' 형태로 선언
- 함수의 선언부에 지정
void default_sample(char c, int i, double d = 0.5 ); // 함수의 선언부에 디폴트 인자 선언
void main()
{
default_sample (‘X', 10);
default_sample (‘Y', 30, 2.0);
}
- 제약 조건
- 디폴트 인자 지정 순서
- 함수의 가장 오른쪽 인자부터 지정
- 함수 인자의 생략
- 함수의 가장 오른쪽 인자부터 생략
- 디폴트 인자 지정 순서
void foo1(char c, int i, double d);
void foo2(char c, int i, double d = 0.5);
void foo3(char c, int i = 10, double d = 0.5);
void foo4(char c = 'A’, int i = 10, double d = 0.5);
void foo(char c = 'A', int i = 10, double d = 0.5);
foo('A', 20); // 세 번째 인자만 생략함
foo('B'); // 두 번째, 세 번째 인자만 생략함
foo(); // 인자 모두를 생략함
3. 함수 중복(오버로딩)
- 함수 오버로딩(Overloading)
- 이름은 같지만 인자의 개수나 데이터 형이 다른 함수를 여러 번 정의할 수 있는 기능
- 각각의 함수는 인자의 개수나 인자의 데이터 타입이 반드시 달라야함
- 함수 호출 시 전달된 인자의 데이터 타입으로 컴파일러가 어떤 함수를 호출할 지 결정
- 함수 중복 성공 조건
- 중복된 함수들의 이름 동일
- 중복된 함수들의 매개 변수 타입이 다르거나 개수가 달라야함
- 리턴 타입은 오버로딩과 무관
- 장점
- 함수 이름을 구분하여 기억할 필요 X
- 오류 가능성을 줄임
- Ex)
#include <iostream>
using namespace std;
int big(int a, int b)
{ // a와 b 중 큰 수 리턴
if(a>b) return a;
else return b;
}
int big(int a[], int size)
{ // 배열 a[]에서 가장 큰 수 리턴
int res = a[0];
for(int i=1; i<size; i++)
if(res < a[i]) res = a[i];
return res;
}
int main() {
int array[5] = {1, 9, -2, 8, 6};
cout << big(2,3) << endl;
cout << big(array, 5) << endl;
}
4. 함수 템플릿
1) 오버로딩의 코드 중복
- 만약 두 함수가 오버로딩을 통해 선언되었다면 같은 내용의 코드가 2번 선언됨
- 중복을 줄이기 위해 템플릿 사용
2) 일반화와 템플릿
- 일반화(Generic)
- 함수나 클래스를 일반화시키고, 매개 변수 타입을 지정하여 틀에서 찍어내듯이 함수나 클래스 코드를 생산
- 템플릿(Template)
- 함수나 클래스를 일반화하는 도구
- template 키워드로 함수나 클래스 선언
- 변수나 매개 변수의 타입만 다르고, 코드 부분이 동일한 함수를 일반화
- 구체화(Specialization)
- 템플릿 함수로부터 구체화된 함수의 코드 생성
- 암시적 인스턴스와 명시적 인스턴스 두 가지 방
- 장점
- 함수 코드의 재사용
- 높은 소프트웨어 생산성과 유용성
- 함수 코드의 재사용
- 단점
- 포팅에 취약
- 컴파일러에 따라 지원하지 않을 수 있음
- 컴파일 오류 메세지 빈약
- 디버깅에 어려움
- 포팅에 취약
#include <iostream>
using namespace std;
template <class T>
void print(T array[], int n) {
cout << "템플릿" << endl;
for (int i = 0; i < n; i++)
cout << array[i] << '\t';
cout << endl;
}
void print(char array[], int n) { // char 배열을 출력하기 위한 함수 중복
cout << "중복함수" << endl;
for (int i = 0; i < n; i++)
cout << (int)array[i] << '\t'; // array[i]를 int 타입으로 변환하여 정수 출력
cout << endl;
}
int main() {
int x[] = { 1,2,3,4,5 };
double d[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
print(x, 5);
print(d, 5);
char c[5] = { 1,2,3,4,5 };
print(c, 5);
}
- 위의 경우를 보면 char 형 배열에 대한 함수 오버로딩이 선언되어 있다.
- 이때 우선 순위는 중복 함수이다.
'프로그래밍 언어 > C++' 카테고리의 다른 글
5) 생성자와 소멸자 (0) | 2023.11.01 |
---|---|
4) 클래스와 객체의 기본 (1) | 2023.11.01 |
2) 포인터와 레퍼런스 (1) | 2023.11.01 |
1) C++ 프로그래밍의 기본 (2) | 2023.11.01 |
22.05.27) C++ (0) | 2023.01.15 |