bitwise - not 연산자 ~ 는 단항 연산자로 각 비트를 반전(toggle)시킨다. 즉 1은 0으로, 0은 1로 바꾼다.


표 3.5.4 비트not연산

x

~x

0

1

1

0


이 연산은 전체 비트에 대해서 수행된다. 예를 들면 다음과 같다.


unsigned char uca = 0b10101100, ucb;

ucb = ~uca; // 0b01010011 이 대입된다.


 다음 예제는 위의 네 가지 비트 연산(&, |, ^, ~)을 수행한 결과를 16진수로 보여주는 예제이다. 전 절에서도 소개한 바와 같이 printf()함수에서 정수를 16진수로 표시하는 서식 문자는 ‘%x’이다. 연습을 위해서 16진수 하나하나를 이진수로 바꾼 다음 손으로 연산을 수행해 보기를 권한다.


#include <stdio.h>
typedef unsigned char uchar;
int main(void)
{
  uchar ucA1 = 0xfa;
  uchar ucB1 = 0x3a;
  uchar ucC1 = 0xc1, ucC2;
  uchar ucD1 = 0xbb, ucD2 = 0xa8, ucD3;
  ucC2 = ~ucC1;
  ucD3 = ucD1^ucD2;
  printf("0x%x & 0xf0 = 0x%x\n", ucA1, ucA1 & 0xf0);
  printf("0x%x | 0x8c = 0x%x\n", ucB1, ucB1 | 0x8c);
  printf("~0x%x = 0x%x\n", ucC1, ucC2);
  printf("0x%x ^ 0x%x = 0x%x\n", ucD1, ucD2, ucD3);
}


0xfa & 0xf0 = 0xf0
0x3a | 0x8c = 0xbe
~0xc1 = 0x3e
0xbb ^ 0xa8 = 0x13


여기에서 typedef 명령에 의해서 unsigned char 형은 uchar 로 줄여서 사용할 수 있다. 즉, main()함수 내의 uchar 은 unsigned char 와 같다.


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


c{c++},n{c0053}

Posted by 살레시오
,

 비트 xor 연산자(^)는 두 피연산자의 같은 위치의 비트끼리 xor 연산을 수행한다. 두 비트의 xor 연산은 두 비트가 서로 다른 경우에는 1, 같은 경우는 0이다. 그 진리표는 다음 표와 같다.


[표 1] 비트 xor 연산

x

y

x⊗y

0

0

0

0

1

1

1

0

1

1

1

0


두 비트의 연산은 이해하기 쉬우나 세 개 이상의 비트들에 대해서 xor 연산을 수행하면 결과가 어떻게 될지 예측하기는 쉽지 않다. 다음 표에 세 비트의 xor 결과를 기록하였다.


[표 2] 세 비트의  xor 연산

x

y

z

x⊗y⊗z

0

0

0

0

0

0

1

1

0

1

0

1

0

1

1

0

1

0

0

1

1

0

1

0

1

1

0

0

1

1

1

1


일반적으로 n개 비트들의 xor 결과는 1의 개수가 홀수 개이면 1, 짝수 개이면 0이다. 위의 두 표에서도 이 규칙이 적용되므로 확인해 보기 바란다.


 다음 예제로 xor 연산 결과를 살펴보자.


unsigned char ucX = 0x3a, ucY = 0xb2, uCZ ;
ucZ = ucX ^ ucY;


이제 변수 ucZ에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucX

=

0

0

1

1

1

0

1

0

(0x3a)

^

ucY

=

1

0

1

1

0

0

1

0

(0xb2)


ucZ

=

1

0

0

0

1

0

0

0

(0x88)


 이 bit-xor 연산을 이용하면 원하는 비트를 반전시키는데(toggle) 응용할 수 있다. 만약 어떤 데이터에서 상위 4비트는 그대로 유지하고 하위 4비트만을 반전시키고자 하면 다음과 같이 한다.


unsigned char uca = 0xba;
uca ^= 0x0f;





b7

b6

b5

b4

b3

b2

b1

b0



uca

=

1

0

1

1

1

0

1

0

(0xba)

^

0x0f

=

0

0

0

0

1

1

1

1

(0x0f)


uca

=

1

0

1

1

0

1

0

1

(0xb5)


위의 예에서 보면 0x0f(=0b00001111)과 xor연산을 취하면 하위 4비트만 반전됨을 알 수 있다. 상위 4비트는 원래 값을 유지한다. 그 결과로 uca변수에는 0xb5가 남는다.


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


c{c++},n{c0052}

Posted by 살레시오
,

 두 피연산자의 or 연산은 같은 자리의 비트끼리의 or 연산을 전체 비트들에 대해서 수행하며 다음  표에 bitwise - or 연산을 정리하였다. 두 비트가 모두 0이어야 0이고 하나라도 1이라면 1이 된다.


[표 1] 비트 or 연산

x

y

x+y

0

0

0

0

1

1

1

0

1

1

1

1


앞의 경우와 같은 예제를 살펴보자.


unsigned char ucx = 0x3a, ucy = 0xb2, ucz ;
ucz = ucx | ucy;


이제 변수 ucz에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucx

=

0

0

1

1

1

0

1

0

(0x3a)

|

ucy

=

1

0

1

1

0

0

1

0

(0xb2)


ucz

=

1

0

1

1

1

0

1

0

(0xba)


이 결과를 보면 같은 위치의 비트끼리 bit-or 연산을 취한 결과가 얻어진다는 것을 알 수 있다.


 여기서 소개한 bitwise-or 연산자는 특정 비트를 강제로 1로 만들고 싶을 때도 많이 사용된다. 예를 들어 ucm변수가 1바이트값 0x2A라고 했을 때 3번, 4번, 7번 비트만 1로 강제로 만들고 싶다면 다음과 같이 하면 된다.


unsigned char ucm = 0x2A;
ucm |= 0x98;


여기서 0x98은 이진수로 0b10011000 이고 3번, 5번, 7번 비트만 1, 나머지는 0인 수이다. 이것과 ucm을 or 연산을 한 결과는 3번, 5번, 7번 비트만 무조건 1로 만들고 나머지는 그대로 놔둔 수를 얻게 된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucm

=

0

0

1

0

1

0

1

0

(0x2A)

|

0x98

=

1

0

0

1

1

0

0

0

(0x98)


ucm

=

1

0

1

1

1

0

1

0

(0xBA)


이렇게 특정한 비트를 1로 강제로 변환시키는 연산도 마스킹(masking)이라고 한다.


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


c{c++},n{c0051}

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

C/C++의 bitwise-not 연산 (~)  (0) 2015.05.20
C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-and 연산  (0) 2015.05.20
C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
Posted by 살레시오
,

 두 피연산자의 and연산은 같은 자리의 비트끼리 전체 비트들에 대해서 수행하며 [표 1]에 AND연산을 정리하였다. 두 비트가 모두 1이어야 1이고 하나라도 0이라면 0이다.


[표 1] 비트-and 연산

x

y

x▪y

0

0

0

0

1

0

1

0

0

1

1

1


예를 들면 다음과 같다.


unsigned char ucx = 0x3A, ucy = 0xB2, ucz ;
ucz = ucx & ucy;


이 경우 변수 ucz에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucx

=

0

0

1

1

1

0

1

0

(0x3A)

&

ucy

=

1

0

1

1

0

0

1

0

(0xB2)


ucz

=

0

0

1

1

0

0

1

0

(0x32)


이 그림에서 보듯이 (unsigned) char형 변수는 보통 최하위 비트를 0번으로 해서 1번, 2번, ...  , 7번 비트까지 있으며 각각 b0, b1, b2, … , b7이라고 표시한다. 변수의 가장 하위 비트를 LSB (least significant bit), 가장 상위비트를 MSB (most significant bit)라고 한다. 이 경우는 8비트 연산이지만 16비트(short)나 32비트(long) 연산도 원리는 동일하다. 즉, 같은 위치의 비트끼리 and연산을 취하는 것이다.


 다음과 같은 경우에도 and연산이 사용된다. 만약 어떤 데이터 값에서 상위 4비트는 그대로 유지하고 하위 4비트만을 0으로 만들고 싶다면 어떻게 해야 할까.


unsigned char uca = 0xBA;
uca &= 0xF0;





b7

b6

b5

b4

b3

b2

b1

b0



uca

=

1

0

1

1

1

0

1

0

(0xBA)

&

0xF0

=

1

1

1

1

0

0

0

0

(0xF0)


uca

=

1

0

1

1

0

0

0

0

(0xB0)


위의 예에서 보면 0xF0(=0b11110000)과 and연산을 취하면 그러한 동작이 일어남을 알 수 있다. 그 결과로 uca변수에는 0xB0가 남는다. 즉 상위 4비트는 그대로 유지하면서 하위 4비트는 0으로 바뀐다. 이러한 연산을 마스킹(masking)이라고 한다.


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


c{c++},n{c0050}

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

C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
Posted by 살레시오
,

 비트 연산자는 피연산자의 같은 자리에 있는 비트끼리의 연산을 수행한다. 마이크로콘트롤러(아두이노 등) 프로그래밍에서는 특정 레지스터의 비트값을 조작해야 하는 일이 매우 빈번하기 때문에 비트 연산에 대해서는 자세히 알아두는 것이 좋다. 사실 PC와 같은 환경에서는 비트 연산이 그리 유용하지 않으나 마이크로콘트롤러 프로그래밍에서는 그렇지 않다는 것을 실제로 실습을 진행해 보면 알게 될 것이다.


 다음 표에 비트 연산자의 종류와 동작에 대해서 정리하였다.


표 3.6.1 비트연산자의 종류

비트연산자

의미

수행 동작

&

논리-and

두 피연산자의 bit-wise AND

|

논리-or

두 피연산자의 bit-wise OR

^

논리-xor

두 피연산자의 bit-wise XOR

~

논리 -not

피연산자의 bit-wise NOT

<<

왼쪽shift

비트의 위치를 왼쪽으로 이동

>>

오른쪽shift

비트의 위치를 오른쪽으로 이동


비트 연산자는 정수형 데이터(char, int, short, long, long long 과 각각의 unsigned형)에만 적용되며 실수형 (float, double, long double)에는 사용하지 않는다는 것에 주의해야 한다.


 이항 연산인 & (and), | (or), ^ (xor) 세 연산자의 경우 비트 연산은 데이터의 같은 위치에 있는 비트끼리 연산이 이루어진다는 사실을 숙지해야 한다. 또한 연산 기호가 논리 연산자(&&, ||, ~)와 비슷해서 혼동하기 쉬우니 주의해야 한다.


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


c{c++},n{c0049}

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

C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
C/C++의 bitwise-and 연산  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
C/C++의 조건 연산자(?:)  (0) 2015.05.19
Posted by 살레시오
,

3.8 대입연산자    [doc]    [smts]

대입 연산자 “=”는 두 개의 피연산자를 갖는 이항 연산자이다. 연산식에서 우변에서 구해진 값을 좌변의 변수에 저장하는 역할을 한다. 대입연산자는 아래 [표 1]에 보인 바와 같이 여러 가지 종류가 있다. 단순 대입연산자 ‘=’와 관계연산자 ‘==’는 확실히 구분해야 함은 다시 한 번 강조한다.


[표 3.8.1] 대입연산자의 종류

대입연산자

수행 동작

=

좌측값을 우측변수로 대입

+=, -=

좌값과 우값을 더한(뺀) 후 좌측에 저장

*=, /=

좌값과 우값을 곱한(나눈) 후 좌측에 저장

%=

좌값을 우값으로 나눈 나머지를 좌측에 저장

&=, |=, ^=

좌값과 우값을 AND/OR/XOR 한 후 좌측에 저장

<<=, >>=

좌값을 우값으로 왼쪽/오른쪽 비트이동한 후 좌측에 저장


 위 표에서 보듯이 대입연산자들 중 “연산자=” 의 형태를 갖는 것들이 있다. 예를 들어서 다음 두 줄은 같은 일을 수행한다.


a += b;

a = a + b;


이 두 표현식은 완전히 동일하며 보통 줄여서 전자와 같이 사용한다. 또 다른 예로


a += b + 10;
a = a + (b+10);

이 두 줄도 완전히 동일하다. 우변이 먼저 구해진 후 그 값을 이용하여 좌변의 변수를 갱신시키는 것이다. 대입 연산자의 우선 운위가 가장 낮다.


몇몇 예를 다음 표에 더 들었다.


[표 3.8.2] 대입 연산자의 용례들

용례

동일식

동작

x -= 20;
x = x-20;

x에서 20을 뺀다.

x *= 5;
x = x*5;

x에 5를 곱한다.

x %=10
x = x%10

x에 x를 10으로 나눈 나머지를 저장한다.

x += y-5
x=x+(y-5)

x에 (y-5)를 더한다.


다음 예를 입력하고 결과를 확인하여 보자.


ex03-11.c
#include "stdio.h"
int main(void) {
 int ia=1, ib=10;
 ia++;
 ib -= ia;
 ia *= ib++;
 ia %= --ib;
 printf(“ia:%d, ib:%d”, ia, ib);
}

ia:?? , ib:??

단순 대입연산자 =는 한 표현식에서 중복으로 사용할 수 있다. 예를 들면


a = 0;
b = 0;
c = 0;

이 세 줄은 다음과 같이 한 줄로 줄일 수 있다.


a = b = c = 0;


이 때 연산은 오른쪽에서 왼쪽으로 순차적으로 일어난다. 따라서 먼저 c=0을 수행하고 그 결과 값을 다시 b에 대입하고 마지막으로 a에 대입한다.


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

C/C++의 bitwise-and 연산  (0) 2015.05.20
C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
C/C++의 조건 연산자(?:)  (0) 2015.05.19
C/C++의 논리 연산자  (0) 2015.05.19
Posted by 살레시오
,

3.7 증감연산자    [doc]    [smts]

증감 연산자 ++와 --는 한 개의 피연산자를 갖는 단항 연산자로서 피연산자를 1씩 증가 혹은 감소시키는 것이다. 피연산자로서 정수형과 실수형 모두 사용할 수 있으나 주로 정수형 변수에 사용된다. 증감연산자는 수식을 간결하게 만들어주므로 디버깅이나 실행속도 면에서 좀 더 효율적이다. 이 연산자는 C/C++ 에서 매우 자주 쓰이는 연산자이지만 잘못 사용한 경우에는 발견하기 힘든 오류을 발생시킬 수 있으므로 주의해서 사용해야 한다.


[표 3.71] 증감 연산자의 종류와 용법

형식

의미

++x

x를 먼저 1증가시킨 후 그 값을 사용

--x

x를 먼저 1감소시킨 후 그 값을 사용

x++

x값을 먼저 사용한 후 1 증가

x--

x값을 먼저 사용한 후 1 감소


위 표에서와 같이 증감연산자는 변수 앞에도 붙을 수 있고 뒤에 올수도 있다.  ++x 나 x++ 는 프로그램에서 다른 조건식이나 수식에 연결되지 않고 단일문으로 쓰일 경우에는 같은 결과를 얻지만 수식의 일부분으로 사용할 경우에는 그 의미가 달라질 수 있다. 다음 예를 보자.


ex03-09.c
#include<stdio.h>
int main()
{
  int ia, ib;
  ia = ib = 1;
  ia++;
  ib--;
  printf(“ia:%d, ib:%d”, ia, ib);
}

이 예에서 출력되는 ia와 ib값은 각각 2와 0이다. ia++, ib--은 각각 다음과 같다.


ia = ia + 1;
ib = ib - 1;

다음 예에서와 같이 증감연산자가 다른 연산자와 사용될 때에는 주의해야 한다.


ex03-10.c
#include<stdio.h>
int main()
{
  short sa = 10, sb = 10, sx, sy;
  sa++;
  ++sb;
  printf(“sa:%d, sb:%d\n”, sa, sb);

  sx = --sa;
  sy = sb--;
  printf(“sa:%d, sb:%d\n”, sa, sb);
  printf(“sx:%d, sy:%d\n”, sx, sy);
}

sa:11, sb:11
sa:10, sb:10
sx:10, sy:11

이 예제에서 sa에 저장되는 값과 sb에 저장되는 값은 각각 10과 11이다. sx=--sa 에서는 sx에 대입되기 전에 먼저 sa값이 1 감소하고 그 후에 그 값이 sx에 대입된다. sy=sb-- 에서는 sy에 sb값이 먼저 대입되고 sb값이 1 감소한다. 증감연산자가 앞에 붙느냐 혹은 뒤에 붙느냐에 따라 동작의 순서가 달라진다는 점에 유의해야 한다.


 관례적으로 증감연산자를 쓰지 말아야 할 경우가 있다.


  1. 하나의 변수가 수식 내에서 두 번 이상 사용될 경우에는 증감연산자를 사용하지 않는다. 예: y = x*2 + x++

  2. 한 변수가 어떤 함수의 인자로 두 번 이상 사용될 경우에는 이 변수에 증감 연산자 ++, --를 사용하지 않는다. 예: func(x*2, x++)


그 외에도 프로그램 작성자가 혼동의 여지가 있을 것 같다면 명확하게 작성하도록 유의해야 한다.



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

C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
C/C++의 조건 연산자(?:)  (0) 2015.05.19
C/C++의 논리 연산자  (0) 2015.05.19
3.4 관계 연산자  (0) 2015.05.19
Posted by 살레시오
,

3.6 조건연산자    [doc]    [smts]

조건 연산자(혹은 삼항 연산자라고도 한다)의 형식은 다음과 같다.


(조건식) ? 표현식1 : 표현식2;

조건연산자는 조건식이 참일 경우에는 표현식1을 선택(혹은 수행)하고, 거짓인 경우에는 표현식2를 선택(혹은 수행)시키는 연산자이다. 표현식에는 상수, 변수, 수식, 함수 호출 등이 올 수 있다.


예를 들어보면 다음과 같다.


(fa > fb)? printf(“true”):printf(“false”);
ir = ( i > j ) ? 1 : 0 ;
ir = ( ca == cb ) ? (ia+ib) : (ia-ib) ;

이 연산자는 if~else 문을 줄여서 쓴 형태라고 볼 수 있으며 if~else보다 간결하므로 단순 비교의 경우에는 자주 사용된다.


이것을 이용하여 두 수 중 큰 것을 구하는 간단한 프로그램을 작성해 보자.


int ia = 5, ib = 7, max;
max = (ia>ib)? ia:ib;

이 프로그램을 다음과 완전히 동일하다.


int ia=5, ib = 7, max;
if (ia>ib) {
  max = ia;
} else {
  max = ib;
}

또 다른 예를 들어보자.


ex03-08.c
#include<stdio.h>
int main()
{
  char cA = 'A', cB = '0';
  unsigned short usA;
  usA = (cA == 'A')? 1:0;
  printf("usA:%d\n", usA);
  (cB == 48)? printf("cB:'0'\n"):printf("cB: not '0'\n");
}

실행 결과

usA:1
cB:'0'

 조건 연산자는 사용 빈도가 높은 편이므로 잘 익혀두어야 한다.



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

C/C++의 대입연산자  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
C/C++의 논리 연산자  (0) 2015.05.19
3.4 관계 연산자  (0) 2015.05.19
3.2 산술 연산자와 부호 연산자  (0) 2015.05.19
Posted by 살레시오
,

3.5 논리 연산자    [doc]    [smts]

 논리 연산자는 다수의 조건식을 논리식으로 연결하는 연산자이이다. C 언어의 논리 연산자는 다음과 같은 것들이 있다.


[표 3.5.1] 논리 연산자.

논리연산자

의미

사용 예

&&

AND

i>80 && i<90

||

OR

i>10 || i<20

!

NOT

!(i<10)


논리 연산자에서 NOT의 의미인 ‘!’ 연산자는 관계 연산자의 ‘같지 않다’인 ‘!=’와 비슷하다. 그래서 초보자들은 가끔 혼동하는 경우가 있으니 주의해야 한다.


 예를 들어 정수형 변수 ‘ia가 0보다 크고 10보다 작다’ 라는 논리식은 다음과 같이 ‘0보다 크다’와 ‘10보다 작다’ 라는 논리식을 and로 묶어야 한다.


0 < ia  && ia < 10

세 개 이상의 조건문도 논리 연산자로 묶을 수 있다. ‘문자형 변수 ca가 ‘a’ 이거나 ‘b’ 혹은 ‘c’이다’라는 논리식을 다음과 같이 or로 묶어야 한다.


ca == ‘a’ || ca == ‘b’ || ca == ’c’

다음 논리식은 ! 연산자를 이용한 예이다.


!(ia>0) // ia<=0과 같다.
!(ca == ‘a’ || ca == ‘b’) // (ca != ‘a’ && ca != ‘b’) 과 같다.

 논리 연산자는 관계 연산자와 마찬가지로 내부적으로 참(true), 거짓(false)의 값을 가진다. &&는 양쪽 조건식이 모두 참일 때 전체 조건식이 참이 되며 ||는 양쪽 조건식 중 하나 이상이 참일 때 전체 조건식이 참이 된다. !은 참은 거짓으로, 거짓은 참으로 논리값을 바꿔준다.


 실습으로 어떤 short형 변수 값이 양의 짝수인지를 판별하고 어떤 실수형 변수가 1보다 크거나 –1보다 작은지를 검사하는 프로그램을 작성해보자.


ex03-07.c
#include <stdio.h>
int main(void) {
   short sA = 10;
   float fX = 2.0f;
   if ( sA>0 && sA%2 == 0 )
       printf("sA is a positive even number.\n");
   if ( fX<-1 || fX>1 )
       printf("|fA|<1.\n");
}

이것을 실행하면 첫 번째 printf()문만 수행될 것이다.



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

C/C++의 증감연산자(++, --)  (0) 2015.05.19
C/C++의 조건 연산자(?:)  (0) 2015.05.19
3.4 관계 연산자  (0) 2015.05.19
3.2 산술 연산자와 부호 연산자  (0) 2015.05.19
3.3 형변환  (0) 2015.05.19
Posted by 살레시오
,

3.4 관계 연산자    [DOC]    [SMTS]

관계 연산자는 두 개의 피연산자 간의 상등/대소 관계를 판단하는 이항 연산자이다. 보통 if 명령이나 조건 연산자 ?와 조합되어서 사용된다. 사용법을 정리하면 다음 표와 같다.


[표 3.4.1] 관계 연산자

관계 연산자

의미

x == y

x 값과 y 값이 같다.

x != y

x 값과 y 값이 서로 다르다.

x < y

x 값이 y 값보다 작다.

x <= y

x 값이 y 값보다 작거나 같다.

x > y

x 값이 y 값보다 크다.

x >= y

x 값이 y 값보다 크거나 같다.


관계 연산자에서 주의할 점은 ‘같다’를 표현하는 ‘==’이다. 흔히 하는 실수가 조건식에 ‘=’하나만 써 놓고 프로그램이 제대로 돌아가지 않는다고 의아해 하는 경우이다. C/C++언어에서는 ‘=’는 오른쪽의 데이터를 왼쪽에 대입하라는 의미이다. 이것과 구별시키기 위해서 ‘==’를 사용한다. 또 하나는 ‘같지 않다’란 관계 연산자인 ‘!=’이다. 만약 ‘!’하나만 쓴다면 논리연산자의 NOT 이므로 주의해야 한다. 그리고 ‘작거나 같다’의 ‘<='을 ’=<‘으로 바꿔 쓰지 않도록 주의하자. ’크거나 같다‘도 ’>=‘로 써야지 ’=>‘로 쓰지 않아야 한다.


int ia = 10, ib = 10, ic = 33
ia == ib //참(1)
ib == ic //거짓(0)
ib != ic // 참(1)
ic < ib // 거짓(0)

관계연산의 결과가 참일 때는 내부적으로 1값(true)을 가지고 거짓일 때는 0값(false)을 갖는다.  

그리고 관계 연산자의 두 피연산자의 데이터 형은 반드시 일치시켜야 한다. 만약 그렇지 않으면 엉뚱한 결과가 나올 수 있다. 다음 예를 살펴보기 전에 if 명령어의 문법을 간단하게 알아보자.


if (조건식) {
  명령들;
}

제어 명령어인 if 는 구조가 굉장히 간단한데 if 바로 다음에 오는 괄호 안 조건식이 참이면 중괄호 { }로 묶여진 명령들을 실행하고 거짓일 경우에는 실행하지 않는다.  조건식에서는 관계연산자와 다음 절의 논리연산자가 사용되며 조건식은 반드시 시작과 끝을 괄호로 묶어야 한다. if 명령은 또한 else 와 짝을 이루어 사용되기도 한다.


if (조건식) {
  명령들1;
} else {
   명령들2;
}

이렇게 하면 조건식이 참이면 {명령들1}이 실행되고 거짓이면 {명령들2}가 수행된다.


 다음 예제를 살펴 보자.


ex03-05.c
#include<stdio.h>
int main()
{
  char cA = 'A', cB = 'a';
  short sA = -10;
  unsigned long ulA = 1000;
  float fA = 1.0/10;

  if (cA == cB)
      printf("cA equals cB\n");
  if (sA < 0)
      printf("sA is negative.\n");
  if (ulA%2 == 0)
      printf("ulA is an even number.\n");
  if (fA != 0.1f)
      printf("fA is not 0.1f.\n");
      
  printf("%ld > %d : %d.\n",ulA, sA, ulA>sA);
}

sA is negative.
lA is an even number.
fA is not 0.1f.
1000 > -10 : 0.

위의 프로그램에서 실행된 결과를 하나씩 살펴보자. 먼저 첫 번째 if 문에서 (cA == cB)조건을 검사했다. 전절에서 설명한 대로 문자상수는 내부적으로 ASCII코드값으로 취급된다. ‘A’의 아스키코드는 65이고 ‘a’는 97이므로 cA는 65이고 cB는 97이다. 따라서 (cA == cB)조건은 거짓이 되므로 그 밑의 printf()함수가 수행되지 않는다. 그 밑의 printf()함수에서는 논리식 (sA < 0)이 참이므로 내부적으로 printf()문이 실행된다.


그 다음 조건식은 (fA != 0.1f)인데 fA는 1.0f/10으로 초기화 되었으므로 당연히 이 조건은 거짓으로 판명되고 그 밑의 printf()문은 수행되지 않아야 되지만 실행 결과를 보면 참으로 판단되었음을 알 수 있다. 이 예제에서 보듯이 C/C++ 에서는 실수형 변수에 대해서 직접 같다(==), 다르다(!=)를 사용하는 것은 정확하지 않은 결과를 초래할 수 있으므로 가급적 피해야 한다.


 그리고 마지막 문장에서 (ulA > sA)라는 조건도 ulA는 1000이고 sA는 –10이므로 당연히 참일 것 같지만 결과는 거짓(0)으로 출력되었다. 이렇게 비교연산의 두 피연산자의 데이터형이 다르면 결과가 엉뚱하게 나올 수 있으므로 주의해야 한다.


 이 예제에서 보듯이 실수형(float, double, long double)의 같고 다름을 판별할 때는 주의를 기울여야 한다. 보통 C/C++언어에서는 보통 두 실수가 서로 같은 값인가를 비교하지 않는다. 오류를 발생시킬 확률이 높기 때문이다. 이는 십진수를 2진소수로 변환하는데서 발생하는 오차때문이며 앞에서도 언급한 바와 같이 float형의 소수점 이하 유효 자리수는 정수부를 포함해서 6자리 정도에 불과하다는 사실에도 주의해야 한다.


이제 사용자로부터 입력받은 정수가 짝수라면 화면에 “even number.’ 라고 출력하고 홀수이면 “odd number”라고 출력하는 프로그램을 작성해 보자. 짝수는 2로 나누었을 때 나머지가 0인 정수이다.


ex03-06.c
#include<stdio.h>
int main()
{
  int ia;
  scanf("%d", &ia);
  if (ia%2 == 0) {        
      printf("even number.\n");
  } else {
      printf("odd number.\n");
  }
}

이 프로그램을 실행시키고 정수를 입력하면 그 정수가 짝수라면 화면에 “even number!”라고 출력이 되는 것을 확인할 수 있을 것이다.



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

C/C++의 조건 연산자(?:)  (0) 2015.05.19
C/C++의 논리 연산자  (0) 2015.05.19
3.2 산술 연산자와 부호 연산자  (0) 2015.05.19
3.3 형변환  (0) 2015.05.19
C/C++의 연산자 종류  (0) 2015.05.19
Posted by 살레시오
,