[c 언어] c 프로그래밍을 하기 위한 기본 main 함수 구조

2020. 10. 7. 01:25W.IT/W.C언어

main 함수는 프로그램이 실행되면 가장 먼저 들어가는 함수입니다. 즉, 프로그램을 여는 문이라고 생각해보시면 됩니다.

그렇기에 main 함수 안은 명확해야 하고 깔끔 혹은 세련되어 보여야 한다고 생각합니다.

 

그렇다면, 어떻게 main 함수를 작성해야 명확하고 깔끔해 보일까요?

 

답은 짧게 작성하되 각 PART를 잘 나눠 작성을 해야 합니다.

 

예를 들어볼까요?

 

첫 번째 코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int a = 0, b = 0, c = 0;
char *k = NULL;

int main(int argc, char *argv[])
{
    b = 50;
    c = 25;
    k = (char *)calloc(1, 4);
    if(!k)
    {
    	return -1;
    }
    
    for(a = 1; a <= b; a++)
    {
    	if(a == c)
        {
            memcpy(k, "MID", 3);
            printf("num : %d -- %s\n", a, k);
        }
        else
        {
            printf("num : %d\n", a);
        }
    }
    
    if(k)
    {
    	free(k);
        k = NULL;
    }
    
    return 0;
}

 

 

두 번째 코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int a = 0, b = 0, c = 0;
char *k = NULL;

int init()
{
    b = 50;
    c = 25;
    k = (char *)calloc(1, 4);
    if(!k)
    {
    	return -1;
    }
    
    return 0;
}

int proc()
{
    for(a = 1; a <= b; a++)
    {
    	if(a == c)
        {
            memcpy(k, "MID", 3);
            printf("num : %d -- %s\n", a, k);
        }
        else
        {
            printf("num : %d\n", a);
        }
    }
    
    return 0;
}

int term()
{
    if(k)
    {
    	free(k);
        k = NULL;
    }
}

int main(int argc, char *argv[])
{
    if(init())
    {
        return -1;
    }
    proc()
    term()

    return 0;
}

 

두 코드들은 같은 내용을 담고 있습니다.

 

다만 코드의 구조가 다르죠.

 

간단히 설명하자면, 첫 번째 코드는 main 함수의 모든 기능이 다 들어가 있는 형태이고 두 번째 코드는 main 함수는 각 기능들이 담긴 함수가 들어가 있습니다.

 

어떤 코드가 더 이해하기 쉬우신가요?

 

보통 프로그래밍을 할 때는 두 번째와 같이 main 부분을 짧게 각 PART 별로 나눠 프로그래밍을 진행합니다.

현재 제가 작성한 코드를 보고

"음.. 난 첫 번째 코드가 더 이해하기 쉽고 간단한 거 같은데?"

라고 생각하실 수도 있겠지만 만약 이 코드가 1000줄이 넘고 10000줄이 넘는 코드를 main 함수에 다 담는다면 정말 끔찍한 가독성을 가진 프로그램을 보실 수 있으실 겁니다..

 처음에는 본인이 작성하였으니 대충 보면 아실 수도 있겠지만 훗날 다시 그 프로그램을 유지 보수하거나 업데이트할 일이 생기면... 생각만 해도 끔찍합니다.

 또한, 다른 사람과 공동작업을 하거나 에러가 발생했을 경우 등 다양한 곳에서 문제가 발생할 것입니다. 그러므로 처음부터 함수화하는 습관을 들이셔야 합니다.

 

 다시 본론으로 들어와서 제가 배우고 자주 사용했던 main 함수의 구조는 아래와 같습니다.

 

int main(int argc, char *argv[])
{
    get_option()/* 옵션 처리 함수 */
    signal()	/* 신호 세팅 함수 */
    init()	/* 초기화 함수    */
    proc()      /* 실제 process 동작 함수 */
    term()      /* 종료를 위한 함수  */
}

 

 get_option 함수는 말 그대로 option을 가져오는 것입니다. 

 만약 option이 없으시다면 굳이 넣으실 필요 없습니다. 다만 나중에 프로그램을 구현하실 때 config 파일에서 option을  읽어와 처리하는 경우가 많기 때문에 넣었습니다.

 

 signal 함수는 signal을 받으면 해당 signal에 대한 동작을 세팅하는 것입니다. 이것도 OS에서 프로그램 구현할 때 거의 필수로 들어가는 처리이기 때문에 넣어봤습니다.

 signal에 대해선 나중에 다시 글을 올리겠습니다.

 

 init 함수는 사용할 변수들이나 구조체 등을 초기화하거나 메모리를 동적 할당받거나, 스레드를 생성하는 등 프로그램이 실행되기 전 준비하는 단계라고 보시면 됩니다. 

 제가 위에서 작성한 두 번째 코드를 보시면 더 이해가 되실 겁니다.

 

 proc 함수는 실질적으로 프로그램을 실행하는 구간입니다. 프로그램에 정체성을 이 함수에 담아주시면 됩니다. 다만 그렇다고 이 함수 안에 무턱대고 다 쑤셔 넣으시면 안 됩니다... 

 프로그래밍은 최대한 세분화하여 가독성 좋게 나누어 작업하시는 것이 좋습니다.

 

 term 함수는 이 프로그램이 종료되기 전 마지막으로 호출되는 함수입니다. 여기서는 동적 할당한 메모리를 해제시켜주는 작업을 주로 진행하시게 될 겁니다.

 


 

 프로그램을 구현하는 것은 하나의 c파일로 구현하는 것이 아닌 여러 c파일과 라이브러리, 헤더 파일 등으로 구현되지만 이 수많은 프로그램 소스 중 main 함수는 한 개입니다. 그러므로 처음 시작을 체계적으로 깔끔하고 명확하게 잡아야 뒤에 코딩을 할 때에도 헤매지 않을 수 있습니다. 

 

 또한 프로그래밍을 하면서 중요한 것은 에러 처리입니다. 각 코드마다 또는 함수마다 에러 처리를 할 수 있는 건 다 해주시는 것이 좋습니다. 


※ 제 글에서 부족하거나 잘못된 부분이 있다면 댓글로 남겨주시길 부탁드립니다.

※ 제 글은 제가 코딩하면서 지속해서 확인하기 위한 히스토리 성 정보들이자 회사 생활 중 실제 프로그램을 코딩하며 중요하거나 필요했던 정보들을 공유하기 위해 적은 글입니다.