프로그래밍 언어/C++

3) 개선된 함수 기능

busy맨 2023. 11. 1. 20:39

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(); // 인자 모두를 생략함

디폴트 인자 예시
result

3. 함수 중복(오버로딩)

  • 함수 오버로딩(Overloading)
    • 이름은 같지만 인자의 개수나 데이터 형이 다른 함수를 여러 번 정의할 수 있는 기능
    • 각각의 함수는 인자의 개수나 인자의 데이터 타입이 반드시 달라야함
    • 함수 호출 시 전달된 인자의 데이터 타입으로 컴파일러가 어떤 함수를 호출할 지 결정
  • 함수 중복 성공 조건
    1. 중복된 함수들의 이름 동일
    2. 중복된 함수들의 매개 변수 타입이 다르거나 개수가 달라야함
    3. 리턴 타입은 오버로딩과 무관

주의 사항 1
주의 사항 2

  •  장점
    • 함수 이름을 구분하여 기억할 필요 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;
}

result

 

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