[c++] 함수
- 컴퓨터공학과/Programming
- 2013. 10. 9.
returnValueType functionName(list of parameters) // 함수 헤더
{
// 함수 몸체
}
functionName(actual parameter); //함수 호출
- 함수 헤더 + 몸체 : 할 일 정의
- 함수 호출 : 함수 사용
☞ 함수 헤더 : 함수의 반환값 유형(returnValueType), 함수 이름(functionName), 매개변수
☞ 매개변수 : 함수 헤더에 작성된 변수. 함수가 호출될 때 값이 전달되어 저장되는 변수
☞ 실매개변수(인수) : 호출하는 쪽의 매개변수
5. int max(int num1, int num2)
6. {
7. int result;
8. if(num1 > num2)
9. result = num1;
10. else
11. result = num2;
12. return result;
13. }
14. int main()
15. {
16. int I = 5;
17. int j = 2;
18. int k = max(i, j);
19. cout << "the maximum between" << I << "and" << j << " is" << K;
20. // cout << max(i,j);
21. return 0;
22.
>>> the maximum between 5 and 2 is 5
- 함수는 값을 반환한다(o).
- 함수는 반환내용 없이 주어진 일을 처리한다(o). => void함수
☞ 함수 시그니처 : 함수이름, 매개변수
** returnValueType은 함수 시그니처 아님!
- 프로그램에서 함수를 호출하게 되면 프로그램 제어는 호출하는 함수 쪽으로 넘어간다. 호출된 함수에서는 반환 문이 실행되거나 함수의 끝에 도달했을 때 호출자에게 제어를 되돌려준다.
- main도 다른 함수와 마찬가지로 같은 함수이나 프로그램을 시작하기 위해서 운영체제에 의해 호출된다는 점이 다르다.
- 위 코드 프로그램 제어 순서 : 14~18 -> 5~13 -> 19~22
- 19번째와 같이 하나의 변수처럼 사용할 수도 있으며 20번째 줄과 같이 수식에서도 사용 가능하다
- 함수는 호출되기 전에 선언되어야 한다.
=> 함수 호출 전 함수 원형 선언
☞ 함수 원형(prototype): 함수의 구현(몸체)이 없는 선언
- ; 주의
- 함수 원형에서는 매개변수의 이름을 작성할 필요는 없고 매개변수 유형만 있어도 된다.
☞ 스택 : 메모리 영역. LIFO 형태
- 함수가 호출될 때마다 인수와 변수들을 스택 메모리 영역에 저장한다.
- 함수가 다른 함수를 호출하게 되면 현재 함수의 스택 공간은 유지되고, 호출된 함수를 위해 새로운 메모리 공간이 생성된다.
|
|
|
|
☞ void 함수 : 반환 값이 없는 함수
- void 함수의 호출은 하나의 문장으로 작성해야 한다. 즉 수식이나 대입 식에 void함수를 포함시킬 수 없다.
** 매개변수가 있는 함수를 호출할 때 인수 값 전달
♥ Call-by-value
인수가 변수라면 변수의 값이 매개변수로 전달된다. 함수 안에서 매개변수의 값이 변경되더라도 호출한 곳에서 인수로 사용된 변수의 값은 변화가 없다.
void increment(int n) {
n++;
cout << "n inside the function is " << n << endl;
}
int main()
{
int x = 1;
cout << "before the call, x is " << x << endl;
increment(x);
cout << "after the call, x is" << x << endl;
return 0;
}
>>> before the call, x is 1
n inside the function is 2
after the call, x is 1
- 함수 호출 후에도 함수의 값은 변하지 않는데 인수의 값이 매개변수로 전달되었기 때문이다. 이는 매개변수와 인수가 서로 독립적인 공간을 사용하기 때문으로 인수의 값이 변경된다 해도 원 변수의 값은 변화가 없는 것이다.
- x를 n으로 이름을 바꾸면 어떻게 될까?
여전히 두 값의 변경은 이루어지지 않는다. 호출자의 인수와 함수의 매개변수가 같은 이름을 가진다 하더라도, 함수의매개변수는 함수가 호출될 당시에 호출자 인수와는 상관없이 자신만의 메모리 공간을 할당받는다. 이 매개변수를 위한 메모리 공간은 함수의 실행이 끝나고 호출자로 되돌아갈 때 사라지게 된다.
void swap(int n1, int n2)
{
cout << "Inside the swap function" << endl;
cout << "Before swapping n1 is" << n1 << "n2 is" << n2 << endl;
int temp= n1;
n1 = n2;
n2 = temp;
cout << "After swapping n1 is" << n1 << "n2 is " << n2 << endl;
}
int main ()
{
int num1 = 1;
int num2 = 2;
cout << "Before invoking the swap function, num1 is " << num1 <<
"and num2 is " << num2 << endl;
swap(num1, num2);
cout << "After invoking the swap function, num1 is "<< num1 << "and num2 is" << num2 << endl;
return 0;
}
>>> Before invoking the swap function, num1 is 1 and num2 is 2
Inside the swap function
Before swapping n1 is 1 and n2 is 2
After swapping n1 is 2 and n2 is 1
After invoking the swap function, num1 is 1 and num2 is 2
♥ call-by-reference (참조변수)
☞ 참조변수 : 원 변수를 참조하기 위해 함수의 매개변수로 사용되는 변수이다.
- 참조변수는 변수에 대한 별칭으로 동작하여, 참조 변수에 수정을 하면 원 변수에도 수정된 내용이 반영된다.
- 참조변수를 선언할 때는 변수 앞에 엠퍼샌드&를 붙인다.
type &ref_var;
ref_var = orgin_var;
=> type &ref_var = orgin_var;
int main()
{
int count = 1;
int &refCount = count;
refCount++;
cout << " count is " << count << endl;
cout << "refCount is" << refCount << endl;
return 0 ;
}
>>> count is 1
refCount 2
- 함수 매개변수에서도 참조변수를 사용할 수 있으며 호출하는 측에서는 일반 변수를 사용하여 호출하면 된다. 이 때 매개변수는 원 변수에 대한 별칭이 된다.
즉, 다시한번 정리하면 함수에 매개변수를 전달하는 두가지 방법
- Call-by-value, Call-by-reference
- 값에 의한 전달은 독립적인 변수에 값을 복사하는 것이고, 참조에 의한 전달은 같은 변수를 공유하는 것이라고 볼 수 있다.
☞ 함수 오버로딩 : 하나의 파일 안에 이름은 같고 매개변수 목록만 다른 함수 여러 개 사용
- 함수 오버로딩은 프로그램을 보다 간결하게 하고 읽기 쉽게 한다.
- 함수 호출 시 가장 가까운 함수를 찾음
max(3,4) -> max(int, int) > max(double, double)
max(1,2) ? max(int, double), max(double, int) => 모호한 호출 에러
** 이름이 같되, 매개변수 목록이 달라야 한다. (반환 유형이 다른 경우는 상관없음)
- 기본 인수 값으로 함수를 선언할 수 있는데, 인수 없이 함수를 호출하면 기본 값이 매개변수로 전달된다.
- 함수의 장점 중 하나는 다른 프로그램에서 함수 재사용이 가능하다는 것이다.
- #include 전처리 지시자를 사용하여 함수를 포함한 프로그램의 헤더 파일을 포함시키면 된다.
- 헤더 파일에서 main 함수를 작성하지 말아야 한다.
#: 컴파일하기 전에 ~부터 하라.
#include <iostream>
#include "myLib.h"
iostream -> 표준 헤더 파일
myLib.h -> 사용자 정의 헤더 파일
☞ 변수의 범위 : 프로그램에서 변수가 어떤 범위까지 참조되는 것인지에 관한 것
☞ 지역변수 : 함수 안에 선언된 변수
☞ 전역변수 : 함수 외부에서 선언되어 파일 내 모든 함수에서 접근이 가능한 변수
- 변수는 사용하기 전에 먼저 선언되어 있어야 한다.
- 지역변수는 기본 값이 없지만, 전역 변수는 기본 값이 0으로 설정된다.
- 지역변수의 범위는 선언한 지점으로부터 해당 블록이 끝날 때까지이다. 전역 변수의 범위는 변수 선언한 지점으로부터 프로그램이 끝날 때까지이다.
- 전역변수의 범위는 변수 선언한 지점으로부터 프로그램이 끝날 때까지이다.
- 매개변수는 => 지역변수
int main() {
t1();
t2();
return 0;
}
int y; // 전역변수, 초기값 0
void t1() {
int x = 1; // 지역변수
cout << x <<" " << y << endl;
x++; y++;
}
void t2() {
int x = 1;
cout << x <<" " << y << endl;
}
>>> 1 0
1 1
- t1()의 x와 t2()의 x는 이름만 같은 것이지 실제로 다른 메모리 영역에 저장되어 있기 때문에 서로 다른 변수이다. (t1의 x의 값의 변경이 t2의 x에 아무런 영향을 미치지 않음)
- 지역 변수의 이름과 전역 변수의 이름이 동일한 경우, 함수 내에서는 지역 변수의 이름만 접근할 수 있다.
-> 이 경우, 함수 내에서 전역 변수에 접근하고자 하는 경우에는 ::전역변수 를 사용하여 전역변수에 접근할 수 있다.
☞ 정적 지역 변수 : 함수 실행이 완료되어도 사라지지 않는 지역변수
- 지역 변수를 사용하기 위해 지역변수에 저장된 값을 유지하고자 할 때 사용
- 프로그램이 끝날 때까지 메모리가 사라지지 않고 계속 유지된다.
- static 키워드 사용.
void t1() {
stiatic int x = 1;
int y = 1;
x++; y++;
cout << x << " " << y << endl;
}
- 함수를 사용하면 프로그램이 읽기 쉽고 유지보수도 좋아진다.
- 그러나 함수 호출은 실행 오버헤드(인수전달, cpu 레지스터를 스택으로 이동, 함수간의 제어 전달, context switch overhead 등)가 발생
☞ 인라인 함수 : 함수처럼 호출되는 것이 아니라 컴파일러에 의해 인라인 함수를 호출하는 지점으로 함수 내용을 복사하는 방식
- 함수 선언 앞에 inline 키워드 사용
- c++ 컴파일러가 인라인 함수를 호출하는 지점에 인라인 함수를 복사해 넣어 코드를 확장하는 것이다.
- 함수의 길이가 짧은 경우에만 적합, 여러 곳에서 호출되는 큰 함수의 경우 부적합
-> 인라인 함수로 처리할지 무시할지의 결정은 컴파일러에게 달려있다.
'컴퓨터공학과 > Programming' 카테고리의 다른 글
[c++] 포인터 (0) | 2013.11.29 |
---|---|
[Android] 초보자도 할 수 있다! 안드로이드 자동 가위바위보 게임앱 만들기! (7) | 2013.10.09 |
[JSP] 개발환경구축 - ⑤ JSP 프로그래밍 (0) | 2012.07.15 |
[JSP] 개발환경구축 - ④ Tomcat - Eclipse 연동 (0) | 2012.07.15 |
[JSP] 개발환경구축 - ③ Eclipse 설치 (0) | 2012.07.15 |