블록은 단일 명령문이 허용되는 모든 위치에서 사용할 수 있고, 블록 끝에는 세미콜론(;)이 필요하지 않다.
int add(int x, int y)
{ // 시작 블록 (start a block)
return x + y;
} // 끝 블록 (end a block)
int main()
{ // start a block
// 여러 명령문 (multiple statements)
int value(0);
add(3, 4);
return 0;
} // end a block (no semicolon)
블록은 다른 블록 내부에 중첩될 수 있다.
#include <iostream>
int main()
{
std::cout << "Enter an integer: ";
int value;
std::cin >> value;
if (value >= 0)
{ // start of nested block
std::cout << value << " is a positive integer (or zero)" << std::endl;
std::cout << "Double this number is " << value * 2 << std::endl;
} // end of nested block
else
{ // start of another nested block
std::cout << value << " is a negative integer" << std::endl;
std::cout << "The positive of this number is " << -value << std::endl;
} // end of another nested block
return 0;
}
중첩된 블록(nested block) 수에는 제한이 없다.
int main()
{
std::cout << "Enter an integer: ";
int value;
std::cin >> value;
if (value > 0)
{
if ((value % 2) == 0)
{
std::cout << value << " is positive and even" << std::endl;
}
else
{
std::cout << value << " is positive and odd" << std::endl;
}
}
return 0;
}
지역변수 스코프와 주기
변수의 스코프(scope)에 따라 변수에 접근할 수 있는 위치가 결정된다.
변수의 주기(duration)는 변수가 생성되고 소멸하는 위치를 결정한다.
이 두 개념은 밀접하게 관련돼있다.
함수 내부에 정의된 변수를 지역 변수라고 한다.
지역 변수는 자동 주기(auto duration)을 가지고 있다.
정의되는 시점에 생성되고 초기화되며, 정의된 블록이 끝나는 지점에서 소멸한다.
지역 변수를 지역 스코프(블록 스코프)를 갖는다.
지역 변수의 지역 스코프(블록 스코프) 내에서만 해당 지역 변수에 접근할 수 없다.
int main()
{
int i(5); // i created and initialized here
double d(4.0); // d created and initialized here
return 0;
} // i and d go out of scope and are destroyed here
변수 i와 d는 main() 함수 내부에서 정의되었기 때문에 main() 함수의 실행이 완료되면 모두 소멸한다.
중첩된 블록(nested block) 내부에 정의된 변수는 중첩된 블록이 끝나는 즉시 소멸한다.
int main() // outer block
{
int n(5); // n created and initialized here
{ // begin nested block
double d(4.0); // d created and initialized here
} // d goes out of scope and is destroyed here
// d can not be used here because it was already destroyed!
return 0;
} // n goes out of scope and is destroyed here
블록 내부에 정의된 변수는 해당 블록에서만 접근할 수 있다. 각 함수는 자체 블록을 가지고 있으므로 한 함수의 변수를 다른 함수에서 볼 수 없다.
void someFunction()
{
int value(4); // value defined here
// value can be seen and used here
} // value goes out of scope and is destroyed here
int main()
{
// value can not be seen or used inside this function.
someFunction();
// value still can not be seen or used inside this function.
return 0;
}
중첩된 블록은 외부 블록의 일부로 간주한다. 따라서 외부 블록에서 정의된 변수를 중첩된 블록 내부에서 접근할 수 있다.
#include <iostream>
int main()
{ // start outer block
int x(5);
{ // start nested block
int y(7);
// we can see both x and y from here
std::cout << x << " + " << y << " = " << x + y;
} // y destroyed here
// y can not be used here because it was already destroyed!
return 0;
} // x is destroyed here
쉐도잉
중첩된 블록 내부의 변수는 외부 블록과 같은 이름을 가질 수 있다. 이 경우 외부 블록의 같은 이름의 변수는 잠시 가려지는데 이것을 쉐도잉(shadowing) 또는 숨기기(hide)라고 부른다.
#include <iostream>
int main()
{ // outer block
int apples(5); // here's the outer block apples
if (apples >= 5) // refers to outer block apples
{ // nested block
int apples; // hides previous variable named apples
// apples now refers to the nested block apples
// the outer block apples is temporarily hidden
apples = 10; // this assigns value 10 to nested block apples, not outer
block apples
std::cout << apples << '\n'; // print value of nested block apples
} // nested block apples destroyed
// apples now refers to the outer block apples again
std::cout << apples << '\n'; // prints value of outer block apples
return 0;
} // outer block apples destroyed
If you run this program, it prints:
10
5
위 프로그램에서 중첩된 블록 내부의 변수 apple은 외부 블록 apple을 숨긴다. 중첩된 블록이 끝나면 중첩된 블록 내부 변수 apple 은 소멸하고 다시 외부 블록 apple에 접근할 수 있게 된다.
만약 중첩된 블록 내부에서 변수 apple을 정의하지 않으면 외부 블록 변수 apple에 접근하여 값 10을 할당한다.
#include <iostream>
int main()
{ // outer block
int apples(5); // here's the outer block apples
if (apples >= 5) // refers to outer block apples
{ // nested block
// no inner block apples defined
apples = 10; // this now applies to outer block apples, even though we're
// in an inner block
std::cout << apples << '\n'; // print value of outer block apples
} // outer block apples retains its value even after we leave the nested block
std::cout << apples << '\n'; // prints value of outer block apples
return 0;
} // outer block apples destroyed
If you run this program, it prints:
10
10
변수는 가능한 한 제한된 스코프(=범위) 안에서 정의되는게 좋다. 예를 들어, 변수가 중첩된 블록 내에서만 사용되는 경우, 해당 중첩된 블록 내에서 정의되도록 하자.
함수 매개 변수
함수 매개 변수는 함수가 속하는 블록 내에서 정의되지는 않았지만 대부분 블록 스코프를 가진 것으로 간주할 수 있다.
int max(int x, int y) // 변수 x와 y는 함수 매개 변수에서 정의되었다.
{
// 매개변수는 블록 스코프를 가진것으로 간주되므로 블록 내부에서 접근가능하다.
// x와 y중 더 큰 값을 변수 max에 할당한다.
int max = (x > y) ? x : y;
return max;
} // 변수 x와 y는 여기서 소멸된다.
전역 변수와 링크
함수 내부에서 정의된 변수를 지역 변수라고 한다. 지역 변수는 블록 스코프(정의된 블록 내에서만 접근 가능)를 갖고 자동 주기(정의 시점에서 생성, 블록이 종료되면 소멸)를 갖는다.
함수 외부에서 선언된 변수를 전역 변수라고 한다. 전역 변수는 정적 주기(static duration)로, 프로그램이 시작할 때 생성되고 프로그램이 종료될 때 파괴된다.
전역 변수는 파일 스코프(전역 스코프)를 갖는다.
전역 변수는 정의된 시점부터 소스 파일의 끝까지 접근 가능하다는 것이다.
전역 변수 정의
#include <iostream>
// 함수 외부에서 정의된 변수는 전역 변수(global variable)다.
int g_x; // global variable g_x
const int g_y(2); // global variable g_y
void doSomething()
{
// 전역 변수가 정의된 이후, 프로그램 어디에서든지 접근 가능하다.
std::cout << g_y << "\n";
}
int main()
{
doSomething();
// 전역 변수가 정의된 이후, 프로그램 어디에서든지 접근 가능하다.
g_x = 5;
std::cout << g_y << "\n";
return 0;
}
중첩된 블록(nested block)이 이름이 같은 외부 블록의 변수를 숨기는 것처럼, 전역 변수와 같은 이름을 가진 지역 변수는 전역 변수를 숨긴다.
그러나 전역 범위 연산자(: :)를 사용하면 컴파일러는 지역 변수 대신 전역 변수를 사용한다.
#include <iostream>
int value(5); // 전역 변수
int main()
{
int value = 7; // 전역 변수를 숨긴다. (shadowing or hide)
value++; // 지역 변수를 증가시킨다.
::value--; // 전역 변수를 감소시킨다.
std::cout << "global value: " << ::value << "\n";
std::cout << "local value: " << value << "\n";
return 0;
} // 지역 변수 value는 소멸된다.
This code prints:
global value: 4
local value: 8
그러나 전역 변수와 같은 지역 변수를 정의하는 건 피해야 한다. 관습에 따라 일반적으로 전역 변수를 정의할 때는 g_ 접두사를 붙인다.
이 방법은 전역 변수를 식별하는데 편리할 뿐만 아니라 지역 변수와 충돌을 방지하는 데 도움이 된다.
static과 extern 키워드를 이용한 내부/외부 링크
변수는 스코프와 주기 외에도 링크라는 속성을 갖는다.
링크는 같은 이름의 여러 식별자가 같은 식별자를 참조하는지를 결정한다.
// Uninitialized definition:
int g_x; // defines uninitialized global variable (external linkage)
static int g_x; // defines uninitialized static variable (internal linkage)
const int g_x; // not allowed: const variables must be initialized
// Forward declaration via extern keyword:
extern int g_z; // forward declaration for global variable defined elsewhere
extern const int g_z; // forward declaration for const global variable defined elsewhere
// Initialized definition:
int g_y(1); // defines initialized global variable (external linkage)
static int g_y(1); // defines initialized static variable (internal linkage)
const int g_y(1); // defines initialized static variable (internal linkage)
// Initialized definition w/extern keyword:
extern int g_w(1); // defines initialized global variable (external linkage, extern keyword is redundant in this case)
extern const int g_w(1); // defines initialized const global variable (external linkage)
링크가 없는 변수는 정의된 제한된 범위에서만 참조할 수 있다.
지역 변수가 링크가 없는 변수의 예이다.
이름은 같지만 다른 함수(블록)에서 정의된 지역 변수는 링크가 없다.
각 지역 변수는 독립적이다.
내부 링크가 있는 변수를 static 변수라고 한다.
static 변수는 변수가 정의된 소스 파일 내에서 어디서나 접근할 수 있지만, 소스 파일 외부에선 참조할 수 없다.
static int g_x; // g_x is static, and can only be used within this file
int main()
{
return 0;
}
외부 링크가 있는 변수를 extern 변수라고 한다. extern 변수는 정의된 소스 파일과 다른 소스 파일 모두에서 접근할 수 있다.
extern double g_y(9.8); // g_y is external, and can be used by other files
// Note: those other files will need to use a `forward declaration` to access this // external variable
// We'll discuss this in the next section
int main()
{
return 0;
}
기본적으로 전역 변수는 extern 변수로 간주한다. 그러나 상수(const) 전역 변수는 static 변수로 간주한다.
extern 키워드를 통한 변수 전방 선언
다른 소스 파일에서 선언된 외부 전역 변수를 사용하려면 '변수 전방 선언(variable forward declarations)'을 해야 한다.
extern 키워드는 두 가지 다른 의미가 있다. 어떤 상황에서는 extern 키워드가 외부 링크가 있는 변수를 의미하고 다른 상황에서는 다른 어딘가에서 정의된 변수에 대한 전방 선언을 의미한다.
// global.cpp
// 두 개의 전역 변수를 정의한다.
// non-const globals have external linkage by default
int g_x; // external linkage by default
extern int g_y(2); // external linkage by default, so this extern is redundant and
// ignored
// in this file, g_x and g_y can be used anywhere beyond this point
만약 변수 전방 선언이 함수 외부에서 선언되면 소스 파일 전체에 적용된다. 함수 내에서 선언되면 해당 블록 내에서만 적용된다.
// main.cpp
#include <iostream>
#include "global.cpp"
extern int g_x; // forward declaration for g_x (defined in global.cpp) -- g_x can
// now be used beyond this point in this file
int main()
{
extern int g_y; // forward declaration for g_y (defined in global.cpp) -- g_y
// can be used beyond this point in main() only
g_x = 5;
std::cout << g_y; // should print 2
return 0;
}
변수가 static으로 선언된 경우, 이에 접근하기 위해 변수 전방 선언을 해도 적용되지 않는다.
// main.cpp
#include <iostream>
#include "constant.cpp"
extern const double g_gravity; // This will satisfy the compiler that g_gravity
// exists
int main()
{
std:: cout << g_gravity; // This will cause a linker error because the only
// definition of g_gravity is inaccessible from here
return 0;
}
함수 링크
함수는 변수와 같은 링크 속성을 갖는다.
함수는 항상 외부 링크로 기본 설정(extern이 default)되지만 static 키워드를 통해 내부 링크로 설정할 수도 있다.
// This function is declared as static, and can now be used only within this file
// Attempts to access it via a function prototype will fail
static int add(int x, int y)
{
return x + y;
}
함수 전방 선언에는 extern 키워드가 필요하지 않다. 컴파일러는 함수 몸체인지 원형인지 알아서 판단한다.
전역 변수가 나쁜 이유
non-const 전역 변수가 나쁜 이유: 호출되는 함수에 의해서 값이 예상치 못한 값으로 변경될 수 있기 때문이다.
// 전역 변수 선언
int g_mode;
void doSomething()
{
g_mode = 2; // 전역 변수 g_mode의 값을 2로 설정한다.
}
int main()
{
g_mode = 1; // 지역 변수 g_mode가 없기 때문에 전역 변수 g_mode의 값을 1로 설정한다.
doSomething();
// 프로그래머는 전역 변수 g_mode의 값이 1이라고 생각할 수 있다.
// 그러나 doSomething() 함수가 g_mode 값을 2로 바꾸었다.
if (g_mode == 1)
std::cout << "No threat detected.\n";
else
std::cout << "Launching nuclear missiles...\n";
return 0;
}
정적 변수(static)
static 키워드는 전역 변수 뿐만 아니라 블록 내에 선언된 지역 변수에서도 사용할 수 있다.
지역 변수는 '자동 주기(auto duration)'를 가지며, 정의되는 시점에서 생성되고 초기화되며, 정의된 블록이 끝나는 지점에서 소멸한다.
static 키워드를 사용한 지역 변수는 전혀 다른 의미를 갖는다.
static 키워드를 사용한 지역 변수는 '자동 주기'에서 '정적 주기'를 갖는다.
이것을 정적 변수(static variable)라고도 부르는데, 생성된 스코프(=범위)가 종료한 이후에도 해당 값을 유지하는 변수다.
스코프가 종료된 이후에도 값은 유지되지만, 그렇다고 해서 스코프 밖에서 접근 가능한 것은 아니다. 왜냐하면 정적 변수도 결국엔 지역 변수이기 때문이다.
또한, 정적 변수는 한 번만 초기화되며 프로그램 수명 내내 지속된다.
지역 변수와 정적 변수의 차이 예제
#include <iostream>
void incrementAndPrint()
{
int value = 1; // 기본적으로 '자동 생명 주기'
++value;
std::cout << value << '\n';
} // value는 여기서 소멸된다.
int main()
{
incrementAndPrint();
incrementAndPrint();
incrementAndPrint();
}
program outputs:
2
2
2
#include <iostream>
void incrementAndPrint()
{
static int s_value = 1; // 'static' 키워드를 사용한 '정적 생명 주기', 이 줄은 한번
// 만 실행된다.
++s_value;
std::cout << s_value << '\n';
} // s_value가 여기서 소멸되지는 않지만 이 스코프 밖에서
// s_value에 접근할 수 있는 것은 아니다.
int main()
{
incrementAndPrint();
incrementAndPrint();
incrementAndPrint();
}
program outputs:
2
3
4
스코프, 주기, 링크 요약
변수의 스코프, 주기, 링크
변수와 함수 전방 선언
2. 함수
함수의 선언과 정의
함수의 형식
ReturnType functionName(fParameterList) // 머리부(header)
{ // 몸체 블록(body block)
Type1 localVar1; // 지역변수 선언
Type2 localVar2;
...
statement1; // 처리할 작업을 수행하는 문장
statement2;
...
return returnExpression; // 결괏값을 반환
}
fParameterList는 함수를 호출하는 루틴이 전달하는 값(인수)들을 받을 매개변수들의 자료형과 이름을 나열해놓은 것으로, 이것을 형식 매개변수라고 한다.
함수 안에 선언한 변수를 지역변수라고 한다.
형식 매개변수와 함수 안에 지역변수는 그 함수 내에서만 사용할 수 있다.
지역변수는 함수의 첫머리에 선언하는 것이 일반적이지만 C++에서는 사용되는 곳의 앞이면 함수의 어느 위치에서든 선언하여도 된다.
함수 바깥에 선언한 변수는 프로그램의 모든 영역에서 사용할 수 있다. => 전역변수
반환할 값의 자료형을 함수의 첫머리에 지정하여야 한다.
returnExpression은 ReturnType으로 암사적 형 변환이 가능한 자료형의 수식을 사용해야 한다.
return 명령은 함수의 처리를 마치려고 할 때 언제든 사용할 수 있으며, 한 함수 내에서 여러 개의 return 명령을 사용할 수 있다.
값을 반환할 필요가 없는 함수를 만들 때는 ReturnType을 void형으로 지정, 함수의 마지막에 return 문을 써주지 않아도 되며, 필요하다면 return 명령으로 언제든 함수를 종료하고 복귀할 수 있다. 이런 경우 return 명령은 returnExpression 없이 사용된다.
함수의 위치
함수는 호출되는 영역보다 먼저 앞의 위치에서 선언 및 정의돼 있어야 한다.
#include <iostream>
int add(int x, int y)
{
return x + y;
}
int main()
{
std::cout << "The sum of 3 and 4 is: " << add(3, 4) << std::endl;
return 0;
}
함수의 전방 선언
전방 선언(forward declaration)은 실제로 식별자를 정의하기 전제 식별자의 존재를 컴파일러에 미리 알리는 것이다.
함수의 경우, 함수의 몸체를 정의하기 전에 함수의 존재에 대해 컴파일러에 미리 알리는 것을 말한다.
이 방법으로 컴파일러가 함수를 호출할 때 함수가 정의된 방법이나 위치를 아직 모를 때에도 함수를 호출한다는 것을 이해시킬 수 있다.
함수의 전방 선언을 하려면 함수 원형(prototype)이라고 하는 선언문(declaration statement)을 사용해야 한다.
함수가 전방 선언되면 함수 몸체의 정의는 해당 함수가 호출되는 영역 이후에 위치할 수 있게 된다.
함수 원형은 리턴 타입, 이름 그리고 매개 변수로 구성되지만, 함수 몸체({} 사이의 부분)는 포함하지 않는다. 함수 원형은 명령문(statement)이므로 세미콜론(;)으로 끝나야 한다.
함수 원형 형식
ReturnType functionName(fParameterList);
,함수 원형(선언문)을 이용한 함수 전방 선언
#include <iostream>
int add(int x, int y); // add() 함수의 전방 선언(함수 원형)
int main()
{
std::cout << "The sum of 3 and 4 is: " << add(3, 4) << std::endl;
return 0;
}
int add(int x, int y)
{
return x + y;
}
// The sum of 3 and 4 is: 7
함수 원형에서 매개 변수의 이름을 지정하지 않고 선언할 수 있다.
int add(int, int); // 매개변수의 이름을 생략 가능하다.
선언 vs 정의
선언(declaration)은 식별자(변수 또는 함수 이름) 및 해당 타입의 존재를 컴파일러에 알려주는 명령문(statement)이다.
// 컴파일러에게 두 개의 int 매개 변수를 사용하고
// int를 반환하는 "add"라는 이름의 함수를 알려준다.
int add(int x, int y);
int x; // x라는 정수형 변수를 컴파일러에게 알려준다.
선언하지 않고 식별자를 사용하면 컾파일러에서 오류가 발생한다.
정의는 식별자를 실제로 구현하거나, 인스턴스화 한다.
링커를 만족하기 위해서는 정의가 필요하다.
int add(int x, int y) // add() 함수를 구현한다.
{
return x + y;
}
int x = 10; // x라는 정수형 변수를 인스턴스화(메모리 할당)
의미있는 작업 단위로 모듈화하여 프로그램을 분할 작성함으로써, 간결하고 이해하기 쉬운 프로그램을 만들 수 있다.
여러 곳에서 반복 사용되는 기능을 함수로 정의하면, 동일 코드를 중복 작성하지 않아도 된다.
잘 설계하면 만든 함수는 그 기능이 필요한 여러 가지 다른 응용에서 재사용하기 좋다
단점
함수를 사용하면 함수 호출과 복귀 과정에서 처리 시간이 추가된다.(inline 함수로 보완 가능)
인수의 전달
값 호출
값 호출은 실 매개변수의 값을 형식 매개변수에 복사하여 주는 방식이다.
함수 내에서 형식 매개변수의 값을 변경하더라도 실 매개변수의 값은 영향받지 않는다.
참조 호출
값 호출과 달리 참조 호출은 실 매개변수의 참조, 즉 주소를 전달한다.
이에 따라 형식 매개 변수는 전달되는 실 매개변수의 별명처럼 사용된다.
C++ 언어에서는 포인터 대신 참조형을 사용할 수 있다.
#include <iostream>
using namespace std;
void SwapValues(int &x, int &y); // 원형(함수 전방 선언)
int main() {
int a, b;
cout << "두 수를 입력하시오 : ";
cin >> a >> b;
if(a < b) SwapValues(a, b);
cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
return 0;
}
// 함수 정의
void SwapValues(int &x, int &y) {
int temp = x;
x = y;
y = temp;
}
두 수를 입력하시요 : 50 100
큰 수 = 100 작은 수 = 50
참조변수는 포인터와 같이 다른 대상을 참조하는 것이므로 자료형이 일치해야 한다.
const 매개변수
참조 호출을 하거나 매개변수가 포인터인 경우 함수 내에서 호출 루틴의 실 매개변수를 수정할 수 있다.
그러나 이러한 방식의 호출을 했다고 해도 실 매개변수의 값을 보호하고 싶을 때에는 해당 형식의 매개 변수를 const로 지정하면 된다.
const로 지정한 매개변수는 데이터의 크기가 큰 인수를 전달할 때 유용하게 사용할 수 있다.
만약 크기가 큰 인수를 값 호출 방식으로 전달하면 이를 복사하기 위해 많은 시간이 소비되며 메모리도 많이 소비된다.
이런 경우에는 참조 호출을 이용하는 것이 바람직하다.
그러나 참조 호출을 하면 호출한 루틴에서 전달한 인수가 함수를 실행한 후 원래의 값을 유지하고 있다는 것을 보장받지 못한다.
이 때 실 매개변수의 값이 변경되지 않을 보장하기 위해 함수의 매개변수에 const를 지정할 수 있다.
2개 이상의 디폴트 인수가 있을 때, 뒤의 인수는 디폴트 값이 아닌 다른 값을 전달하고 싶다면
앞의 인수는 디폴트 값을 사용한다 할지라도 값을 명시적으로 지정해줘야 한다.
void f(int x, int y = 10, int z = 20);
void g(int x, int y = 10, int z); // Error - 디폴트 인수는 반드시 인수 리스트의 끝에
f(5);
f(5, 100);
f(5, 100, 200);
f(5, , 300); // Error
f(5, 10, 300); // OK
함수의 다중 정의
다중정의(overloading)란 동일한 이름에 대하여 여러가지 의미를 부여하는 것이다.
동일한 이름을 갖는 함수를 여러 개 정의할 수 있다.
함수를 다중정의하는 것은 동일한 개념의 처리를 다양한 데이터나 객체에 대해 해야 할 경우 쓰인다.
함수를 다중정의한 경우, 사용되는 함수가 같은 이름을 가지고 있는 여러 함수 중에서 어느 함수를 의미하는가를 구분할 수 있어야 한다.
구분의 기준은 인수의 개수 및 인수의 자료형이다.
함수의 다중 정의는 명확하게 구분하여 호출할 수 있게 해야 한다.
int g(int a)
{...}
int g(int a, int b = 100)
{...}
g(10) // 어떤 함수 g를 호출하는 것인지 불분명
int h(int a)
{...}
int h(float a)
{...}
h(10.0) // 어떤 함수 h를 호출하는 것인지 불분명
inline 함수
함수를 호출하는 과정에는 인수를 전달하고, 함수의 위치로 분기하며, 결과를 반환하고, 호출한 위치로 돌아오는 과정이 수반된다.
이에 따른 처리시간 및 코드의 증가는 비록 미미한 것이지만, 때로는 매우 빠른 처리가 필요하여 불필요한 시간 지연을 피하고 싶을 때가 있다.
특히 모듈의 크기가 매우 작아 모듈을 실행하는 시간이나 모듈 크기가 함수 호출에 따른 부수적인 시간 및 코드의 양과 큰 차이가 없고, 이 모듈을 매우 빈번히 호출한다면 함수를 사용하지 않는 것이 더 바람직할 수 있다.
inline 함수는 함수가 가지는 모듈화의 장점을 살리면서 이러한 불필요한 실행 효율 저하를 막기위해 사용할 수 있다.
inline 함수를 작성하는 것은 inline 키워드를 사용하는 것외에는 일반 함수와 동일하다.
그러나 컴파일러가 번역할 때에는 일반 함수와는 달리 함수의 처리 문장이 호출되는 위치에 직접 삽입된다.
이렇게 번역하면 함수 호출 명령이 생략되어 호출에 따른 부수적 동작이 생략된다.\
inline 함수를 사용하면 원시 프로그램은 함수를 사용한 간결하고 이해하기 쉬운 형태를 그대로 유지하면서 함수 호출에 따른 실행 효율 저하는 발생하지 않는다.
#include <iostream>
using namespace std;
inline void SwapValues(int &x, int &y) {
int temp = x;
x = y;
y = temp;
}
int main() {
int a, b;
cout << "두 수를 입력하시오 : ";
cin >> a >> b;
if(a < b) SwapValues(a, b);
cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
return 0;
}
inline으로 함수를 선언하더라도 그 함수가 반드시 inline으로 번역된다는 것은 아니다.