본문 바로가기

Programming

[C언어] C언어 기초강좌 6 / C언어 / 프로그래밍 기초 / 프로그램 만들기

이번 강좌에서는 프로그램 흐름제어에 대해 알아보겠습니다. 

프로그램 흐름 제어란 실제 프로그램에서 가장 중요한 부분으로 

어떤 조건이 만족될때 어떤 부분을 실행하거나 

어떤 특정 부분을 반복하는 기능을 수행하도록 프로그램의 흐름을 

제어하는 것을 말합니다. 

C에서는 프로그램 흐름 제어를 위해 많은 방법을 제공합니다. 

그럼 그것들을 하나씩 알아보죠. 
1. if문. 

프로그램을 만들다 보면 

어떤 조건이 만족되면 특정 부분을 실행하고 그렇지 않으면 

또다른 특정 부분을 실행해야 하는 등의 구조가 필요할때가 있습니다. 

이때는 if문을 사용하면 됨니다. 

if문은 어떤 조건이 만족 되면 특정 부분을 실행하는 기능을 합니다. 

그럼 자세히 알아보죠. 


(1) C언어 에서 참과 거짓 

if문을 배우기 전에 한가지 알아 둘 것이 있습니다. 

C에서 참과 거짓의 구분을 어떻게 하는지 알아야 하거든요. 

저번 관계형 연산자에서 참은 1 거짓은 0을 돌려준다고 했습니다. 

그럼 참과 거짓은 1과 0으로만 구분할까요? 

그렇지 않습니다. 

C에서 0이 아닌 모든 값은 참으로 인식하고, 

0만 거짓으로 인식합니다. 

지금은 별로 중요하지 않게 보여도 if문에서 정말 중요한 것 입니다. 


(2) if문 

그럼 이제 if문을 진짜로 공부해 보죠. 

if문의 사용법은 가장 기본적인 형태가 


if(조건) 

{ 

/* 하나 이상의 C언어 문장 */ 

. 

. 

} 


이것 입니다. 

만약 조건이 만족되면 {}안의 문장들을 실행하는 것이죠. 

여기서 조건은 관계형 연사자에 의해 만들어진 

조건이어도 되고 

참과 거짓을 나타내는 값이어도 됨니다. 

즉 조건에 어떤 변수를 넣어도 되는데, 

그럴때는 변수가 0이면 거짓으로 인식하고 

0이 아니면 참으로 인식합니다. 

예제를 보죠. 


/* 파일 이름 : C7-1.C 

프로그램 내용 : if문 예제.. */ 

#include 

void main() 

{ 

int a=10; 

if(a==10) 

{ 

printf("A = 10\n"); 

} 

if(a) 

{ 

printf("A = True\n"); 

} 

if(!a) 

{ 

printf("A = False\n"); 

} 

} 


다음 프로그램의 결과는 어떻게 나올까요? 

당연히 "A = 10"이라는 문장이 출력되겠죠? 

그리고 "A = True"란 문장도 이유는 a가 10이므로 

a==10이라는 조건은 참이 됨니다. 

그러므로 그 안에 문장을 실행시키게 되는 것이죠. 

두번째의 if문에서 a는 0이 아니므로 그것도 역시 참이 됨니다. 

하지만 세번째 if문에선 !a라는 조건을 주었는데 

!연산자는 NOT연산자로 참을 거짓으로 거짓을 참으로 바꾸는 

연산자라고 배워습니다. 

a는 참인데 !를 붙이면 거짓이 되므로 그 안에 문장은 실행되지 않죠. 

이 예제에서 처럼 {}안에 문장이 하나밖에 없을때는 

{}로 묶지 않아도 됨니다. 그러니까 


if(a==10) 

printf("A = 10\n"); 


이렇게 써도 된다는 것이죠. 


(3) if-else문 

if문은 위와 같이 어떤 조건이 만족되면 특정 부분을 실행합니다. 

그런데 그 조건이 만족되지 않을때도 특정 부분을 실행해 줄수는 없을까요? 

당연히 할수 있죠. C로는 못하는게 없으니.. 

그때는 else라는 걸 씁니다. 

이때는 


if(조건) 

{ 

/* A부분 */ 

. 

. 

} 

else 

{ 

/* else부분 */ 

. 

. 

} 


이런 구조를 갖죠. 

여기서 조건이 참이면 A부분을 실행하고, 그렇지 않으면 

else부분을 실행합니다. 

예제를 보죠 


/* 파일 이름 : C7-2.C 

프로그램 내용 : if-else 문 예제.. */ 

#include 

void main() 

{ 

int a=0; 

if(a) 

{ 

printf("True\n"); 

} 

else 

{ 

printf("False\n"); 

} 

} 


이 예제에서도 if의 {}안에 문장이 한개이므로 

{}를 생략해서 


/* 파일 이름 : C7-3.C 

프로그램 내용 : if-else 문 예제.. */ 

#include 

void main() 

{ 

int a=0; 

if(a) 

printf("True\n"); 

else 

printf("False\n"); 

} 


이렇게 써도 됨니다. 

그럼 이 프로그램의 결과는 어떻게 나올까요? 

False가 출력 되겠죠? 

이유는 a가 참이 아니므로 그렇게 되는 것이죠. 


(4) if-else if-else문 

만약 여러 조건별로 실행을 다르게 하려면 어떻게 할까요? 

즉 A라는 조건이 만족하면 A부분을 B라는 조건이 만족하면 

B부분을.... 

이렇게 여러가지 조건 별로 말입니다. 

이럴땐 else if를 씀니다. 

사용법은 


if(조건A) 

{ 

/* A부분 */ 

. 

. 

} 

else if(조건B) 

{ 

/* B부분 */ 

. 

. 

} 

. 

. 

else 

{ 

/* else부분 */ 

} 


이런 식으로 사용하죠. 

여기서 조건A가 참이면 A부분을, 조건B가 참이면 B부분을.. 

이렇게 계속 나가다가, 어떤 조건에도 만족하지 않으면, 

else부분을 실행합니다. 

이때 else부분은 생략해도 됨니다. 

그때는 어떤 조건에도 만족하지 않으면, 아무것도 실행하지 않게 

됨니다. 

그럼 예제를 


/* 파일 이름 : C7-4.C 

프로그램 내용 : if-else if-else문 예제.. */ 

#include 

void main() 

{ 

int a=2; 

if(a==1) 

printf("A = 1\n"); 

else if(a==2) 

printf("A = 2\n"); 

else if(a==3) 

printf("A = 3\n"); 

else 

printf("Error!\n"); 

} 


이걸 실행하면. 결과는 무엇일까요? 

A = 2가 나오겠죠? 

왜 그런지는 다 아시죠? 구지 설명할 필요 없는것 같군요. 

그럼 예제 하나 더.. 이번엔 else를 생략한 걸로 


/* 파일 이름 : C7-5.C 

프로그램 내용 : if-else if문 예제.. */ 

#include 

void main() 

{ 

int a=4; 

if(a==1) 

printf("A = 1\n"); 

else if(a==2) 

printf("A = 2\n"); 

else if(a==3) 

printf("A = 3\n"); 

} 


이거의 실행 결과는 아무것도 출력되지 않습니다.. 

참이 되는 조건이 없기 때문이죠. 


이것으로 if문에 대한 설명은 마치도록 하죠. 


2. switch문 

이번엔 switch문에 대해 알아 보죠. 

switch문은 어떤 특정한 변수 또는 식의 값에 따라 

특정 부분을 실행하는 것 입니다. 


기본적인 사용법은 


switch(식) 

{ 

case 값A: 

. 

. 

break; 

case 값B: 

. 

. 

break; 

. 

. 

} 


이렇습니다. 

여기서 식에는 상수, 변수, 수식 어느것도 다 들어갈수 있습니다. 

만약 식의 값이 값A이면 case 값A:에서 break가 나올때까지 실행하고 

식의 값이 값B이면 case 값B:에서 break가 나올때까지 실행합니다. 

예를 들어 보죠 


/* 파일 이름 : C7-6.C 

프로그램 내용 : switch문 예제.. */ 

#include 

void main() 

{ 

int a=1; 

switch(a) 

{ 

case 1: 

printf("A = 1\n"); 

break; 

case 2: 

printf("A = 2\n"); 

break; 

} 

} 


이걸 실행하면 A = 1이 출력됨니다. 

이유는 a가 1이기 때문에 

case 1:부터 break가 나올때 까지 실행하면 그게 출력되기 때문이죠. 

여기서 break는 중요합니다. 

만약 case 1:에 break가 없다면 


/* 파일 이름 : C7-7.C 

프로그램 내용 : switch문 예제.. */ 

#include 

void main() 

{ 

int a=1; 

switch(a) 

{ 

case 1: 

printf("A = 1\n"); 

case 2: 

printf("A = 2\n"); 

break; 

} 

} 


이렇게 되어 있다면 결과는 어떻게 될까요? 

break가 가장 밑에 있으므로. 

거기까지 실행해서 A = 2까지 출력이 되게 됨니다. 

만약 break가 하나도 없다면 switch문이 끝날때까지의 모든 문장을 실행합니다. 

그러므로 break를 빼먹으면 절대로 않되죠. 

어떤 if문은 switch문으로 쓰면 더 간결해 지는데 

예를 들어 다음과 같은 프로그램. 


/* 파일 이름 : C7-8.C 

프로그램 내용 : if문 예제. */ 

#include 

void main() 

{ 

int a=4; 

if(a==1) 

printf("One\n"); 

else if(a==2) 

printf("Two\n"); 

else if(a==3) 

printf("Three\n"); 

else if(a==4) 

printf("Four\n"); 

else if(a==5) 

printf("Five\n"); 

} 


이런 프로그램은 switch문으로 고치는게 보기에 쉽습니다. 

switch문으로 고치면 


/* 파일 이름 : C7-9.C 

프로그램 내용 : switch문 예제. */ 

#include 

void main() 

{ 

int a=4; 

switch(a) 

{ 

case 1: 

printf("One\n"); break; 

case 2: 

printf("Two\n"); break; 

case 3: 

printf("Three\n"); break; 

case 4: 

printf("Four\n"); break; 

case 5: 

printf("Five\n"); break; 

} 

} 


보기가 좀 쉽워졌죠? 

즉 하나의 변수를 값 별로 특정 문장을 실행할땐 

if문보다 switch문이 더 좋다는 것이죠. 


이렇게 switch문은 if문을 대신할수도 있는데, 

if문의 else문..즉.. 아무것에도 해당하지 않을때 

실행하는 부분은 어떻게 만들까요? 

이건 default라는 걸 사용해 만듬니다. 

사용법은 


switch(식) 

{ 

case 값A: 

. 

. 

break; 

case 값B: 

. 

. 

break; 

. 

. 

default: 

. 

. 

break; 

} 


이런 식으로 씀니다 

만약 식이 어떤 값에도 해당하지 않으면 

default아래에 나오는 것들을 실행해 주죠.. 

예제를 봅시다. 


/* 파일 이름 : C7-10.C 

프로그램 내용 : switch문 예제. */ 

#include 

void main() 

{ 

int a=4; 

switch(a) 

{ 

case 1: 

printf("One\n"); break; 

case 2: 

printf("Two\n"); break; 

case 3: 

printf("Three\n"); break; 

default: 

printf("Another value\n"); break; 

} 

} 


이 프로그램의 결과로는 Another value 가 출력되겠죠? 

a가 어떤 값에도 해당하지 않으니.. 


이정도로 switch문의 설명도 마치도록 하죠. 


3. for문 

for문은 어떤 특정 부분을 반복해서 실행할때 사용합니다. 

for문의 사용법은 


for(수식1;조건;수식2) 

{ 

문장들.. 

} 


이런 구조 입니다. 

수식1은 for문일 시작하기 전 한번 실행하는 것으로 

보통 카운터 변수를 초기화 할때 씁니다. 

그리고 수식2는 for문 내의 문장들을 반복해서 실행할때마다 

한번씩 실행해 주는 수식으로 보통 카운터를 증가 시키거나 

감소 시킬때 사용합니다. 

for문은 조건이 만족할때 까지만 {}안의 문장을 반복해 실행해 줌니다. 

그냥 보면 저걸로 어떻게 반복문을 만들수 있는지 이해가 

잘 안 가실 거지만 예제를 보시면 이해가 되실 겁니다. 


/* 파일 이름 : C7-11.C 

프로그램 내용 : for문 예제. */ 

#include 

void main() 

{ 

int i; 

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

printf("%d ",i); 

} 


아주 간단한 예제 이지만 이걸 실행하면 1부터 100까지 출력이 됨니다. 

프로그램을 잘 살펴보며 어떻게 반복이 되는지 알아보죠. 

우선 카운터로 쓸 변수 i를 정의 했습니다. 

그리고 for문이 있는데, 

처음에 한번만 실행되는 수식으로 i에 1을 넣어 초기화 했습니다. 

그리고 나서 i<=100인지 확인하죠. 그런데 이건 참이므로 

for문 다음에 다오는 {}안의 문장들을 실행합니다. 

for문 역시 반복실행할 문장이 하나이면 {}를 생략해도 됨니다. 

그래서 여기선 생략했습니다. 이 문장은 i를 출력하고 있죠. 

그러므로 처음엔 1이 출력됨니다. 

이 문장 실행 후 i++를 실행합니다. 그래서 i가 2가 되죠. 

그리고 나서 i<=100인지 검사해 다음에 나올 문장을 실행하죠 

또 참이므로 i를 출력해 이번에 2가 출력되죠. 

이런 식으로 계속 반복해 i가 101이 되면 for문이 끝나게 되죠.. 

이번 방법으로 for문을 통해 반복문을 만듬니다. 

그리고 for문 안에 for문이 들어가도 상관 없습니다. 


for문 안에서 쓸수 있는 키워드가 두가지 있는데 

continue와 break입니다. 

continue는 continue다음에 나오는 문장들은 다 무시하고 

다시 for문의 처음으로 돌아가 실행을 계속하는 것이죠. 

예를 들어 보죠.. 


/* 파일 이름 : C7-12.C 

프로그램 내용 : for문 예제. */ 

#include 

void main() 

{ 

int i; 

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

{ 

if(i%2==0) continue; 

printf("%d ",i); 

} 

} 


우선 이걸 자세히 보면 i%2==0일때 continue가 실행되는 것을 알수 있습니다. 

i%2가 0일때는 i가 2의 배수일 때 인데.. 그때 continue를 하면 

밑에 i를 출력하는 문장은 무시되고 그냥 넘어가기 됨니다. 

그러므로 이 예제를 실행하면 1부터 100까지 중 2의 배수가 아닌 수만 

출력하게 되죠. 


break는 for문을 빠져 나오는 기능을 합니다. 

이것두 예를을 보면 쉽게 이해가 되실 겁니다. 


/* 파일 이름 : C7-13.C 

프로그램 내용 : for문 예제. */ 

#include 

void main() 

{ 

int i; 

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

{ 

if(i==51) break; 

printf("%d ",i); 

} 

} 


이 프로그램을 보면 i가 51일때 break를 했는데 

그러면 for문을 바져 나오므로 1부터 50까지만 출력이 되다가, 

for문을 빠져 나와 버립니다. 




오늘은 흐름 제어중 반복문에서 

저번에 하지못한 while와 do-while에 대해 공부하겠습니다. 




2. while문 

우선 while문에 대해 알아보죠. 

while문은 for문처럼 반복문이지만 for문보다 사용법은 간단합니다. 

우선 사용법을 알아보죠. 


while(조건) 

{ 

/* 하나 이상의 C언어 문장 */ 

. 

. 

} 


이렇게 사용하는데, 여기서 조건이 만족하는 동안만 

while문 내의 문장들을 실행합니다. 

이거 역시 문장이 하나이면 {}를 생략할수 있습니다. 

그럼 예제를 볼까요? 


/* 파일 이름 : C8-1.C 

프로그램 내용 : while문 예제.. */ 

#include 

void main() 

{ 

int a=1; 

int total=0; 

2 

while(a<=100) 

{ 

total+=a; 

a++; 

} 


printf("%d\n",total); 

} 


while문을 보면 

a<=100일때 까지만 반복하는 반복문 입니다. 

while문 안에를 보면 

total+=a를 하고 있는데, 이건 total=total+a라는것은 

언젠가 설명 했고 이걸 실행 한 후에 a++로 a를 

1증가시키고 있습니다. 

이렇게 계속 되다 보면 total=total+1, total=total+2... 

이렇게 계속 실행이 되겠죠? 

그래서 나중엔 1부터 100까지의 합이 total에 들어가고 

그것이 출력되게 되죠. 그러므로 5050이 출력됨니다. 




3. do-while문 

그럼 이번엔 do-while문에 대해 알아보죠. 

do-while문도 while문과 비슷하지만. 

이건 조건이 밑에 있다는 것이 다름니다. 

우선 사용법을 보죠. 


do 

{ 

/* 하나 이상의 C언어 문장 */ 

. 

. 

} while(조건); 


이렇게 사용합니다. 

이것은 처음에 문장들이 실행 된 후, 

조건이 만족하면 또 실행시키고 하는 식으로 실행됨니다. 

while문에서는 처음부터 조건이 만족하지 않으면 

한번도 실행되지 않지만, do-while문은 처음부터 조건이 

만족하지 않더라도 최소한 한번은 실행이 됨니다. 


/* 파일 이름 : C8-2.C 

프로그램 내용 : do-while문 예제.. */ 

#include 

#include 

void main() 

{ 

int yn; 

do 

{ 

printf("Continue(Y/N)?"); 

yn=getche(); 

putchar('\n'); 

}while(yn!='Y' && yn!='N'); 

} 


이 프로그램은 "Continue(Y/N)?"이라는 메시지를 출력하고 

Y또는 N이 입력되면 종료되고 다른 것이 입력되면 

계속 입력을 받는 것 입니다. 

잘 분석해 보시면 왜 그렇게 되는지는 쉽게 아실수 있을겁니다. 




4. goto문 

goto문은 사실 강좌에 넣으려고 하지 않았지만, 

그래도 C의 일부분 이므로 설명은 드리죠. 

goto문은 특정 라벨로 뛰어 넘어 버리는 기능을 합니다. 

사용법은... 


goto 라벨; 


이렇게 사용하죠. 

여기서 라벨은 같은 함수 내에 존재해야 합니다. 

라벨의 정의는 이렇게 하죠. 


라벨명: 


라벨명은 함수명이나 변수명과는 겹쳐도 상관 없고 

서로 함수가 다르다면 라벨명이 겹쳐도 됨니다. 

하지만 같은 함수 내에서 라벨명이 겹쳐서는 않되며, 

라벨명도 심볼과 같은 규칙에 따라 지어져야 하죠. 

즉 라벨명의 첫문자는 반드시 영문자 또는 언더스코어(_)가 와야 하고, 

그 뒤로는 영문자, 숫자, 언더스코어만 올수 있다는 것이죠. 

또한가지 라벨을 정의할때는 뒤에 :를 붙이지만, 

goto문에서 라벨을 쓸때는 이걸 쓰면 않된다는 것 입니다. 

예를 들어 


Label: 


이런 라벨이 있을때 


goto Label:; 


이렇게 해서는 않되고, 


goto Label; 


이렇게 해야 한다는 것 입니다. 

goto문은 C같은 구조화 프로그래밍 언어 에서는 

거의 쓸모가 없습니다. 또한 대부분의 C 프로그래머들은 

goto문의 사용을 꺼려하고 있습니다. 

이유는 goto문을 많이 사용할 경우 프로그램을 보기가 힘들어지고 

복잡해 보이기 때문이죠. 

그러므로 되도록 goto문의 사용은 줄이고, 함수나 C언어의 강력한 

제어문들을 사용해 프로그래밍을 하는 습관을 들여야 합니다.