2020. 10. 9. 19:17ㆍW.IT/W.C언어
앞에서 main 함수의 구조를 나타내 보았습니다.
그중 main 함수의 매개변수(파라미터)에 대해선 따로 언급을 하지 않아 이번에 언급하려고 합니다.
main 함수의 매개변수란, 쉽게 말해 프로그램을 실행할 때 받아오는 값이라고 생각하시면 됩니다.
처음 c언어를 배울 때는 함수 안에 매개변수(파라미터) 값을 설정하지 않고 그냥 선언을 합니다.
int main()
{
return 0;
}
이렇게 배우는 것은 전 별로 좋다고 생각되지 않습니다.
이 방법이
"프로그램 실행할 때 매개변수(파라미터)를 안 주면 되지 않아요?"
라고 생각하실 수도 있으시겠지만, 실제로 문제가 없더라도 매개변수(파라미터)를 안 받아와서 문제가 없는 것이 아닙니다.
프로그램을 실행할 때 무조건 매개변수(파라미터)를 건네받아 실행됩니다. 바로 실행 프로그램의 경로와 이름 그리고 개수입니다. 이것에 대해선 밑에 더 자세히 설명드리겠습니다.
또한, 일반적으로 해당 프로그램에 대한 도움말이나 예시, 옵션을 실행할 때 매개변수(파라미터)로 받아옵니다.
ex) -h(도움말 옵션)
그러므로 매개변수(파라미터)가 없더라도 main 함수를 작성할 때 꼭 매개변수(파라미터)를 작성하는 습관을 들이시면 좋겠습니다.
정석적인 main 함수의 선언은 아래와 같습니다.
int main(int argc, char *argv[])
{
return 0;
}
프로그램을 실행 시 넣는 문자열(옵션)은 argv 포인터 배열에 들어가고 그 개수가 argc에 저장됩니다.
기본적으로는 argc는 1이란 숫자를 가지고 들어오며, 1개의 해당되는 문자열(옵션) 값도 argv 0번째 포인터에 값이 들어갑니다.
이 값은 프로그램 명이라고 생각하시면 편합니다. 이 프로그램 명에는 프로그램 경로까지 포함될 수 있습니다.
예를 들어보겠습니다.
test라는 프로그램을 실행하려고 합니다. 만약 현재 경로의 test라는 프로그램이 있다면, 또는 bash_profile에 해당 실행파일 경로가 저장되어 있다면,
[won@localhost ~]$ test
라고 치셔서 실행시킬 것입니다. 그렇다면 test라는 문자열이 argv[0]에 저장되고 argc는 1이 저장되어 프로그램이 실행될 것입니다.
만약 다른 경로(./dir)의 해당 실행파일이 존재한다면
[won@localhost ~]$ ./dir/test
라고 치시며 실행시킬 것입니다. 이때는 ./dir/test라는 문자열이 argv[0]에 저장됩니다.
main 매개변수를 활용한 간단한 프로그램 예제를 통해 더 자세히 설명해드리겠습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char time_unit[2] = {0,};
int t_value = 0;
int title()
{
printf("====================================================\n");
printf(" START TIMER\n");
printf(" TIME UNIT : %c TIME VALUE : %d\n", time_unit[0], t_value);
printf(" made by won\n");
printf("====================================================\n");
return 1;
}
int timer_func()
{
int i;
char time_string[10];
int t_value_r = 0;
memset(time_string, 0x00, sizeof(time_string));
if(!strcasecmp(time_unit, "s"))
{
t_value_r = t_value;
memcpy(time_string, "SECOND", 6);
}
else if(!strcasecmp(time_unit, "m"))
{
t_value_r = t_value * 60;
memcpy(time_string, "MINUTE", 6);
}
else if(!strcasecmp(time_unit, "h"))
{
t_value_r = t_value * 60 * 60;
memcpy(time_string, "HOUR", 4);
}
else
{
return 0;
}
for(i = 0; i < t_value_r; i++)
{
printf("\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf(" set time : %d %s (%d)\n", t_value, time_string, t_value_r);
printf(" cuurent time : %d SECOND\n", i);
printf(" Achievement rate : %.2f %%\n", (i/(double)t_value_r) * 100);
printf("\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
sleep(1);
}
}
int end()
{
printf("\n====================================================\n");
printf(" END TIMER\n");
printf(" TIME UNIT : %c TIME VALUE : %d\n", time_unit[0], t_value);
printf(" made by won\n");
printf("====================================================\n");
return 1;
}
int main(int argc, char *argv[])
{
if(argc == 3)
{
if(!strcasecmp(argv[1], "s") || !strcasecmp(argv[1], "m") || !strcasecmp(argv[1], "h"))
{
strcpy(time_unit, argv[1]);
t_value = atoi(argv[2]);
}
else
{
printf("invalid second opt (%s)\n", argv[1]);
printf("possible opt s,m,h\n");
return -1;
}
}
else
{
printf("===================================\n");
printf("\t%s unit time \n",argv[0]);
printf("\tunit : time unit \n");
printf("\t\t s : second\n");
printf("\t\t m : minute\n");
printf("\t\t h : hour\n");
printf("\ttime : it is time that you want\n");
printf("ex) %s s 60\n",argv[0]);
printf("it's mean 60초\n");
printf("===================================\n");
return -1;
}
title();
timer_func();
end();
return 0;
}
위 프로그램은 간단한 타이머 프로그램입니다.
메인 함수를 살펴보자면 아래와 같습니다.
int main(int argc, char *argv[])
{
if(argc == 3) /* argc 매개변수 체크 */
{
if(!strcasecmp(argv[1], "s") || !strcasecmp(argv[1], "m") || !strcasecmp(argv[1], "h"))
{
strcpy(time_unit, argv[1]);
t_value = atoi(argv[2]);
}
else
{
printf("invalid second opt (%s)\n", argv[1]);
printf("possible opt s,m,h\n");
return -1;
}
}
else /* argc 매개변수가 3이 아닐때 도움말 출력후 return */
{
printf("===================================\n");
printf("\t%s unit time \n",argv[0]);
printf("\tunit : time unit \n");
printf("\t\t s : second\n");
printf("\t\t m : minute\n");
printf("\t\t h : hour\n");
printf("\ttime : it is time that you want\n");
printf("ex) %s s 60\n",argv[0]);
printf("it's mean 60초\n");
printf("===================================\n");
return -1;
}
title(); /* 처음 들어온 매개변수 정보 출력 */
timer_func(); /* 실질적으로 타이머 루프 */
end(); /* 종료 출력 */
return 0;
}
여기서 중요한 부분은 프로그램을 실행시키기 위한 도움말입니다.
아무 옵션을 주지 않고 그냥 프로그램을 실행시켜 보겠습니다.
[won@localhost timer]$ ./timer
===================================
./timer unit time
unit : time unit
s : second
m : minute
h : hour
time : it is time that you want
ex) ./timer s 60
it's mean 60초
===================================
위에서 argv[0]은 프로그램 명이 들어간다고 했습니다.
그러므로 printf("\t%s unit time \n",argv[0]); 이라고 출력을 준 부분에는 ./timer unit time이라고 출력이 됩니다.
이것을 도움말에 맡게 옵션을 줘서 처리를 한다면,
[won@localhost timer]$ ./timer s 60
아래 로직으로 들어가게 됩니다.
if(!strcasecmp(argv[1], "s") || !strcasecmp(argv[1], "m") || !strcasecmp(argv[1], "h"))
{
strcpy(time_unit, argv[1]);
t_value = atoi(argv[2]);
}
이 if문은 들어온 argv[1]의 값이 s, m, h인지 체크하며 맞다면 argv[1]과 argv[2]의 값을 전역 변수에 저장합니다.
strcasecmp 함수는 대소문자 구별 없이 매개변수(파라미터)로 준 앞의 문자열과 뒤의 문자열을 비교하여 맞으면 0을 앞 문자열이 크면 양수를 뒷 문자열이 크면 음수를 리턴해 주는 함수입니다.
그럼 뒤로 다양한 문자열(옵션)을 주면 어떻게 될까요?
argv[3] , argv[4] ... 형식으로 해당 argv 배열 값에 순차적으로 문자열이 저장됩니다.
보통 문자열(옵션) 값을 구분하는 건 공백입니다. 만약 문자열 안에 공백을 넣으시고 싶으시다면 문자열을 ""로 감싸시면 됩니다.
[won@localhost timer]$ ./timer s 60 → 3(argc) 개의 옵션
(argv[0] == "./timer" , argv[1] == "s", argv [2] == 60)
[won@localhost timer]$ ./timer "s 60" → 2(argc)개의 옵션
(argv[0] == "./timer" , argv[1] == "s 60")
매개변수를 받아와 조건문을 통해 코딩하실 때도 마찬가지지만, 꼭 에러 처리! 필수입니다.
또한 받아올 argc값과 argv값을 잘 체크하셔야 합니다.
※ 제 글에서 부족하거나 잘못된 부분이 있다면 댓글로 남겨주시길 부탁드립니다.
※ 제 글은 제가 코딩하면서 지속해서 확인하기 위한 히스토리 성 정보들이자 회사 생활 중 실제 프로그램을 코딩하며 중요하거나 필요했던 정보들을 공유하기 위해 적은 글입니다.
'W.IT > W.C언어' 카테고리의 다른 글
[c 언어] 함수(function)의 return (1) | 2020.10.11 |
---|---|
[c 언어] c 프로그래밍을 하기 위한 기본 main 함수 구조 (1) | 2020.10.07 |