2024. 3. 3. 16:48ㆍProgramming Language/C++
아래 링크 클릭 시 해당 본문으로 이동
함수 선언 또는 정의 없이 함수를 호출하면 발생하는 문제
함수
• 각각의 기능들을 함수라고 한다.
• 함수 표현하는 법 : `함수명()`
• 기능의 모듈화 : 밑에서부터 천천히 쌓아 올라가는 것
작은 별도의 기능부터 큰 기능까지 만들 때, 모듈화 하는 습관을 가져야 한다.
• 함수는 여러 번 호출할 수 있다.
함수가 여러 번 호출될 때마다 함수가 사용할 만큼의 메모리 영역을 잡고 해제하며, 결과를 반환하고 함수가 종료되는 과정이 반복된다.
`main()`
• 프로그램을 실행시킨다. = 프로그램의 가장 첫 번째 함수인 `main()`를 호출한다.
`return`
• 해당 함수의 종료를 의미하며, 함수를 호출한 곳으로 돌아가서 결괏값을 반환한다.
`return 상수(또는 변수);` : 해당 함수를 호출한 곳으로 돌아가서 상수(또는 변수)의 값을 반환해 준다.
`return 0;`의 의미
• 현재 실행 중인 함수를 끝낼 때 0을 리턴하면 해당 함수를 오류 없이 성공적으로 끝냈다는 의미이다.
`int main()`는 int를 반환하는 함수이기 때문에 정수형을 리턴해주지 않으면 오류가 발생한다.
`main()`뿐만 아니라 다른 함수들도 마찬가지로 함수명 앞에 있는 자료형에 맞는 값을 반환해야 한다.
▶ 프로그램 종료 과정
int main()
{
return 0;
}
① `return 0;` : 오류 없이 프로그램이 성공적으로 완료되었다는 것을 OS에 전달한다.
② `main()` 내부의 모든 로컬/전역/정적 변수를 정리한다.
③ 프로그램은 '0'을 종료 상태로 OS에 전송하여 성공적으로 완료했음을 확인한다.
• 종료 상태
컴퓨터 프로그래밍에서 특정 프로시저나 위임된 작업의 실행이 끝났을 때의 상태
• 프로시저(procedure)
특정 작업을 실행하기 위한 절차
④ OS는 프로그램에서 사용하던 남은 메모리나 리소스를 회수하여 정리한다.(ex. 열린 파일 또는 할당된 메모리 등)
⑤ 프로그램이 완전히 종료되고 OS는 다른 프로세스를 실행할 준비가 된다.
void
• 함수에 반환(return) 타입이 없을 때 사용
void = 아무것도 없다.
int gi = 0;
void Test()
{
++gi;
// return이 없다. (반환 타입이 없다.)
}
int main()
{
Test();
int a = gi;
return 0;
}
함수 동작 방식
`main()` 처음 부분에 중단점을 걸어놓았다.
중단점을 걸어놓은 구문은 아직 실행 전이다.
참고 링크
• 디버깅, 로컬, 중단점
Q. `main()`가 아직 실행되기 전인데 어떻게 로컬 창에 변수 공간이 생성되었을까?
A. `main()` 초반에 중단점을 걸어놔서 아직 실행되기 전이지만, 그래도 `main()`이 호출됐기 때문에 `main()`에 있는 모든 변수들의 존재를 알 수 있다.
즉, `main()`가 호출되면 사용할 변수들을 얼마만큼 사용할지 미리 파악하기 때문에 로컬 창에 변수 공간이 생성된 것이다.
100byte의 공간이 필요하다면 `main()`가 그만큼의 메모리를 확보해 놓는다.
(ex. 편의점에 가기 전에 음료수 3000원, 라면 2000원을 사기 위해 5000원을 준비하는 경우)
`main()`뿐만 아니라 모든 함수들의 특징이다.
함수가 호출되면 해당 함수 안에 있는 변수들의 존재를 알 수 있다.
▷ 예시
// 메모리 크키 : 4byte + 4byte = 8byte
int Add()
{
int a; // 4byte
int b; // 4byte
return a + b;
}
다른 지역 같은 변수명
▷ 예시
// 정수형 인자 2개를 전달받아 더한 후 Add()를 호출했던 곳(main())에 값을 반환한 뒤에 종료된다.
int Add(int a, int b)
{
a; // Add() 지역에 있는 변수
return a + b; // Add(100, 200) : 100 + 200 = 300
// Add(600, 50) : 600 + 50 = 650
}
int main()
{
int data = Add(100, 200); // 300
data = Add(600, 50); // 650
int a = 70; // main() 지역에 있는 변수
a; // 70 // main() 지역에 있는 변수
return 0;
}
`Add()`에 있는 `a`와 `main()`에 있는 `a`는 서로 다른 변수이다.
각각의 변수가 위치하는 함수 지역(`Add()`, `main()`)에 속해있는 변수이다.
∴ 둘의 함수 영역이 완전 다르기 때문에 변수명을 똑같이 써도 문제가 없다.
함수 선언 또는 정의 없이 함수를 호출하면 발생하는 문제
코드를 작성하다 보면 함수를 `main()` 아래쪽에 모아서 정리해놓기도 하는데, 이때 함수를 선언 또는 정의하지 않으면 발생하는 문제에 대해 알아보자.
▷ `main()`에서 함수가 호출되기 전에 함수를 정의하지 않은 경우
• 컴파일 에러가 발생한다.
코드 검사는 위에서부터 순차적으로 진행되는데, `main()`에서 함수를 호출하기 전에 함수를 선언 및 정의하지 않으면 함수의 실체가 없으므로 컴파일 에러가 발생한다.
int gInt = 0;
int main()
{
Test(); // 컴파일 시 오류 발생
Test();
Test();
int a = gInt;
return 0;
}
// 함수 정의
void Test()
{
++gInt;
}
▷ `main()` 위에 함수 선언만 하고 정의는 하지 않은 경우
• 링킹 에러가 발생한다.
`Test()`를 선언은 했기 때문에 컴파일러가 `Test()`는 나중에 정의되어 있을 거라고 생각하여 컴파일 오류는 발생하지 않는다.
대신, `Test()`를 정의하지 않았기 때문에 파일 및 코드들을 연결(link)해 주는 링킹 단계에서 오류가 발생한다.
int gInt = 0;
void Test(); // Test() 선언
int main()
{
Test();
Test();
Test();
int a = gInt;
return 0;
}
오류 코드 : C와 LNK의 의미
ⓐ 컴파일 단계 오류
Compile(컴파일) ➜ C
ⓑ 링킹 단계 오류
Linking(링킹) ➜ LNK
'Programming Language > C++' 카테고리의 다른 글
[C++] 반복문, 반복문 탈출 방법 (0) | 2024.03.03 |
---|---|
[C++] 입출력 (printf(), scanf(), cout, cin) (0) | 2024.03.03 |
[C++] 메모리 영역, 변수 (0) | 2024.03.02 |
[C++] 조건문(Conditional Statements), 삼항 연산자 (0) | 2024.02.29 |
[C++] 연산자(Operators), 전처리기[#define], 연산자 우선순위 (0) | 2024.02.29 |