IT Japan

프로그래밍 기초 3 본문

IT/Programming

프로그래밍 기초 3

swhwang 2016. 3. 22. 00:09
반응형

?| ?90171c0678c86bbf598ea33e700e5375_11154                                                            ?      a1               

입출력이나 계산을 할 때에도 프로그램 

에 융통성을 주어 작성할 수가 있다. 이번 장에서는 프로그램의 흐름을 다 

양하게 해주는 순환과 제어에 관한 방법에 대하여 배우겠다. 



1. 제어문 


제어문이란 프로그램의 실행을 강제로 바꾸는 명령어이다. 




goto 문 ( goto label; ) - ## 있다는 것만 알고, 쓰지 말기를 바란다 ## 



goto문은 프로그램의 실행을 지정된 레이블이 있는 위치로 강제로 옮기는 

명령어이다. 레이블명 뒤에는 반드시 :를 붙이며,goto명령과 결합된 레이 

블 뒤에는 :를 붙이지 않는다. 


<예제/리스트1> 짝수가 계속 출력되는 프로그램 


#include 

main() 

int n=0; 

abc: /*레이블*/ 

printf("%d ",n); 

n=n + 2; 

goto abc; 


한편 위의 프로그램은 멈추지 않는 무한루프에 빠지게 된다. 프로그램의 

실행을 강제로 멈추게 하려면 + 키를 누르면 된다. 일반적 

인 경우에는 goto문을 쓰지 않는다. goto문은 프로그램의 논리적 측면에도 

역행하고, 프로그램의 분석을 어렵게 하므로 우리는 이러한 게 있다는 것 

만 알아두자. 




if ... then ... else 문 (조건 제어문) 



조건 제어문이란 어떤 조건이 참, 거짓 여부를 판단하여 실행을 제어하는 

구조를 말하며, 중첩사용도 허용이 된다. 


[형식] if (조건식) <= 조건식은 반드시 ( )로 둘러싸야 된다 

{ 실행부1;} <= 실행부의 문장의 여러개일 경우 반드시 { } 

else 로 묶어야 하고, 한개뿐일 경우는 생략이 

{ 실행부2;} 가능하다 


if( )안의 조건식이 참이면 실행부1을 실행하고 거짓이면 실행부2를 

실행하라는 뜻이다. 



<예제2> 하나의 정수를 입력받아 짝수인지 홀수인지 판별하는 프로그램 

(리스트들의 단짓기 요령을 유심히 보아주기 바란다) 


<리스트2> 

#include 

main() 

int n; 

printf("정수입력 : "); 

scanf("%d",&n); 


if (n%2 == 0) { /* %는 나머지를 구해주는 연산자 */ 

printf("당신이 입력하신 수는"); 

printf("짝수입니다.\n"); 

else 

printf("입력하신 수는 홀수입니다.\n"); 


베이직에서는=가 대입할 때도 쓰이고 같다는 등호로도 쓰이지만, C에서 

는=과 == 을 엄격히 구별한다. 즉=는 대입 연산자로 쓰이고, == 는 같 

음을 나타내는 관계 연산자로 쓰인다. 


sum=a + b => (대입연산자) a+b의 값을 sum에다 대입시켜라 

if ( a == b ) => (관계연산자) 만약, a와 b가 같다면,, 


첫번째 실행문은 복문이므로 { }로 묶었으나, 두번째 실행문은 단문이므 

로 { } 로 묶지 않아도 된다. 그리고 if나 else뒤에는 ; 가 붙지 않는다는 

것도 주시하여야 한다. 



<예제3> 입력받는 정수가 양수면 '양수', 음수면 '음수', 0이면 '제로'라 

고 출력하는 프로그램 작성 


<리스트3> #include 

main() 

int n=0; 

printf("정수입력:"); 

scanf("%d",&n); 


if (n>0) 

printf("양수\n"); 

else if (n<0) 

printf("음수\n"); 

else 

printf("제로\n"); 


위와 같이 else 다음에 다시 if..else문을 포함시킬 수가 있다. 그리고 C 

에는 elseif가 없으므로 else와 if를 반드시 띄어야 한다. 



<예제4> 1+(1+2)+(1+2+3)+...+(1+2+3+...+200)의 합을 구하는 프로그램 


<리스트4> 1: #include 

2: main() 

3: { 

4: int k,n; 

5: float sum=0; 

6: k=n=0; 

7: loop: 

8: k += 1; 

9: n += k; 

10: sum += n; 

11: if (k<200) goto loop; 

12: printf("합계=%f\n",sum); 

13: } 


6행의 k=n=0;은 n에 0을 대입하고, n값을 다시 k에 대입하라는 의미 

이다. 이와 같이 식을 우변부터 평가하는 성질을 '우결합성'이라고 하는데 

연산자에 따라 우결합성, 좌결합성이 다르다. 일단은 대입연산자 =는 우결 

합성을 가진다고 알고 있자. 몇가지 예를 더 들어보자. 


a=b=c=d=e=1; (이 때 1이 기억되는 순서는 e,d,c,b,a순이다) 

a=2*b=3*c=4*d=5; (d에 5를 기억시키고, d에 기억된 값에 4를 곱 

해서 c에 기억시키고, c에 기억된 값에 3을 

곱하여 b에 기억시키고, b에 기억된 값에 2를 

곱하여 a에 기억시키라는 의미이다) 


하지만, int k=n=0;의 경우에는 에러이므로 쓰지 말기를 바란다. 

8 ~ 10행에서 +=란 걸 썼는데, 이것은 각각 k=k+1, n=n+k, sum=sum+n 과 

같다. +=를 쓰는게 컴파일 후 실행속도가 더 빠르다고 한다. -=, *=,/= 도 

마찬가지이다. 




switch .. case문 (선택제어문) 



[형식] switch (변수or식) { 

case 식1: 명령문;명령문;...;break; 

case 식2: 명령문;명령문;...;break; 

case 식n: 명령문;명령문;...; 

default: 명령문; 명령문;...; 


여기서 식1~식n은 반드시 상수 또는 상수식이어야 한다. 실행시 switch다 

음의 식(또는 변수)의 값가 case다음의 식(혹은 상수)을 비교하여 값이 같 

은 곳으로 제어를 옮긴다. 만약 값이 일치하는 곳이 없으면 default다음의 

문장을 수행한다. case 다음의 문장들은 여러 개의 문장을 나열할 수 있지 

만 블럭이 아니므로 { }로 둘러싸선 안된다. case 다음의 명령문을 수행한 

후에도 switch 블럭 ({ }안의 부분)을 빠져나가지 않고 그 밑의 case문 부 

터 최종 deault문까지 실행을 하므로 필요한 경우 case 명령문 끝에 break 

를 붙인다. break를 만나면, switch블럭{ }밖으로 빠져 나가게 된다. 


<예제5> 점수를 입력받아 90점 이상이면 A, 80-89점이면 B, 70-79점은 C, 

그 이하는 F를 출력하는 프로그램 (만일 점수로 -999를 입력하면 

처리를 끝내게 한다) 


<리스트5> 1: #include 

2: main() 

3: { 

4: int score; 

5: char c; 

6: Loop: 

7: printf("점수? "); 

8: scanf("%d",&score); 

9: if (score != -999) { 

10: switch (score/10) { 

11: case 10 : c='A'; break; 

12: case 9 : c='A'; break; 

13: case 8 : c='B'; break; 

14: case 7 : c='C'; break; 

15: default : c='F'; 

16: } 

17: printf("당신의 성적은 %c입니다.\n",c); 

18: goto Loop; 

19: } 

20: } 


9행의 !=는 관계연산자이다. ==가 등호를 나타낸다고 하였는데, BASIC에 

서는 <>가 같지 않음을 나타내나 C에서는 !=가 부등호이다. 그러므로 scor 

e가 -999가 아니면 { }안의 문장을 수행하라는 의미이다. 

10행에서 score/10에 대하여 이상하게 생각하는 사람이 있을 것이다. 만 

약 95를 입력하면 9.5가 나오는데 case에서는 9.5가 없으니 default 값인 

F가 출력되는게 아니냐하고 말이다. 하지만 지난장에서 배웠듯이 정수와 

정수의 연산은 정수의 결과를 낳으므로 95/10은 9.5가 아니라 소수점 이하 

가 절삭되어 9가 된다는 것을 명심하기 바란다. 




2. 순환문 


순환문이란 특정한 부분을 반복수행하도록 하는 명령들을 일컫는 말이다. 



for문 



[형식] for(초기식;조건식;반복식) 

{반복할 부분;} <= 반복할 부분이 단문이라면 { } 생략한다 


초기식은 for문이 처음 실행될 때 단 한번 실행이 되며 여러개의 식을 , 

로 구분하여 기술할 수가 있다. 


조건식은 루프의 실행 중 매회 조사를 하며, 단 한 개의 문장만을 기술할 

수 있으며, 조건식이 참(1)이면 루프를 반복하며 거짓(0)이면 루프를 빠져 

나간다. 


반복식은 루프의 다음 실행을 준비하는 단계로서, 여러개의 식을 ,로 구 

분하여 나열할 수가 있다. 위에서 공부한 제어문들과 마찬가지로 for(...) 

다음에는 ; 를 붙이지 않는다. 


for문의 블럭에서 강제로 빠져나갈 때는 switch문에서와 같이 break 명령 

어로 빠져나간다.(goto는 되도록 쓰지 말자) 



<예제6> 1부터 100까지의 합을 구하여 1+2+3+....+100=5050를 출력하는 

프로그램 작성 


<리스트6> 1: #include 

2: main() 

3: { 

4: int i, sum=0; 

5: for (i=1;i<=100;i++) sum += i; 

6: printf("1+2+3+...+100=%5d\n",sum); 

7: } 


for 다음의 루프가 단문일 때는 { }를 쓰지 않고 일반적으로 5행과 같이 

표현한다. 그럼, 5행을 분석해 보자. 


for(i=1;i<=100;i++) sum += i; 

# @ & * 


1) # : 변수 i에 초기값으로 1을 대입한다. 

2) @ : i가 100과 같거나 작으면(현재 작다) *식을 수행한다. 

3) & : i를 1증가시킨다 ( i++는 i=i+1과 같다 ) => 2가 된다 

4) @ => * => & 를 i가 101이 될 때까지 반복한다. 

5) @ : i가 101이므로 조건식은 거짓이 되어 *를 실행하지 않 

고 루프를 빠져나와 다음 문장을 실행하게 된다. 


참고로 for(;;) printf("Loop\n"); => Loop를 영원히 찍는다. 

for(;;); => 영원히 아무것도 안한다. 




while문 



[형식1] while (조건식) { [형식2] do { 

. . 

반복할 부분; 반복할 부분; 

. . 

} } while (조건식) 


[형식1]은 

조건식의 결과가 참(1)이면 반복할 부분을 수행하고, 거짓이면 블럭을 빠 

져 나간다. 그러므로 루프안에 조건식의 결과를 변화시키는 문장이 있어야 

하며, 조건식의 변수를 변화시켜 주지 않은 경우엔 무한 루프를 돌게된다. 

while문의 블럭에서 빠져나갈 경우에도 break문을 사용한다. 


[형식2]의 경우에는 루프를 먼저 실행한 다음에 while다음의 조건식을 검 

사하는 차이가 있다. [형식1]의 경우에 조건식이 바로 거짓이 되어 루프를 

실행하지 않을 경우가 있으나 [형식2]에서는 루프를 반드시 한 번은 실행 

한다.( 이러한 것을 '판단후 처리형의 구조'와 '처리후 판단형의 구조'로 

나누어 부르기도 한다 ) 



<예제7> <예제6>의 프로그램을 while문을 이용하여 구하라. 


<리스트7> #include 

main() 

int i=0,sum=0; 

while (i<100) { 

i ++ ; 

sum += i; 

printf("1+2+3+...+100=%5d\n",sum); 


<리스트6>의 for안에는 i<=100 이지만 여기서는 i<100이다. 왜 그런지는 

곰곰히 생각해 보면 알게 될 것이다. 


그리고, <리스트4>와 <리스트5>에서 goto문을 남발하였는데 이제 순환문 

을 배울만큼 배웠으니, goto을 쓰지말고 for나 while문을 사용하여 반드시 

작성해 보길 바란다. 자신이 직접 프로그램을 짜 보고 오류를 찾아보는 것 

이 가장 좋은 방법이다. 




3. 중첩된 루프(nested loop)와 루프 예제들 


중첩된 루프란 다른 루프 내에 포함된 루프를 말한다. 그럼, 예제를 통해 

루프를 중첩시키는데 대하여 알아보자. 


<예제8> 구구단을 출력시키는 프로그램을 작성하라 


#include 


main() 

int i,j; 


for(i=2;i<=9;i++) { 

printf(" === %d 단 ===\n",i); 


for(j=1;j<=9;j++) 

printf("%3d * %3d=%3d\n",i,j,(i*j)); 


puts("아무키나 누르시오.."); 

getch(); 


<예제9> 입력된 어떤 수까지 그 이내에 들어 있는 모든 소수를 찾는 프로 

그램을 작성하라. 


1: /* 소수 추출 프로그램(C Primer Plus에서 발췌) */ 

2: #include 

3: 

4: main() 

5: { 

6: int number, divisor, limit; 

7: int count=0; 

8: 

9: printf("상한 값을 입력하라.(2보다 커야함) :"); 

10: scanf("%d",&limit); 

11: 

12: while (limit < 2) { /* 입력오류 검사 */ 

13: printf("다시 입력하라: "); 

14: scanf("%d",&limit); 

15: } 

16: printf("1에서 %d까지의 소수들은..\n",limit); 

17: 

18: for (number=2;number<=limit;number++) { 

19: for (divisor=2;number%divisor != 0;divisor++) 

20: ; 

21: if (divisor == number) { 

22: printf("%5d ",number); 

23: count++; 

24: if (count % 10 == 0) /*한줄에 10개의 소수출력*/ 

25: printf("\n"); 

26: } 

27: } 

28: getch(); 

29: } 


위 프로그램은 프로그램 다운 골격을 어느정도 갖추었다. 

6,7행에서 보듯이 변수명에 의미를 부여하면, 프로그램의 판독도 쉽고 보 

기도 좋아진다. 또한, 12 - 15행에서 처럼 입력오류를 검사하는 루틴도 가 

지고 있다. 프로그램 중간중간에 주석문을 넣어줌으로서 판독이 쉽게 하였 

다. 이렇한 주석문들은 프로그램의 오류(버그)를 수정하기 쉽게 한다(이러 

한 것을 디버깅이라고 한다). 

18행에서 27행까지의 루프는 2에서부터 limit까지의 숫자를 차례로 검사 

하는 루프이다. 


소수란 1과 자신으로만 나누어지는 수를 말한다. 


19,20행은 number와 중간에 나누어 떨어지는 수가 하나라도 있으면 21행 

으로 가라는 의미이다. 중간에 나누어 떨어지는 수가 없으면 결국 number 

는 자신으로 나누어 떨어져(number와 divisor이 같아져-결국은 소수이다), 

21행의 조건을 만족시키므로 화면에 출력되는 것이다. count는 한 줄에 소 

수를 10개씩 찍기 위하여 만들어 놓은 변수이다. 

20행의 ;는 반드시 있어야 한다. 만일 없으면 if블럭이 for루프안에 속하 

게 되어 예기치 않은 결과가 발생하게 된다. 조건식(number%divisor!=0)이 

참이면 계속 19,20행을 돌게 된다. 


앞에서 break는 switch, for, while문에서 루프를 강제로 빠져 나올때 쓰 

이는 명령어라고 배웠다. goto나 break같은 것은 프로그램의 구조적인 면 

을 반감시키므로 되도록이면 쓰지 않도록 하자. 




이번 장에서는 C언어의 제어문과 순환문에 대하여 알아보았다. 이 순환문 

과 제어문은 C뿐만 아니라 모든 언어에서 가장 많이 쓰이는 것이므로 여러 

분들은 각 명령어의 구조와 기능을 확실히 이해해 두어야 한다. 



반응형

'IT > Programming' 카테고리의 다른 글

제 6장 - 배열과 포인터  (0) 2016.03.22
제 5장 - 함수 / 기억부류  (0) 2016.03.22
제 4장 - 연 산 자  (0) 2016.03.22
제 2장 - C의 입출력 함수 및 수의 표현  (0) 2016.03.22
제 1장 - C의 구조와 변수  (0) 2016.03.22
Comments