3.2 산술연산자와 부호연산자    [DOC]    [SMTS]

 산술 연산자는 덧셈, 뺄셈 등 산술 연산을 수행하는 연산자들이고 부호 연산자는 부호를 지정하는 것들이다. 산술 연산자는 피연산자가 두 개이므로 이항 연산자이고 부호 연산자는 피연산자가 하나이므로 단항 연산자에 해당된다.


 사칙 연산자 +, -, *, /, % 는 덧셈, 뺄셈, 곱셈, 나눗셈 그리고 나눗셈의 나머지를 구하는 연산을 수행하는 이항 연산자이다. 예를 들면 다음과 같다.


int ia = 11, ib = 22, ic, id, ie;
ic = 1a + ib;
id = ia – ib;
ie = ia * ib;
double da = 1.1, db=2.2;
da = ie*ie;
db = da/ia;

 부호 연산자는 어떤 값의 부호를 지정하거나 바꾸는데 쓰인다. 여기서 +, -기호는 부호 연산자로도 사용되며, 부호 연산자는 한 개의 피연산자를 요구하는 단항 연산자이다.  예를 들면 다음과 같다.


+1234   -1234   -temp   +a   -b

따라서 다음과 같은 표현식에서 첫 번째 ‘-’는 부호연산자이고 두번째 ‘-’는 산술연산자이다.


ia = -ib - ic;

연산의 결과를 변수에 저장할 때는 결과 값이 그 변수의 허용 범위에 들어가는지 여부를 잘 판단해야 한다.


int ia = 2000000;
int ib = ia*10;
char ca = 129; // 오류
unsigned short usa = 50000, usb;
usb = usa + 20000; // 오류 발생

 나머지(%)연산의 예를 들면 다음과 같다.


10%5 // 0
3%2 // 1
8%3 // 2
3%5 // 3

한 가지 주의할 점은 %연산자의 피연산자는 정수형만 가능하다는 점이다. 예를 들어서,


a = b % c

는 변수 a에 변수 b값을 c로 나눈 나머지를 대입하는 것인데 변수 b와 변수 c는 정수형(char, short, int, long, long long과 각각의 unsigned 형)이어야 한다는 것이다.


다음 예제는 사용자로부터 하나의 숫자를 입력받아서 2로 나눈 나머지를 출력해 주는 프로그램이다.


ex03-01.c
#include <stdio.h>
int main(int argc, char** argv)
{
  int ia;
  scanf("%d", &ia); //정수를 입력받는다.
  printf("result:%d", ia%2);
}

실행 결과

123
result:1

이 예제에서 scanf()함수는 전에 설명한 대로 사용자로부터 입력을 받는 기능을 한다.  첫 번째 인수로 “%d”로 지정하면 정수를, “%f”로 지정하면 실수를 입력받아서 그 뒤의 변수에 그 값을 저장한다. 변수명 앞에 변수의 주소를 구하는 ‘&’를 꼭 붙여야 되므로 유의하자.


다음 예제는 두 수를 입력받아서 덧셈, 뺄셈, 곱셈, 나눗셈의 결과를 표시해 주는 프로그램이다.


ex03-02.c
#include <stdio.h>
int main(int argc, char** argv)
{
  float fa, fb;
  scanf("%f %f",&fa ,&fb); //두 수를 입력받는다.
  printf("fa+fb=%f\n", fa+fb);
  printf("fa-fb=%f\n", fa-fb);
  printf("fa*fb=%f\n", fa*fb);
  printf("fa/fb=%f\n", fa/fb);
}

1e5
12.34
fa+fb=100012.340000
fa-fb=99987.660000
fa*fb=1234000.015259
fa/fb=8103.727615

키보드로 숫자들을 입력할 때 공백 문자(스페이스바 혹은 엔터키)로 두 수를 입력해야 함에 유의하자.


 변수를 사용할 때에는 항상 저장할 수 있는 범위를 고려하여야 한다. 또한 나눗셈의 경우 0으로 나누는 경우가 발생하지 않는지 검토해 보아야 한다. 다음 예제를 실행시켜 보자. (변수명을 타이핑 할 때 대소문자를 반드시 정확히 입력해야 한다.)


ex03-03.c
#include <stdio.h>
int main(void)
{
   char cA = 123, cB = 10, cC = -100, cR1, cR2;
   unsigned char ucW = 110, ucX = 100, ucY = 200;
   unsigned char ucR1, ucR2;
   short sA = 1234, sB = 100, sR1, sR2;
   cR1 = cA + cB + cC;
   cR2 = cA / cB;
   ucR1 = ucW - ucY;
   ucR2 = ucX * ucY;
   sR1 = sA/sB;
   sR2 = sA%sB;
   printf("cR1=%d, cR2=%d\n", cR1, cR2);
   printf("ucR1=%d, ucR2=%d\n", ucR1, ucR2);
   printf("sR1=%d, sR2=%d\n", sR1, sR2);
}

실행 결과

cR1=33, cR2=12
ucR1=166, ucR2=32
sR1=12, sR2=34

이 예제에서는 ucR1과 ucR2 변수의 결과값이 unsigned char형의 범위를 벗어나므로 엉뚱한 값이 표시됨을 눈여겨봐야 한다.


'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 논리 연산자  (0) 2015.05.19
3.4 관계 연산자  (0) 2015.05.19
3.3 형변환  (0) 2015.05.19
C/C++의 연산자 종류  (0) 2015.05.19
C/C++의 goto 명령  (0) 2015.05.19
Posted by 살레시오
,

3.3 형변환    [DOC]    [SMTS]

 산술 연산에서 한 가지 주의할 점은 두 피연산자의 자료형이 다를 경우이다. 이 경우 결과값의 데이터형이 어떤 것이 되느냐가 문제가 될 수도 있다. 먼저, 같은 형끼리의 연산은 결과값도 바로 그 데이터형이 된다.


5/4 // 1 (정수/정수 ➜ 정수)
3/2 // 1 (정수/정수 ➜ 정수)
5.0/4.0 // 1.25 (실수/실수 ➜ 실수)
3.0/2.0 // 1.5 (실수/실수 ➜ 실수)

위 예에서 보듯이 정수형끼리의 나눗셈의 결과도 정수형이 됨에 유의해야한다. 즉, 2/2 는 1.5가 아니라 1이 된다.


 그리고 정수형과 실수형 간 사칙연산 결과는 실수형이 된다는 사실에 유의해야 한다. 즉, 피연산자 중에 하나라도 실수형이라면 결과값도 실수형이 된다.


5.0/4 ➜ 1.25 (실수/정수 ➜ 실수)
2/4.0 ➜ 0.5 (정수/실수 ➜ 실수)

다음 예제에서 이를 확인해 보자


ex03-04.c
#include <stdio.h>
int main()
{
  int ia = 10, ib = 4;
  float fa, fb = 4.0f, fc;
  fa = ia/ib; // (1)
  fc = ia/fb; // (2)
  ib = ia/fb; // (3)
  printf("fa=%f, fc=%f, ib=%d\n", fa, fc, ib);
}

실행 결과

fa=2.000000, fc=2.500000, ib=2

위의 실행 결과에서 변수 fa와 fc값이 왜 다른지 잘 이해해야 한다. (1)에서는 정수/정수이므로 결과값이 먼저 정수형으로 산출된다. 이 값이 실수형으로 형변환되어 실수형 변수 fa에 저장되는 것이다. 그러나 (2)에서는 정수/실수 이므로 결과값이 실수형으로 산출된다. 따라서 정확하게 계산된 값이 실수형 변수 fc에 대입되는 것이다. (3)의 경우는 계산 결과는 실수인데 정수형 변수 ib에 그것을 대입하도록 하였다. 이경우 실수는 정수로 자료형이 변환되며 소수점 이하는 버려진다. 그래서 2.5에서 소수점 이하는 버려진 2 라는 정수값이 ib에 대입되는 것이다.

3.3.1 자동 형변환 (automatic conversion)

 자동 형변환은 이와 같이 산술 연산에서 두 피연산자의 형이 다를 경우 둘 중 더 넓은 자료형으로 다른 하나가 자동으로 변환되는 것을 말한다. 다음에서 오른쪽으로 갈수록 더 넓은 자료형이다.


char < short < int < long < long long < float < double < long double

예를 들어 만약 a + b 에서 a가 long형, b가 double 형이라면 a가 더 넓은 double형으로 자동으로 변환 된 후 덧셈이 수행된다. char형과 long형이라면 둘 다 long형이 된다. 그리고 계산 결과는 항상 넓은 자료형이 된다. 만약 하나는 unsigned 형이고 다른 하나는 signed형이라면 결과를 예측할 수 없으므로 이런 경우는 가급적 피하여야 한다.

3.3.2 명시적인 형변환 (casting)

 사용자가 자료를 명시적으로 형변환해야 할 경우도 있다. 예를 들어서 int형 ia를 long형으로 바꾸고 싶다면 다음과 같이 변수 앞에 (자료형)을 붙여주면 된다.


(long)ia

변수 ia 자체는 변하지 않지만 (long)ia 는 long형 자료가 된다.


int ia=2, ib=4;
float fa = ia/ib;
float fb = (float)ia/ib;

이 예에서 fa 는 0.0 이 fb에는 0.5 가 저장된다. 왜냐면 ia/ib는 둘다 정수이기 때문에 결과값도 정수가 된다. 따라서 소수점 이하가 버려진다. 하지만 (float)ia/ib는 하나는 float형이고 다른 하나는 int 형이므로 ib가 float형으로 자동 형변환 되고 결과값도 float형이 된다. 따라서 정확한 실수값인 0.5가 저장되는 것이다.


 명시적 형변환의 다른 예를 들면 다음과 같다.


(long)(‘a’+2.0f)
fa = (float)((int)ia +1)
da = (double)sa/5

명시적 형변환의 우선 순위는 산술 연산보다 높다는 것도 알아두자.


'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

3.4 관계 연산자  (0) 2015.05.19
3.2 산술 연산자와 부호 연산자  (0) 2015.05.19
C/C++의 연산자 종류  (0) 2015.05.19
C/C++의 goto 명령  (0) 2015.05.19
C/C++의 continue 명령  (0) 2015.05.19
Posted by 살레시오
,

 연산자(operator)는 주어진 데이터에 대해서 계산이나 비교 등을 수행하여 결과 값을 얻어내는 명령어를 말한다. C/C++ 에는 다양한 연산자가 마련되어 있으며 일반적으로 분류하면 다음 표와 같다.


[표 1] 연산자의 종류

구분

연산자

비고

산술 연산자

+  -  *  /  %

%는 나머지 연산자

부호 연산자

+  -

부호 표시

관계 연산자

<  >  <=  >=  ==  !=

대, 소, 등가 관계

논리 연산자

&&  ||  !

AND, OR, NOT

조건 연산자

? :

참, 거짓

증감 연산자

++  --

1증가, 1감소

대입 연산자

=

+=  -=  *=  /=  %=

&=  |=  ^=  <<=  >>=

오른쪽의 값을 왼쪽에 대입

비트 연산자

&  |  ~  ^  <<  >>

AND, OR, NOT, XOR, shift

형변환 연산자

(데이터형)

sizeof 연산자

sizeof

데이터 형의 크기

쉼표 연산자

,

구분

간접 지정 연산자

( ) [ ] -> *

함수, 배열, 구조체, 포인터


연산의 대상이 되는 수치나 변수 값을 피연산자라고 하며, 연산자는 피연산자의 개수에 따라서 이항(二項) 연산자와 단항(短項) 연산자로 나뉜다.


  • 피연산자 : 연산의 대상이 되는 수치나 변수.

  • 이항 연산자 : 피연산자가 두 개인 연산자.

  • 단항 연산자 : 피연산자가 하나인 것.


예를 들어서 덧셈(+)이나 뺄셈(-)은 피연산자가 하나이면 연산을 수행하지 못하고 반드시 두 개가 있어야 그 두 수를 더하거나 뺄 수 있으므로 이항 연산자이다. 이에 반해서 부호연산자(+. -)는 하나의 항의 부호를 규정하는 것이므로 피연산자가 하나이고 단항 연산자이다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0041}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

3.2 산술 연산자와 부호 연산자  (0) 2015.05.19
3.3 형변환  (0) 2015.05.19
C/C++의 goto 명령  (0) 2015.05.19
C/C++의 continue 명령  (0) 2015.05.19
C/C++의 break 명령  (0) 2015.05.19
Posted by 살레시오
,

4.8 goto 명령     [doc]      [smts]

 프로그램 중간에 주소(이름)을 만들어 지정해 주고 goto문을 사용하여 그 지점으로 한 번에 프로그램 수행을 이동할 수 있다.


label:
  .....
  ......
  goto label;

goto 명령은 원하는 곳으로 무조건 이동을 수행한다. 아무 곳으로라도 즉시로 이동할 수 있어 일견 굉장히 편하고 유용한 명령어처럼 보이나 프로그램의 구조를 저해하는 문제점을 내포하고 있어서 일반적으로 잘 쓰이지 않는 명령어이다. 대부분의 경우는 break, continue와 같은 명령어를 이용하여 문제를 해결할 수 있기 때문이다.


하지만 다중루프를 한 번에 빠져나가야 하는 경우에는 break문을 복잡하게 사용하기보다는 goto문이 쓰이기도 한다. 아래의 예를 살펴보자.


  for(...) {
      for (...) {
          for(...) {
              if (...) goto OutOfHere;
          }
      }
  }
OutOfHere:
  ......
  ......

 하지만 goto문은 실제 프로그램에서 거의 쓰이지 않으므로 구체적인 예제는 생략한다.



'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

3.3 형변환  (0) 2015.05.19
C/C++의 연산자 종류  (0) 2015.05.19
C/C++의 continue 명령  (0) 2015.05.19
C/C++의 break 명령  (0) 2015.05.19
C/C++ 의 do ~ while 반복문  (0) 2015.05.18
Posted by 살레시오
,

4.7 continue 명령     [doc]     [smts]

반복문 안에서 사용되는 continue 명령은 그 뒤의 모든 실행문을 무시하고 반복문의 처음으로 돌아가서 다음 단계를 수행한다.


반복명령어(for, do, while) {
  명령문1;
  continue;
  명령문2;
}

위에서 프로그램이 continue를 만나면 아래의 명령문2를 수행하지 않고 반복문의 다음 단계로 돌아간다. for문의 경우 변환문을 실행한 후 조건 검사를 하여 참이면 다시 반복을 시작할 것이고 while문은 조건 검사를 수행할 것이다.


for (int k=0; k<10; k++) {
   printf(“Hi “);
   continue;
   printf(“there. “);
}
int k=0;
while(k++ <= 10) {
   printf(“Hi “);
   continue;
   printf(“there. “);
}

이 예제를 수행하면 첫 번째 printf() 함수만 실행되므로 “Hi “만 열 번 화면에 출력될 것이다. continue 명령에 의해서 그 뒤의 printf()는 실행되지 않기 때문이다.


 다음 예는 0부터 100까지의 정수 중 3의 배수가 아닌 것들만 출력하는 프로그램이다.


0407-01.c

#include <stdio.h>
int main() {
   for (int ia=0; ia<=100; ia++) {
       if (ia%3 == 0) continue;
       printf("%d ",ia);
   }
}

실행 결과

1 2 4 5 7 8 10 11 13 14 16 17 19 20 22 23 25 26 28 29 31 32 34 35 37 38 40 41 43 44 46 47 49 50 52 53 55 56 58 59 61 62 64 65 67 68 70 71 73 74 76 77 79 80 82 83 85 86 88 89 91 92 94 95 97 98 100


만약 ia%3==0 이 참, 즉 ia가 3의 배수라면 continue 문에 의해 밑의 printf() 함수는 실행되지 않고 다음 단계로 넘어간다.


보통은 조건문과 조합하여 특정 조건이 만족되면 반복문의 시작으로 되돌아가게끔 하는데 사용한다. 다음 예제는 1000 이하의 가장 큰 소수(prime number)를 구하는 것이다.


0407-02.c
#include <stdio.h>
int main() {
  for (int ia = 1000; ia>=2; ia--) {
      int ib = 2;
      while( ib <= ia/2 ) {
          if (ia%ib == 0) break;
          ib++;
      }
      if (ib <= ia/2) continue;
      printf("result: %d\n", ia);  //❷
      break;
  }
}

997


반복 변수 ia가 1000 부터 시작하여 1씩 감소하면서 그 수 가 소수인지 아닌지를 판별하는 것이다. while 반복문으로 2부터 ia/2 까지의 수로 모두 나눠보고 중간에 나누어 떨어지는 경우가 있다면 반복문을 종료한다. 만약 ia가 소수가 아니라면 ib<=ia/2 이 참이므로 다음 수로 넘어간다. 아니라면 (즉, ia가 소수라면) 결과를 표시하고 for 반복문을 빠져나온다.


 break문이 반복문을 완전히 빠져나가게 하는 것이고 continue문은 반복문을 계속 수행하게 한다는 것을 잘 구별해야 한다.



'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 연산자 종류  (0) 2015.05.19
C/C++의 goto 명령  (0) 2015.05.19
C/C++의 break 명령  (0) 2015.05.19
C/C++ 의 do ~ while 반복문  (0) 2015.05.18
C/C++ 의 while 반복문  (0) 2015.05.18
Posted by 살레시오
,

4.6 break명령     [doc]     [smts]

 break 명령은 전 절에서 소개한 switch 명령과 반복문 안에서만 쓰이며 이 명령을 만나면 그것을 둘러싸고 있는 가장 안 쪽의 반복문 하나를 빠져 나온다.


다음의 간단한 예를 보자.


0406-01.c
for (int ia=0; ia<10; ia++) {
printf(“%d\n”,ia);
if (ia==3)
break;
}

이 프로그램의 결과는


0

1

2

3


이다. 왜냐면 ia가 3이라면 break 명령이 수행되어 for반복문 밖으로 빠져나오기 때문이다.


0406-02.c
int ia;
while(1) {
scanf(“%d”,&ia);
if (ia==0)
break
else
printf(“you typed %d.”,ia);
}

이 예는 사용자가 입력한 정수가 0 이 되면 break 명령을 만나서 무한 루프를 빠져나오는 것이다.


 또 다른 예로 사용자로부터 숫자(정수)를 입력받는데 정해진 입력이 아니면 다시 입력하도록 하는 것을 생각해 보자. 가상의 로봇에 대한 입력이 1번, 2번, 3번만 있는 경우 나머지 경우에 대해서는 다시 입력하도록 하려면 다음 예 break_ex01 과 같이 반복문과 break명령을 조합하여 사용하면 된다.


0406-03.c
#include <stdio.h>
int main(void)
{
  char cIn;
  printf("1. Turn left.\n");
  printf("2. Turn right.\n");
  printf("3. Stop.\n ");
  printf("Choose one : ");
  while(1) {
      scanf("%d", &cIn);
      if (cIn==1 || cIn==2 || cIn==3)
          break;
      printf("Wrong! Input again : ");
  }
}

이 예를 보면 while 반복문 안에서 scanf()함수에 의해서 하나의 정수를 입력받게 되어 있다. 입력받은 정수가 1, 2, 혹은 3이라면 break명령에 의해서 바로 반복문을 빠져 나가고 아니라면 scanf()함수가 반복되어 호출되도록 되어 있다. 이렇게 함으로서 올바른 숫자가 입력될 때까지 반복해서 입력을 받게끔 할 수 있다.


1. Turn left.
2. Turn right.
3. Stop.
Choose one : 5
Wrong! Input again : 1

또 다른 예를 들어보자. 소수(prime number)란 1과 그 자신의 수로만 나누어 떨어지는 수이다. 1000이하의 소수 중 가장 큰 것을 찾는 프로그램을 작성하고자 한다고 하자. 이 경우는 1000부터 하나씩 줄어가면서 소수인지 아닌지를 판별하는 것이 나을 것이다.


0406-04.c
#include <stdio.h>
int main() {
  for (int ia = 1000; ia>=2; ia--) {
      int ib = 2;
      while(ib < ia/2 ) {
          if (ia%ib == 0) break;
          ib++;
      }
      if (ib == ia/2 +1) {                  //❶
          printf("result: %d\n", ia);  //❷
          break;
      }
  }
}

이 예제에서 for문 안을 눈여겨보자. while 반복이 끝나고 ❶번줄로 넘어왔을 때 ib 변수값이 (ia/2+1)과 같다면 while반복문이 그 안의 break문을 만나지 않고 종료되었다는 의미이므로 (즉, 이것은 ia를 2 ~ (ia/2) 사이의 값으로 나눴을 때 한 번도 0이 되지 않았음을 의미한다) ia는 소수이다. 따라서 이 경우 바깥쪽 for반복문도 빠져나가게끔 되어 있다. 만약 while 반복이 끝나고 ❶번 줄로 넘어왔을 때 ib 변수값이 ia와 같지 않다면 이것은 2~(ia-1) 사이의 값으로 나눴을 때 어디선가 나머지가 0이라는 말이므로 소수가 아니라는 뜻이다. 따라서 다음 ia값을 다시 검사해야 된다. for문 바깥인 ❷로 빠져 나간 후 ia값을 printf()함수에 의해서 화면에 표시한다.


 이 예제를 이해했다면 for, while, break 에 대해서 어느 정도 이해를 했다고 볼 수 있다.


'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 goto 명령  (0) 2015.05.19
C/C++의 continue 명령  (0) 2015.05.19
C/C++ 의 do ~ while 반복문  (0) 2015.05.18
C/C++ 의 while 반복문  (0) 2015.05.18
C/C++의 for 반복문  (0) 2015.05.18
Posted by 살레시오
,

4.5 do~while 반복문     [doc]     [smts]

반복문에 사용되는 do~while 의 문법은 다음과 같다.


do {
  실행문;
  ...
} while(조건문);

while문과 차이점은 do{...} 안의 실행문이 처음에 한 번은 무조건 실행된다는 것이다. 그 이후 while 뒤의 조건문을 체크하여 참이면 do{...} 블럭을 다시 수행하고 거짓이면 그대로 반복을 종료한다.  초보자가 주의할 점은 while()문 뒤의 세미콜론을 빠뜨리기 쉽다는 것이다.


 다음이 do-while문의 예인데 1부터 100까지의 합을 구하는 것으로서 결과는 앞의 예제들과 같다.


0405-01.c
int ia=1, isum=0;
do {
  isum += ia;
} while(ia++ < 100);

while 뒤의 조건문을 잘 파악하면 ia가 1부터 정확히 100까지 do 블럭을 반복한다는 것을 알 수 있다.


다른 예를 들어보자.


0405-02.c
#include <stdio.h>
int main() {
  int ia;
  printf(“Input a positive integer : “);
  do {
      scanf(“%d”, &ia)
  } while(ia<=0);
}

이 예는 사용자가 양의 정수를 입력할 때 까지 do 블럭 안의 scanf()함수를 실행한다.  왜냐면 0이나 음수를 입력하면 while 문 뒤의 조건문이 참이 되어 do 블럭을 다시 수행하기 때문이다. 양수가 입력되면 반복문이 종료된다.



'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 continue 명령  (0) 2015.05.19
C/C++의 break 명령  (0) 2015.05.19
C/C++ 의 while 반복문  (0) 2015.05.18
C/C++의 for 반복문  (0) 2015.05.18
C/C++ 의 switch ~ case 제어문  (0) 2015.05.18
Posted by 살레시오
,

4.4 while 반복문     [doc]     [smts]

while 반복문은 for문에 비해서 구조가 간단하다.


while (조건문) {
  실행문1;
  …
  실행문n;
}

while 명령 바로 다음에 오는 조건문이 참이면 중괄호 안의 명령어들이 수행되고 거짓이라면 while 문을 빠져 나가게 된다. 만약 조건이 참이어서 실행문들이 다 수행되고 난 후에는 다시 조건문을 검사하여 참이면 다시 수행한다.


조건문이 참이면 소속된 실행문을 수행하므로 다음 예는 무한 루프에 빠지게 된다.


while (1) {
printf(“hi\n”);
}

반면에 다음과 같은 반복문은 절대로 수행되지 않는다. 조건이 항상 거짓(0)이기 때문이다.


while (0) {
printf(“bye.\n”);
}

화면에 문자열 “hi”가 딱 10 번만 출력 되게 하려면 다음과 같이 외부 변수를 이용해야 할 것이다.


0404-01.c
#include <stdio.h>
int main() {
   int icnt = 0;
   while (icnt < 10) {
       printf("hi ");
       icnt++;
   }
}
실행 결과
hi hi hi hi hi hi hi hi hi hi

위의 프로그램은 다음과 같이 조금 더 간략하게 작성할 수 있다. while 반목문에 속한 실행문이 하나일 경우 중괄호를 생략할 수 있다.


0404-01b.c
#include <stdio.h>
int main() {
   int icnt = 0;
   while (icnt++ < 10) {
       printf("hi ");
   }
}
실행 결과
hi hi hi hi hi hi hi hi hi hi

 다음 예제는 1부터 100까지의 합을 구하는 것을 while문으로 구현한 것이다.


0404-02
#include <stdio.h>
int main() {
   int ia = 1, isum = 0;
   while (ia <= 100) {
       isum += ia;
       ia++;
   }
   printf("isum = %d", isum);
}
실행 결과
isum = 5050

for문과 비교해 보면 초기실행문이 while문 바깥에 나와 있고 변환식은 while문 안으로 들어가 있다. 이 예제는 다음과 같이 조금 더 간결하게 만들 수 있다.


0404-02
#include <stdio.h>
int main() {
   int ia = 1, isum = 0;
   while (ia <= 100) {
       isum += ia++;
   }
   printf("isum = %d", isum);
}
실행 결과
isum = 5050

반복문이 하나의 명령이라면 중괄호를 생략할 수 있다. 단항연산자 ++가 ia뒤에 붙었으므로 먼저 isum변수에 ia값을 더한 후 1이 증가함에 유의하자. 만약


isum += ++ia;

이렇게 바뀌면 어떻게 동작을 할 지 생각해 보라. 단항연산자 ++, --의 동작에 대해서 한 번 더 이해가 갈 것이다.

 또 다른 예로 1부터 숫자를 더해나갈 때 어느 수까지 더하면 10000이 처음으로 넘는지를 알아내는 프로그램을 작성해 보자. 이 경우 while 반복문을 사용하면 다음과 같이 간단하게 작성할 수 있다.


0404-03.c
#include <stdio.h>
int main() {
  int ia=0, isum=0;
  while(isum < 10000) {
      isum += ++ia;
  }
  printf("Sum from 1 to %d is %d.\n", ia, isum);
}
실행 결과
Sum from 1 to 141 is 10011.

이 예제에서는 ia=0으로 초기화 시킨 다음에 isum += ++ia 와 같이 ++연산자를 ia앞에 붙였다. 이렇게 해야만 정확한 결과가 얻어진다는 것을 유의해야 한다. (왜인지 생각해 보자.)



'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 break 명령  (0) 2015.05.19
C/C++ 의 do ~ while 반복문  (0) 2015.05.18
C/C++의 for 반복문  (0) 2015.05.18
C/C++ 의 switch ~ case 제어문  (0) 2015.05.18
C/C++ 의 if ~ else 조건 제어문  (0) 2015.05.18
Posted by 살레시오
,

4.3 for 반복문    [doc]    [smts]

프로그램에서 같은 코드를 변수값만 바꿔가며 반복해서 해야 하는 경우는 빈번하게 발생한다. 이런 경우를 위해서 반복문이 사용된다. C 언어에서 사용하는 반복문은 for 와 while 그리고 do~while 세 가지가 있으며 가장 많이 쓰이는 것은 for 반복문이다.


for (초기실행문; 반복조건; 변환문) {
  명령문1;
  …
  명령문n;
}

for문 이후의 블럭이 정해진 수만큼 반복해서 수행이 된다. 초기실행문은 반복을 시작할 때의 초기값을 설정하는 부분이다. 만약 10번 반복해야 하고 초기값이 0이라면 이 부분에 0을 설정하는 실행문이 들어가야 한다. 만약 반복조건이 거짓이 되면 그 순간 반복문을 빠져 나가게 된다. 변환문은 매 반복이 끝나고(즉 명령문n이 끝난 다음) 반복조건이 참일 때 수행되는 명령문이다. 여기서 변수의 값을 증가 혹은 감소시킨다든가 하는 실행문이 위치하게 된다.


 다음 예제를 보자


0403-01.c
#include <stdio.h>
int main() {
   int ia;
  for (ia=0; ia<10; ia++) {
      printf("count : %d\n", ia);
  }
}
실행 결과
count : 0
count : 1
count : 2
count : 3
count : 4
count : 5
count : 6
count : 7
count : 8
count : 9

이 예제는 단순히 화면에 0부터 9까지 출력하는 프로그램이다. for구문이 수행되는 단계를 기술하면 다음과 같다.


      ① 반복문에 진입하기 전에 초기 실행문은 한 번 수행된다.

      ② 조건식을 검사한다.

      ③ 조건식이 참이라면 반복명령문(들)을 실행한다.

      ④ 변환문을 수행한 후 ②로 돌아간다.


위의 예제에서는 변환문은 ia++ 이다. ia는 0부터 시작해서 10보다 작을 경우 루프를 돌며 반복문을 수행한다. 즉 10번 반복문을 수행한다.


초기 실행문에 아예 변수의 선언을 해도 된다.


0403-02.c

#include <stdio.h>
int main() {
  for (int ia=9; ia>=0; ia--) {
      printf("count : %d\n", ia);
  }
}

실행 결과

count : 9
count : 8
count : 7
count : 6
count : 5
count : 4
count : 3
count : 2
count : 1
count : 0

이 예는 앞의 경우와 반대로 10부터 1까지 카운트다운을 하는 프로그램이다. 이 경우 변수 ia는 반복문이 시작될 때 생성되고 반복문이 종료되면 소멸된다. 즉, 반복문이 종료되면 변수 ia는 사용할 수 없다. 단, 이 기능은 C99 이후부터 지원하므로 gcc 를 실행할 때 ‘-std=c99’ 옵션을 반드시 추가해야 한다. 만약 C++컴파일러를 사용한다면 (g++) 별다른 옵션 조절없이 이 기능을 사용할 수 있다.


 이제 for 반복문을 사용하여 1부터 100까지의 총합을 구하는 프로그램을 작성해 보자.


0403-03.c
#include <stdio.h>
int main(void)
{
  int isum = 0;
  for (int ia=1; ia<=100; ia++) {
      isum += ia;    
  }
  printf(“result: %d.\n”,isum);
}

for 문 뒤에 실수로 세미콜론을 붙이지 않도록 주의한다. 즉


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

  isum += ia;


이와 같이 되면 문법적으로는 오류가 없으나 의도하지 않게 반복문이 수행되지 않을 것이다. 또한 for문 뒤에 오는 명령어가 하나뿐이라면 중괄호{}를 생략할 수 있어 좀더 간결하게 프로그램을 작성할 수 있다.


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

  isum += ia;


하지만 반복문에 속한 명령문이 하나 뿐일지라도 중괄호로 포함해 주면 가독성 측면에서 좀 더 낫다.


 다른 예로 구구단을 출력하는 프로그램을 for 반복문을 이용하여 작성해 보자.


0403-04.c
#include <stdio.h>
int main() {
   int ia = 3;
   for (int ib=2; ib<10; ib++) {
       printf("%d x %d = %d\n",ia, ib, ia*ib);
   }
}

이 예제에서 변수 ia는 단수를 지정하며 다음과 같이 3단을 출력한다.



3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27

for문을 중첩해서 사용할 수 도 있다. 다음 예제는 2단부터 9단가지 출력하는 프로그램이다.


0403-05.c
#include <stdio.h>
int main() {
   for (int ia=2; ia<10; ia++) {
       for (int ib=2; ib<10; ib++) {
           printf("%d x %d = %d\n",ia, ib, ia*ib);
       }
       printf("------------\n");
   }
}

초기 실행문은 콤마(,)로 연결하여 여러 변수를 동시에 초기화시킬 수도 있다.


for (int ia=1, isum=0; ia<=100; ia++) {
  isum += iA;
}

초기실행문에서 선언된 변수는 반복문이 종료된 이후에는 사용할 수 없다. 즉, 이 경우 변수 ia와 isum은 반복문이 종료된 후 소멸되므로 사용할 수 없다. 변환문도 콤마로 구분하여 여러 변수를 동시에 변화시켜줄 수 있다. 또한 조건은 ||연산자나 &&연산자를 이용하여 다중 조건을 체크할 수도 있다. 혹은 리턴값을 가진 함수를 이용하여 그 값을 비교할 수도 있다.


 만약 isum 변수를 반복문 종료 후에도 사용하고 싶다면 반드시 for문 밖에서 선언해야 한다. 다음 예는 1부터 100까지의 합을 구하는 예이다.


0403-06.c
#include <stdio.h>
int main() {
   int isum = 0;
   for (int ia=1; ia<=100; ia++) {
       isum += ia;
   }
   printf("isum = %d", isum); // isum변수를 사용할 수 있다.
}
실행 결과
isum = 5050

   for 반복문 바깥에서 선언된 변수는 반복문이 종료된 이후에도 사용할 수 있다.



'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++ 의 do ~ while 반복문  (0) 2015.05.18
C/C++ 의 while 반복문  (0) 2015.05.18
C/C++ 의 switch ~ case 제어문  (0) 2015.05.18
C/C++ 의 if ~ else 조건 제어문  (0) 2015.05.18
C/C++ 포인터 사용시 주의할 점  (0) 2015.05.18
Posted by 살레시오
,

4.2 다중조건 분기문     [doc]    [stms]

 만약 if 명령으로 여러 가지의 경우를 따져서 수행하려고 하면 if ~ else 문이 다중으로 중첩되어 프로그램의 가독성을 떨어뜨린다. 예를 들어서 어떤 정수형 변수의 값이 0일 때, 1일 때, 2일 때, 등등에 수십 가지에 대해서 동작이 다르게 수행되어야 하는 경우 if ~ else 명령보다는 여기에서 소개할 switch ~ case 명령을 사용하는 것이 가독성이나 수행 속도 면에서 훨씬 효율적이다.


 switch ~ case 명령의 기본적인 문법은 다음과 같다.


switch (정수형변수) {
  case 값1:
      명령문1;
      break;
  case 값2:
      명령문2;
      break;
  ...
  default:
      명령문n;
      break;
}

switch명령 바로 다음에 오는 변수가 case 다음의 값1이나 값2에 해당하는 값이 있는지 판별한 후에 해당하는 값이 있으면 거기에 속한 명령문을 수행한다. case뒤에 오는 것은 반드시 하나의 값이어야 하며 조건이나 여러 값은 올 수 없다. 해당하는 값이 없을 경우에는 default 로 설정된 ‘명령문n’을 수행하게 된다. 필요에 따라 default문은 생략할 수도 있다.


 이 명령을 쓸 때 주의할 점은 다음과 같다.


  1. switch문 뒤에 오는 변수는 반드시 정수형 (char, short, int, long과 각각의 unsigned형) 이어야 한다

  2. case 에 포함된 명령어들의 끝에는 반드시 break문을 써야 한다.


 다음 예제는 정수(명령)를 하나 입력받아서 1이면 “Robot turned left.”이라고 표시하고, 2라면 “Robot turned right.”라고 표시하고 3이면 “Robot stopped.”이라고 표시한다. 만약 1, 2, 3중 아무 것도 아니라면 “illegal command.”라고 표시하는 간단한 프로그램이다. 흔히 하기 쉬운 실수가 case문이 끝나는 곳에 break문을 빼먹는 것인데 초보자들은 유의해야 한다.


ex04-08.c
#include <stdio.h>
int main() {
  int iA;
  printf("1. Turn left.\n");
  printf("2. Turn right.\n");
  printf("3. Stop.\n ");
  printf("Choose one :");
  scanf("%d", &iA);
  
  switch(iA) {
      case 1:
          printf("Robot turned left.\n");
          break;
      case 2:
          printf("Robot turned right.\n");
          break;
      case 3:
          printf("Robot stopped.\n");
          break;
      default:
          printf("Illegal command.\n");
          break;
  }
}

1. Turn left.
2. Turn right.
3. Stop
Choose one : 2
Robot turned right.
Press any key to continue...

이 예제와 같이 세 가지 정도는 if ~ else 문으로 구현해도 상관 없으나 경우의 수가 많아 지는 곳에는 switch ~ case 문이 훨씬 더 효율적이다.



Posted by 살레시오
,