[C++] 함수[main()], return, void

2024. 3. 3. 16:48Programming Language/C++

아래 링크 클릭 시 해당 본문으로 이동

함수

return

void

함수 동작 방식

함수 선언 또는 정의 없이 함수를 호출하면 발생하는 문제


함수

• 각각의 기능 함수라고 한다.

• 함수 표현하는 법 : `함수명()`

• 기능의 모듈화 : 밑에서부터 천천히 쌓아 올라가는 것
작은 별도의 기능부터 큰 기능까지 만들 때, 모듈화 하는 습관을 가져야 한다.

• 함수는 여러 번 호출할 수 있다.

함수가 여러 번 호출될 때마다 함수가 사용할 만큼의 메모리 영역을 잡고 해제하며, 결과를 반환하고 함수가 종료되는 과정이 반복된다.


`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()` 처음 부분에 중단점을 걸어놓았다.

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;
}

링크 단계 오류

오류 코드 : CLNK의 의미

컴파일 단계 오류

컴파일 단계 오류

Compile(컴파일) ➜ C

 

링킹 단계 오류

Linking(링킹) ➜ LNK