[C 언어의 기초]연산자 3부






기타 연산자 - 2




4. 관계 연산자, 논리 연산자 : 연산 결과는 0(거짓) 또는 1(참)
㉠ 관계 연산자

관계 연산자는 조건 판단 등의 관계(>, <, = 등)를 판정하는 것으로 다음과 같은 종류가 있다.

연산자

기 능

우선 순위

>

크다

1

>=

크거나 같다

1

<

작다

1

<=

작거나 같다

1

==

같다

2

!=

같지 않다

2



조건 판단에서 「같다」는 ==라고 = 기호 두 개를 연속으로 쓰는 것에 주의해야 한다. 한 개의 =은 대입연산자이므로 그 의미가 완전히 다르다. 다음의 의미를 생각해 보자.

i > 0, i >= 10, i == 0, i != 0

/* 임의의 산술식에 관계 연산을 적용한 예제 프로그램 */

#include<stdio.h>

main()

{

char ch = 'A';

int I = 1,j = 2,k = -3;

double x = 7.23e+33,y = 0.001;

printf(" %d\n", 'C'- 15 < ch);

printf(" %d\n", -i 4 * j >= k * k);

printf(" %d\n", I < k > j);

printf(" %d\n", x - 5.555 <= x + y / 0.234);

printf(" %d\n", x < x+y);

}


㉡ 논리 연산자
논리 연산자에서는 몇 가지 조건 판단을 형성하는 것으로 &&, ||, !의 세 가지가 있다.

연산자

기능

우선순위

!

부정(NOT)

1

&&

그리고(AND)

2

¦¦

또는(OR)

3


조건식에 대해서는 뒤에서 if 문과 함께 설명하겠지만 예를 들면 a>b && b>c …a>b 이고 그리고 b>c a>b ¦¦ b>c && c==3……&&는 ¦¦ 보다 우선 순위가 먼저이기 때문에 먼저 b>c && c==30이 평가된다. 다음의 의미를 각자 생각해 보자.

(c >= 'A') && (c<= 'Z')

!((c < 'A') || (c > 'Z'))




5. bit 연산자 : <<, >>, &, |, ^, ~
① shift 연산자(<<, >>) : 비트별로 연산자 다음에 주어진 숫자만큼 이동한다.

x << y 의 의미는 x에 저장된 데이터 비트를 y만큼 로 이동시키는 것입니다.

x >> y 의 의미는 x에 저장된 데이터 비트를 y만큼 로 이동시키는 것입니다.


만약 데이터의 비트가 왼쪽(오른쪽)으로 이동하게 되면, 왼쪽(오른쪽) 끝의 최상단(최하단) 비트 자리에 있는 데이터는 다음 자리에 있는 데이터가 들어오기 때문에 없어지고 오른쪽(왼쪽) 끝자리에 0이 채워집니다.

좌/우 이동 연산자(<<, >>)를 사용할 때 주의할 점은 이동 연산자의 좌측에 있는 피연산자 x는 항상 정수형이어야 하고, 우측에 있는 피연산자 y는 양의정수형이어야 합니다. 그리고 y의 정수 값은 x의 비트 크기를 넘어서는 안 됩니다.


/* 여백문자알파벳 대/소문자숫자의 수를 세는 프로그램 */

#include<stdio.h>

main()

{

char ch;

int alpa_count = 0, digit_count = 0,

white_count = 0, other_count = 0;

printf("Input number of characters : ");

while((ch = get char()) ! = EOF)

{

if(ch == '' || ch == '\n' || ch == '\t')

white_count++;

if(ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')

alpa_count++;

if(ch >= '0' && ch <= '9')

digit_count++;

}

printf("There are %d whitespace characters.\n", white_count);

printf("There are %d alphabet characters.\n", alpa_count);

printf("There are %d digit characters.\n", digit_count);

}


② AND(&), OR(|), XOR(^), 1의 보수(~) : 비트 단위로 수행되는 연산자이다.

비트 논리 연산자는 1개의 단항 연산자와 3개의 이항 연산자가 있는데, 이들 각 연산자는 학생이 알고 있는 논리 연산자와 동일한 진리 값을 가지며, 논리 연산자와의 차이점은 논리 연산자가 피연산자로 전체 단어(word)나 바이트가 가지는 값을 그 대상으로 사용하는 반면에 비트 논리 연산자는 기억 장소의 2진 값인 각 비트를 그 대상으로 한다는 점입니다. 

비트 단위연산은 정수를 그 대상으로 하기 때문에 8진, 16진, 10진 정수를 사용해야 하지만 편의상 여러분의 이해를 돕기 위해서 16진수나 기억장소에 실제 데이터가 표현되는 2진수 표현을 사용하기로 합니다. 그러나 C 언어에서 2진수 표현은 사용할 수 없다는 것을 명심하기 바랍니다.

Ⓐ 1의 보수 연산자(~)

1의 보수 연산자는 단항 연산자로서 피연산자가 저장된 기억장소의 각 비트들을 토글(toggle)시킵니다. 즉, 0을 1로 바꾸고, 1을 0으로 바꾸어 줍니다.


(10001010) == ~ (01110101)



Ⓑ 비트 단위 AND (&) 연산자

비트 단위 AND 연산자는 이항 연산자입니다. 즉, 연산을 실행하기 위해서 2개의 비트 피연산자가 필요하며, 2개의 비트 피연산자 중 한 비트 값이라도 0이면, 결과 비트 값은 0이 됩니다. 즉, 2개의 비트 피연산자 값이 모두 1일 때 만 결과 비트 값이 1이 됩니다.

(11010101) & (01101101) == (01000101)


위에서 보는 것처럼 비트 단위 AND 연산자는 피연산자로 사용되는 2개의 비트값 이 00, 01, 10일 때에는 그 결과 값이 0이고, 11일 때에만 1이 됩니다. 비트 단위 AND 연산자는 마스크라는 특별한 동작을 실행하여 하드웨어의 특정 flag 비트를 제어할 때 사용합니다. 

마스크(mask)는 비트 패턴으로 구성된 flag 비트들 중 특정 비트영역만 선택하여 원래의 비트 패턴으로 보호하고 나머지 영역은 0으로 비트 값을 설정하는 동작을 말합니다. 예를 들면, flag라는 변수에 같이 데이터 103이 저장되어 있다고 할 때, 이들 비트 패턴 중 비트 번호 1, 2 (두 번째와 세번째 비트)인 비트만 원래의 데이터를 가지도록 할 때 나머지를 0으로 설정하는 마스크 동작을 실행하려면 다음과 같이 하면 됩니다.

mask = 6;

flag = flag & mask;

실행 과정은 각자 2진수로 표현하여 알아보기 바랍니다.


Ⓒ 비트 단위 OR (|) 연산자


비트 단위 OR 연산자는 2개의 비트 피연산자중 적어도 하나만 1이면 그 결과 비트 값이 1이 되는 연산을 실행합니다. 비트 단위 AND 연산자와 유사하게비트 간 의 OR 연산자도 컴퓨터의 하드웨어를 제어하는데 사용됩니다. 즉 비트 켜기(bit ON)라는 특별한 동작을 실행하는데, 비트 켜기는 flag 비트의 패턴들 중 지정한 비트 영역의 비트패턴의 값을 1로 설정하고, 나머지 영역의 비트 영역은 원래의 비트 패턴으로 유지하도록 하는 연산입니다.

Ⓓ 비트 단위 XOR (^) 연산자

피연산자로 사용되는 2개의 비트가 서로 다른 경우에 그 결과 비트 값이 1이 됩니다. 아래의 확인 문제 2-15처럼, 비트 단위 XOR연산을 취하면 flag 변수의 비트 패턴은 mask의 비트 패턴에 의해 토글(toggle)됩니다.

Ⓔ 비트 끄기(bit OFF)

확인 문제 17처럼, ~mask로 비트단위 AND 연산을 실행하면 마스크 영역의 비트 패턴만 0으로 설정되고 나머지 영역은 그대로 남아 있습니다. 즉, 특정영역을 0으로 설정하는 비트 끄기입니다. 이 연산자들을 잘 이해하고, 그 쓰임새를 완전히 파악하려면 확인 문제 17을 반드시 실행해서 확인하기 바랍니다.

/*비트 단위 논리 연산자(~, &, |, ^)를 이용한 마스크비트 켜기/끄기반전(toggle)의 예 */

#include<stdio.h>

main()

{

unsigned char flag, mask;

flag = 103; mask=6;

printf("flag = %#0x, flag & mask = %#0x\n", flag, flag & mask);

flag = 6; mask = 48;

printf("flag = %#0x, flag | mask = %#0x\n", flag, flag | mask);

flag = 103; mask =255;

printf("flag = %#0x, flag ^ mask = %#0x\n", flag, flag ^ mask);

flag = 103; mask = 6;

printf("flag = %#0x, flag & ~mask = %#0x\n", flag, flag & ~ mask);

}






Reactions

댓글 쓰기

0 댓글