1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.
판매자 | 프리미엄 | 판매 납포인트 | 무료 | 평점 | 0점 / 총 0명 참여 |
---|
***************************< 캠퍼스 C 강좌 >******************************
[제목] :
[코드] : campusc1-015 (초급)
[교재] : CAMPUS C (초급, Third edition) [출판사 : 책과스승]
[알림] :이 파일은 "캠퍼스 C"에서 모든 분께 공개한 "초급 강좌"입니다.
이 [알림]의 내용을 지우지 않는다면 누구에게나 임의로 복사해 줄 수
있습니다.그러나 이 강좌 내용에 대한 저작권은 "캠퍼스 C"에 있습니다.
[연락처] : 605-8662 (서울) ("캠퍼스 C", 도서출판 "책과 스승")
천리안 : go campusc
나우콤 : go lcampc
하이텔 ID : campusc
****************************<< 목 차 >>************************************
<1> 포인터의 복합표현
1> *dangbal++
2> (*dangbal)++
3> *++dangbal
4> ++*dangbal
<2> main 함수(총사령관)도 명령을 받는다
1> argc
2> argv
3> 쓰는 요령
**************************< 내용 시작 >********************************
<1> 포인터의 복합 표현 (*dangbal++, (*dangbal)++, ...)
***********************************************************************
그동안 여러시간 포인터에 관해 얘기를 했음에도 불구하고 내용을
이해 하는데 어려움이 있을겁니다. 물론 아직 진도를 안나간 부분이 있기는
하지만, 원래 포인터의 표현은 복잡하기 짝이 없습니다. 특히 문제가 더 복
잡해 지는 이유는 여러 연산자와 결합하여 복합적으로 나타난다는데 있습니
다.
그중에서도 기초에 해당하면서 약방의 감초같은 놈이 지금 우리가
다룰 4 가지 표현입니다. 프로그램을 오래 하다보면 이런 표현은, 거의 상투
적으로 습관적으로 쓰지만 처음 배우는 입장에서는 기본적으로 내용을 따져
봐야 겠지요
이 표현은 이른바 "...의 값(*)" 과 "증가 연산자(++)" 가 당발씨를
사이에 놓고 한판 경합을 벌이는 과정입니다. 이걸 적어보면
1> *dangbal++
2> (*dangbal)++
3> *++dangbal
4> ++*dangbal
이 표현들은 이미 우리가 알고 있는, 다음과 같은 사실을 근거로 만들어진
것입니다.
-------------------------------------------------------
1. 소령마크(*)는 당발 씨 앞(우리가 보기에는 왼쪽)에서만
팔짱을 낄수 있다.
2. 증가(++)는 앞 뒤 양쪽에서 팔짱을 낄 수 있다.
-------------------------------------------------------
이걸 해석하기 위해서는, 아시는데로 다음과 같은 만고불변의 법칙을 따릅
니다.
----------------------------------
1. 연산자의 우선순위에 따른다.
2. 당발 씨 몸에 가까운 것에서 부터
먼쪽으로 해석해 나간다
----------------------------------
위에서 2번 같은 경우는, 언젠가 얘기 한적이 있지만, 양파는 겉에
서 부터 껍질을 벗기지만, C에서는 안에서 부터 괄호()를 벗긴다 는 법칙과
같은 내용입니다. 즉 괄호()가 없더라도 변수(당발씨) 몸통에 바짝 붙은 연
산자의 말을 우선적으로 들어 주기로 되있는겁니다. 그리고 이런 사실은 너
무 당연해서 그런지 다른 책에서는 분명하게 말로 적어 놓지 않는것 같으므
로 이 자리에서 분명히 기억 하시기 바랍니다.
그리고 이경우에 또 문제가 되는것은 다음과 같은 두가지를 혼동하
는 것 입니다.
--------------------------------------------
1. 마당발의 주소를 증가(++) 시키는 것인가 ?
2. 마당발이 가리키는 람보의 집 내용을 증가 시키는것인가
--------------------------------------------
이런 사실을 일단 염두에 두시고 하나씩 따져 보기로 하지요.
-----------------------------------------------------------------------
1> *dangbal++
-----------------------------------------------------------------------
이 표현은 위의 4 가지중 특히 많이 쓰이는 표현 이므로 , 반드시
이것은 외우고 넘어 가야 합니다. 이것은 아래와 같은 표현을 한문장으로 적
은 표현 입니다.
*dangbal++ <-- *dangbal + dangbal++
따라서 각각의 표현만 알고, 전체적인 기능을 외우고 넘어가면 되지만, 따지
려면 조금 복잡해 지지요. 예를 보면
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
printf("%c", *dangbal); --> 'c' 찍음
dangbal++;
printf("%c", *dangbal); --> 'l' 찍음
dangbal++;
printf("%c", *dangbal); --> 'i' 찍음
dangbal++;
}
저는 "클리프 행어" 라는 영화를 숨한번 못쉬고 정신없이 봤는데, 지금 당발
이가 그 이름을 한글자씩 찍고 있는 것 입니다. 이걸 한문장으로 쓰면 다음
과 같습니다.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
printf("%c", *dangbal++); --> 'c' 찍음
printf("%c", *dangbal++); --> 'l' 찍음
printf("%c", *dangbal++); --> 'i' 찍음
}
표현이 더 간단해 졌지요 ? 여기서는 "연속적"으로 한글자를 찍고 증가를 하
는것인데 여기서 여러분들은, 위에서 언급한 "증가"의 문제를 확실히 구별해
야 합니다. 즉
-----------------------------------------------
1. 마당발이 가지고 있는 내용(즉, 남의집 주소)를
증가(++) 시키는 것인가 ?
2. 마당발이 가리키는 람보의 집 내용을 증가 시키는
것인가 ?
-----------------------------------------------
여기서는 1번의 경우 입니다.즉, 마당발이 한글자를 찍고 나서 그 다음집을
가리키는 것 입니다. 이건 결국 당발씨 자기 집의 값을 증가 시키는 것 입니
다. [211쪽]의 그림을 직접 보는게 더 명확한 모습을 보여줍니다.
이것을 쓰는 경우는 보통 위예 예를 든 바와 같이 "스트링을 찍을
때" 입니다. 위의 "cliff hanger"를 for() 순환문으로 다시 찍어 볼까요 ?
char *dangbal, rambo[] = "cliff_hanger";
main()
{
int i;
dangbal = rambo;
for(i=0; i< sizeof(rambo); i++) {
printf("%c", *dangbal++); --> "cliff hanger" 찍음
}
}
이제 시각적으로는 어떤일을 하는지 눈에 "팍" 들어 오지는 않지만, 훨씬 전
문적인 프로그램 수준으로 들어섰습니다. 앞으로 우리는 가급적 이와같이
"포인터 와 순환문을 사용한" 간결 명료한 표현을 쓰도록 노력해야 합니다.
물론 위와 같은 문장을 찍을려면 "스트링을 찍는 함수"를 사용하면 더 간단
하지요.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
puts(dangbal);
}
그러나 puts()은 옷으로 말하면 "기성복"에 해당하고 우리 맘대로 스트링을
조작할 때 쓰기는 불편하지요. 예를 들면 위 "cliff_hanger"에서 언더라인
(_)을 만날때 까지만 찍어라. 라는 프로그램을 짜려면 다음과 같이 응용을
하는 것이지요.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
int i;
dangbal = rambo;
for(i=0; i< sizeof(rambo); i++) {
if(*dangbal == '_')
break;
printf("%c", *dangbal++); --> "cliff" 까지 찍음
}
}
<문제> 위에서 언급한 *dangbal++ 연산을 하고 나면 rambo[]의 데이타, 즉
"cliff hanger" 라는 글자들은 다른 글자로 바뀌는가 ?
<답> 아니요. *dangbal++ 연산을 아무리 해도 영화 제목은 안바뀌고 그대로
있습니다.
<문제> 그러면 당발씨가 가지고 있는 집주소는 바뀌는가 ?
<답> 예, 당발씨는 *dangbal++ 연산을 할때 마다 옆집을 가리키느라고 정신
없이 변하지요.
-----------------------------------------------------------------------
2> (*dangbal)++
-----------------------------------------------------------------------
이것은 보다시피 괄호()를 해 줌으로서 우리의 눈을 시원하게 해주
는데,의미는 "당발이가 가리키는 곳의 값을 찍어라" 그리고 "증가하라" 입니
다. 이 의미도 역시 [213쪽]의 그림을 보면서 이해하는게 더 편합니다.
여기서 일단 값을 찍으라는것은 이해가 되지요. 위의 예를 그대로
들면 "cliff hanger"의 한글자를 찍을 겁니다. 예를 들어 첫글자 'c'를 찍었
다고 하고, 그다음에 증가를 하는데 여기서는 무엇이 증가 합니까 ? 우리는
둘중에 하나를 선택할 수 있습니다.즉
--------------------------------------------
1. 마당발의 주소를 증가(++) 시키는 것인가 ?
2. 마당발이 가리키는 람보의 집 내용을 증가 시키는것인가
--------------------------------------------
다음을 보지요.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
printf("%c", (*dangbal)++); --> 'c' 찍음
printf("%c", (*dangbal)++); --> 'd' 찍음
printf("%c", (*dangbal)++); --> 'e' 찍음
}
결과는 위에 적은대로 *dangbal++ 와는 다릅니다. 이유는 () 때문인데, 다시
말로 해보면
1) "일단 값을 찍어라 --> 'c'를 찍었다"
2) 그리고 "증가해라 --> 방금찍은 값을 'c'에서 'd'로 증가는 뜻"
다시 말해서 여기서의 증가는 당발이가 옆집으로 포인터를 옮겨 가는것이 아
니고 찍은 그 값 자체를 (즉 rambo[0]) 증가 하라는 겁니다.
<문제> (*dangbal)++ 연산을 하고 나면 rambo[]의 데이타, 즉 "cliff
hanger" 라는 글자들은 다른 글자로 바뀌는가 ?
<답> 예, 할 때마다 바뀝니다.
첫글자 'c'의 경우 c -> d -> e -> f 이런식으로 증가해요
<문제> 그러면 당발씨가 가지고 있는 람보네 집주소는 바뀌는가 ?
<답> 아니요 당발씨 가 가지고 있는 주소는 변한없이 가만 있어요.
*dangbal++ 의 경우와 사정이 정 반대로 뻍다는 것을 알겁니다.
이와 같이 증가에는 두가지가 있는것 입니다. 이제 부터는 이 문제
를 잘 구별 할 줄 알아야 하는데 이것도 역시 I.Q 제로인 컴파일러가 알아
듣는 아주 간단한 법칙이 있습니다. 즉
-----------------------------------------------------------
address다 증가(++)해 --> 주소를 관장하는 당발이가 증가함
값이다 증가(++)해 --> 방금 찍은 값 'c' 가 'd'로 증가함
------------------------------------------------------------
이렇게 증가 하기전에 분명히 말을 해 주는데 이걸 못 알아 듣는 사
람이 있습니까 ? 그러나 C 말에 익숙치 않은 일부 초보자들은 구별을 못하는
경우가 있지요. 구별은 다음과 같이 합니다.
1> *dangbal++ --> *(dangbal++) ( 같은 표현)
-------------------------------------------------
위 표현은 같다는 걸 알아야 합니다. ()를 생략한 거지요. 해석을 해보면 역
시 안쪽 부터
1) "당발아 증가해" 그런데 나는 뒤에 붙어 있으니까 나중에 증가해 !
"그러나 !! " 분명히 네가 "address 표현" 일때 말했어 !
2) 값 찍어
이 말을 위와 같이 쉽게 표현 하면 "address다 증가(++)해 " 입니다.위 1)번
(dangbal ++) 가 address 표현이라는걸 아시지요 ? 비교를 위해서
2> (*dangbal)++
---------------
이것은 괄호가 분명히 말해 주듯
1) 당발이 가 가리키는 값을 찍어, 분명히 값이라고 했어 !!
2) 증가해 !
여기서 문제는 증가(++) 연산을 하기 직전에 "값"을 언급했나, 아니면
"address"를 언급했나를 구별하는 일입니다. 둘을 동시에 비교하면
1> *(dangbal++) <-- 괄호 안이 address 표현 이다
2> (*dangbal)++ <-- 괄호 안이 값(*) 표현 이다
이것도 역시 스트링을 취급할 때 유용하게 써먹을수 있습니다.
<문제 > 다음을 찍으면 어떻게 되는가 ?
char *dangbal, rambo[] = "cliff_hanger";
main()
{
int i;
dangbal = &rambo[3]; /* <-- 요기 조심 */
for(i=0; i< 5; i++) {
printf("%c", (*dangbal)++);
}
}
<문제> 다음 문제를 해결하라
char *dangbal, rambo[] = "abc";
main()
{
dangbal = rambo;
puts(dangbal); /* <-- 결과는 abc */
(*dangbal)++;
(*dangbal)++;
puts(dangbal); /* <-- 결과는 cbc */
dangbal = (rambo + 1);
puts(dangbal); /* <-- 결과는 bc */
(*dangbal)++;
(*dangbal)++;
puts(dangbal); /* <-- 결과는 dc */
dangbal = (rambo + 2);
puts(dangbal); /* <-- 결과는 c */
(*dangbal)++;
(*dangbal)++;
puts(dangbal); /* <-- 결과는 e */
printf("%s ", rambo); /* <-- 위에서 바뀐 결과를 찍음*/
}
위와 같은 과정을 거치면 rambo[] 내부의 각 값을 고칠 수 있습니다.이제 똑
같은 방법으로 아래 프로그램을 고쳐서 결과가 자기 이름의 영문 첫글자를
찍도록 고쳐보세요(가능한 고급 표현을 써서)
char *dangbal, rambo[] = "abc";
main()
{
/* 여기를 고치세요 */
}
-----------------------------------------------------------------------
3> *++dangbal
-----------------------------------------------------------------------
이런건 비교적 쉬운데 말로 해 보면
1) 증가해 ! 그런데 ++는 앞에 붙어 있으니까 무조건 먼저 증가해, 그런
데 증가 하는 것은 (현재 dangbal만 있으니까) "address"표현 이니까 알
아서 해봐
2) 그것의 값을 찍어봐(*)
[214쪽]의 그림을 직접 보고 아래의 문제를 풀어보세요.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
printf("%c", *++dangbal);
printf("%c", *++dangbal);
printf("%c", *++dangbal);
}
<문제> 위에서 언급한 *dangbal++ 연산을 하고 나면 rambo[]의 데이타, 즉
"cliff hanger" 라는 글자들은 다른 글자로 바뀌는가 ?
<문제> 그러면 당발씨가 가지고 있는 집주소는 바뀌는가 ?
<문제> *dangbal++ 과 (*dangbal)++ 어느것과 기능이 유사한가 ?
-----------------------------------------------------------------------
4> ++*dangbal
-----------------------------------------------------------------------
이것도 말로 하면 다음과 같습니다.
1) 당발의 값(*)을 찍어봐
2) 그리고 증가(++)해. 그런데 바로 직전에 "값"을 얘기 했었지 ? 그러니까
증가하는 것도 바로 그값을 하나 증가 하라구.
이것도 [215쪽]의 그림을 직접 보고 이해하세요. 말이 팔요없을 정도로 정확한
표현입니다.
char *dangbal, rambo[] = "cliff_hanger";
main()
{
dangbal = rambo;
printf("%c", ++*dangbal);
printf("%c", ++*dangbal);
printf("%c", ++*dangbal);
}
<문제> 위에서 언급한 *dangbal++ 연산을 하고 나면 rambo[]의 데이타, 즉
"cliff hanger" 라는 글자들은 다른 글자로 바뀌는가 ?
<문제> 그러면 당발씨가 가지고 있는 집주소는 바뀌는가 ?
<문제> *dangbal++ 과 (*dangbal)++ 어느것과 기능이 유사한가 ?
해석을 할 때마다 혼동이 생기면 우리의 "만고불변의 원리"를 항상 참조하세
요
***********************************************************************
<2> main 함수(총사령관)도 명령을 받는다
1> argc
2> argv
3> 쓰는 요령
***********************************************************************
1> argc
-----------------------------------------------------------------------
우리가 람보에게 "미사일과 화살을 쏴라"고 명령을 내릴 때 다음과 같이
함을 압니다.
main()
{
int missile,arrow;
fire(missile, arrow);
}
fire(missile,arrow)
{
}
이와같이 모든 함수들은 명령을 받지요. 그러나 아무도 main() 함수
를 부를 수는 없다고 했습니다. 전쟁 중에는 이 말이 맞지요. 바쁜데 아무도
총사령관을 건드릴 수는 없는 일입니다. 그러나 처음 대통령에게서 전쟁을
일으키라고 명령을 받는 순간에는 예외입니다. 대통령에게서 다음과 같은 명
령을 받습니다.
"총사령관 항공모함 2대 가지고 가서 전쟁 일으키시오 !".
여기서 대통령은 DOS 에 해당하고 항공모함 2대를 받는 형태는 일정하
게 정해져 있습니다.(조금 아래 나옴)
DOS 에서 명령을 주는 형태는 이미 여러분이 잘 알고 있습니다. 쉬운
예로 del명령을 들어볼까요 ? 이건 물론 "도스 명령어"인데 del 도 우리가
del.c를 짜고 컴파일 하여 del.exe 를 만들었다고 생각하면 됩니다.
c:\> del chungha.doc
이건 말로하면 대통령이 chungha.doc를 확 던져 주면서 "del 사령관
!" 하고 부르는 것입니다. 무엇을 하라는 것인지 말을 안해도 우리는 압니
다. 마찬가지로 copy 명령을 보면
c:\> copy chungha.doc my.doc
역시 "chungha.doc 와 my.doc" 를 확 던져주면서 "copy 사령관 !"
하고 부르는 것입니다. 정보가 정확하지 않습니까 ? "chungha.doc를 my.doc
화일로 복사해"라는 두개의 정보를 주었습니다.
이제 우리가 copy.c 라는 프로그램을 직접 짜보기로 합니다. 이것은
컴파일을 거치면 copy.exe 가 될것입니다. 이제 우리는 DOS로 부터 어떤 정
보가 올것으로 기대하고 있으므로, 지금까지 우리가 해오던 대로
main()
{
}
이렇게 짜면 안됩니다. 이건 마치 대답 못하는 벙어리(void) fire() 함수를
부르면서
listen = fire();
로 쓰는것 처럼 바보 같은 짓입니다. 옳게 쓰면
----------------------------
main( int argc, char **argv)
{
}
----------------------------
아니면 아래 표현도 똑같은 것입니다.
------------------------------
main( int argc, char *argv[])
{
}
------------------------------
이제는 2 차원 포인터와 배열은 넘나들 수 있다는 것을 알테니 위의
두 내용이 똑같다고 하는 이유를 이해 할 것입니다. 이렇게 써놓으면 대통령
으로 부터 받는 명령 "chungha.doc", " my.doc" 따위를 main()함수가 받을
수 있는 것입니다. 이제부터는 "대통령에게서 받는 정보"를 "아규먼트
(argument)" 라고 정식 용어를 사용 합니다.
main() 안에 처음 나타나는 변수 argc 는 "argument count"의 준말
입니다. 이건 물론 자기 맘대로 지을 수 있는 것이나 통상 똑같은 이름을 쓰
고 있습니다. 이것은 대통령 입에서 나온 "단어(스트링)의 수" 입니다. 즉
아래는 두 마디 입니다.
c:\> del chungha.doc
| |
1 2마디
대통령이 "del" 과 "chungha.doc" 두마디를 외친거지요. 아래는 세 마디입니
다.
c:\> copy chungha.doc my.doc
여기서 마디의 구별은 다음과 같이 합니다.
---------------------------------
1. 하나이상의 공백문자(space) 로
2, 탭문자 로
---------------------------------
즉, 단어 사이가 떨어지면 마디가 끊어진 것으로 본다는 얘기입니다. 또 쌍
따옴표 " " 로 쌓인 스트링은 하나로 취급합니다. 예를 들면,
c:\> dir <-- argc 는 1
c:\> del *.* <-- argc 는 2
c:\> cd hwp <-- argc 는 2
c:\> game a.dic <-- argc 는 2
c:\> copy a.doc b.doc <-- argc 는 3
c:\> sample "good morning" <-- argc 는 2
이제 test.c 라는 이름으로 아래와 같이 프로그램을 짜봅니다.
main( int argc, char **argv)
{
printf(" count = %d\n", argc);
}
컴파일을 하면 test.exe 가 생길 것입니다.
<문제> 이제는 터보 C 를 빠져나와서 DOS 상태에서 다음과 같이 각각 쳐봅니
다. 결과는 무엇입니까 ?
c:\> test
c:\> test good
c:\> test good morning
c:\> test 1 2 3 4 5 6 7 8
<암기> argc 는 다른말로 하면, "사람이 친 격리된 단어의 갯수" 를 갖고 있
는 변수입니다.
-----------------------------------------------------------------------
2> argv
-----------------------------------------------------------------------
main() 안에 두번째 나타나는 변수 *argv[] 는 (argument vector)의
준말입니다. 이건 이차원 배열과 마찬가지 이므로 스트링 여러개를 취급할
수 있는데 낱말의 뜻은 "argument로 넘어온 각 단어(스트링)들의 번지수
(vector)" 라는 뜻"입니다. 이제 test.c 라는 프로그램을 조금 바꾸어 예를
봅니다.
main( int argc, char **argv)
{
printf(" count = %d\n", argc);
printf(" string = %s\n",argv[0]);
}
컴파일을 하고 터보 C 를 빠져나와서 DOS 상태에서 다음과 같이 쳐봅니다.
c:\> test
결과는 다음과 같습니다.
count = 1
string = c:\tc\test
결과가 얘기하는 것은, argv[0] 은 "완전한 경로명과 함께 test.exe 의 이름
"을 가리키고 있다는 것입니다. 마찬가지로 다음과 같이 프로그램을 고치고
main( int argc, char *argv[])
{
printf(" count = %d\n", argc);
printf(" string1 = %s\n",argv[0]);
printf(" string2 = %s\n",argv[1]);
}
컴파일 후 다음과 같이 치면
c:\> test good
결과는 다음과 같습니다.
count = 1
string1 = c:\tc\test.exe
string2 = good
여기서 우리가 신경쓸것은 "사람이 단어를 몇개를 쳤는가를" 알아야 argv[]
를 찍을 수 있다는 것입니다. 예를 들어 바로 위의 경우처럼 단어 두개를 쳤
는데 다음과 같이 해보는 것은 아무 의미가 없는 것이지요.
printf(" string3 = %s\n",argv[2]);
따라서 반드시 다음과 같은 순서를 거칩니다.
---------------------------------------------
1. "먼저 argc의 갯수를 확인"하고
2. argv[]로 가서 어떤 단어를 쳤는지 읽어본다.
---------------------------------------------
-----------------------------------------------------------------------
3> 쓰는 요령
-----------------------------------------------------------------------
변수 argc 가 의미하는 것은 금방 이해 할 수 있을것입니다. 단순히 단
어의 갯수가 들어 있습니다. argv 는 이차원 포인터와 마찬가지 이기 때문에
머리속에 개념이 안들어 올지도 모르겠습니다.
사실은 나도 천천히 따져봐야지 척본다고 머리속에 그림이 확 그려지
는 것은 아닙니다.
그러나... 실제로는 머리속에서 개념이고 뭐고 따질 필요가 없습니
다. 이것도 역시 상투적으로 쓰는 표현이기 때문에, 조금 익숙해지면 그 의
미 자체를 암기 할 수 있을 것입니다. 따라서 다음과 같은 사실만 이해 하기
로 합니다. 이것도 역시 배열이므로 [0] 부터 시작하는 걸 유의해야 합니다.
사람이 첫번째 친단어 ---> argv[0] 이 "처음 번지수" 를 갖고 있습니다.
사람이 두번째 친단어 ---> argv[1] 이 "처음 번지수" 를 갖고 있습니다.
사람이 세번째 친단어 ---> argv[2] 이 "처음 번지수" 를 갖고 있습니다.
사람이 네번째 친단어 ---> argv[3] 이 "처음 번지수" 를 갖고 있습니다.
. .
. .
여기서 입력하는 단어의 갯수에는 (우리가 쓰기에는 충분할 정도로) 별 제한
이 없습니다.그리고 다음의 표기법도 눈에 익혀야 합니다.
printf(" string = %s\n",argv[1]);
printf 안의 " %s" 타입은 string의 첫번째 번지수를 알려 달라는 뜻입니다.
따라서 argv 같이 0 차원도 도 아니고 *argv[0] 처럼 2 차원도 아니고 위에
처럼 정확히 1차원으로 적어주어야 한다는 것이지요.
다음의 예제를 봅니다.
<예제 1>
copy 명령 처럼 3개 의 단어( "copy", "chungha.doc", "my.doc")가 정
확히 들어와야 하는 경우 에는 이 갯수가 틀리면 더이상 프로그램을 진행시
킬 필요없다.
main( int argc, char *argv[])
{
if( argc != 3) {
printf(" 쓰는법이 틀렸습니다.");
exit();
}
}
<예제 2>
몇개의 단어를 입력할 지 모르는 경우.
main( int argc, char *argv[])
{
int i;
for(i=0; i < argc; i++) {
printf("string = %s\n",argv[i]);
}
}
다음에는 간단한 음악 프로그램을 응용 예로 보입니다. 이걸 sound.c 로 잘
라내고 실행해 봅니다.
#include <stdio.h>
main(int argc, char *argv[])
{
int i, frequence;
clrscr();
if(argc == 1) {
putch(0x07);
printf("사용법 : c:\tc\>sound 100 200 300 ....");
exit();
}
for(i=1; i < argc; i++) {
frequence = atoi(argv[i]); /* 함수소개 참조 */
if( frequence == 0) {
printf(" %s is wrong frequence", argv[i]);
exit();
}
sound(frequence);
delay(300);
nosound();
}
}
<숙제> 프로그램을 읽고 이해해 보라.
<숙제> 가청 주파수는 20 - 20000 Hz 까지라고 합니다. 입력한 숫자가 이 범
위 를 벗어나는지 검사 하고 벗어나면 벨소리와 함께 프로그램을 종료
하도록 고쳐보라
<숙제> delay()는 현재 무조건 300 으로 되있습니다. 이것도 입력받아 박자
로 쓰 고 산토끼같은 간단한 음악을 연주하라.
<숙제 > 간단한 계산기 프로그램을 작성해 보라. 가장 기본적인 사양은 두개
의 수를 + - * / 할 수 있도록 하라. 예를 들어 다음과 같이 DOS 상에서 치
면 값을 계산하도록 하자
c:\> calc 100 + 200 (enter key)
result : 300
**************************< 끝 마치며 >********************************
포인터에 관한 내용이 진행 중인데, 이 내용은 언젠가도 얘기 했듯
이 "이해" 하는 정도로는 곤란하고, "숙달"이 되야 합니다.
포인터는 앞으로 "구조체"를 만나면 표현이 더욱 복잡해 집니다. 아
직도 기초적인 내용이니까 확실히 이해하고 넘어가야 합니다.
***********************************************************************