1.9 식별자와 예약어    [DOC]    [SMTS]

 식별자(identifier)는 변수나 함수 등의 이름을 지정할 때 사용된다. C언어에서사용되는 식별자를 만드는 데에는 다음과 같은 제약 사항이 있다.


❶ 알파벳 대소문자(a, b, …, z, A, B, …, Z), 숫자(0,1,2, …9), 밑줄(_)을 조합하여 만든다.

❷ 숫자로 시작해서는 안 된다.

❸ 예약어(keyword)는 식별자로 쓸 수 없다.


특수문자로는 유일하게 밑줄(_)문자가 식별자를 만드는데 사용이 되며 이외의 다른 특수문자는 식별자롤 사용할 수 없다. 아래의 예는 올바른 식별자이다.


ia  dbase  cStatus  iMotor10  i_AVR_Name  _reg  _123  For

아래의 예는 올바르지 않은 식별자이다.


123a  A$Bc  %pi  if

 한 가지 주의할 점은 C언어에서는 식별자를 사용할 때 대소문자를 구별한다는 점이다. 즉 다음 네 개의 식별자들은 모두 서로 다른 것으로 구별된다.


ab  Ab  aB  AB

이러한 특징은 거의 대부분의 프로그래밍 언어들에 있어서 공통적으로 해당된다.


 예약어(reserved word, keyword)라는 것은 C언어에서 미리 사용하겠다고 지정되어진 단어로서 식별자로 사용할 수 없는 단어들을 말한다. 몇 가지 예를 표 1.8.1에 기술하였다.


표 1.9.1 C언어의 예약어들

분류

예시

자료형 관련

void, char, int, short, long, float, double, signed, unsigned, enum, struct, union, volatile, static, const, extern, register, auto, sizeof, typedef 등

제어 명령 관련

if, else, for, do, while, switch, case, continue, break, goto, default, return 등

전처리 관련

define, include 등

이 예약어들은 식별자(즉 변수명이나 함수명)로 사용할 수 없으므로 필히 알고 있어야 하지만 C프로그램을 작성하는 경험이 많아지면 자연스럽게 알게 되고, 혹시 실수로 예약어를 변수명이나 함수명으로 사용한다 해도 컴파일러에서 에러를 발생시켜 주므로 크게 걱정할 필요는 없을 것이다.



Posted by 살레시오
,

 C/C++을 실습할 수 있는 도구는 매우 종류가 다양한데 유료인 것도 있고 무료로 사용할 수 있는 것들도 많이 있다. 본 교재에서는 무료로 사용할 수 있는 것들 중 “CodeLite” 이라는 오픈소스(open source) IDE를 사용하도록 하겠다. CodeLite은 무료로 사용할 수 있다는 장점과 윈도우즈와 OS X 뿐만 아니라 리눅스에서도 동일한 환경으로 사용 가능하다. 그리고 C/C++ 언어오에 PHP로도 개발할 수 있으므로 C언어에 어느 정도 익숙해진 후 C++로 넘어갈 때에도 동일한 환경에서 같이 실습할 수 있다는 장점도 가지고 있다. 따라서 학생들이 C/C++언어 실습을 하기에 유용한 툴이라고 개인적으로 생각되어 본 포스트에서는 이것의 간략한 사용법에 대해서 설명하도록 하겠다.

 설치 프로그램은 홈페이지(www.codelite.org)에서 다운로드받을 수 있으며 검색엔진에서 ‘codelite’라고 검색하면 쉽게 찾아갈 수 있다.

[그림 1] codelite IDE의 외형

 codelite를 설치한 후 C/C++프로그램을 작성하는 방법을 간략히 소개하면 다음과 같다. 먼저 File>New>Project 를 선택한다. 그러면 새로운 프로젝트를 생성할 수 있는 대화상자가 나타난다. '프로젝트(project)'라는 것은 하나의 C/C++ 프로그램이 여러 개의 파일들로 분산되어 있는 경우에 그 파일들을 하나로 묶어서 관리하는 단위를 나타낸다. 프로그램이 길어질 때는 하나의 화일에 모든 소스코드를 담는 것이 아니라 여러 개의 화일에 분산시켜서 관리하는 것이 일반적인데 이는 여러 명이 하나의 프로그램을 작성할 때 효율적이기도 하다.


[그림 2] 새로운 프록젝트를 생성하는 메뉴

이 [그림 2]와 같이 File>New>New Project 메뉴를 선택하거나 시작화면에서 New Projcet 항목을 선택하면 새로운 프로젝트를 생성할 수 있다.

 이후에 이 창에서 C 언어의 경우  'Simple executable (gcc)' 항목을 선택한 후 (C++은 'Simple executable (g++)') 프로젝트 이름을 기입하면 Project path에 지정된 폴더 하위에 입력한 프로젝트 이름으로 새로운 폴더가 생성되고 이후에 모든 파일들은 그 폴더 안에서 생성되고 관리된다.

[그림 3] 생성할 프로젝트의 종류를 선택하는 창


[그림 4] 프로젝트으 이름과 경로를 선택하는 창

[그림 5] 새로운 프로젝트가 만들어진 후 자동으로 생성된 프로그램


생성된 프로젝트의 src폴더에 보면 main()함수가 포함된 화일명이 main.c로 자동으로 만들어진다.지정한다. 이제 단축키 [ctrl]+[f5]를 누르면 프로젝트가 컴파일 된 후 실행이 되고 콘솔창에서 그 결과를 확인할 수 있다.

 자동으로 생성되는 프로그램(C/C++의 경우)은 다음과 같다. C 프로그램은 src폴더 밑에 main.c 파일에, C++의 경우 main.cpp 파일이 생성된다.


#include <stdio.h>
int main(int argc, char **argv)
{
   printf("hello world\n");
   return 0;
}


다른 부분은 나중에 이해하더라도 일단 printf()함수는 표준 출력(standard output)으로 입력된 문자열을 내보내는 기능을 수행한다는 것은 알아두자. 일단 현 단계에서 표준 출력은 디스플레이 장치(모니터)라고 이해하여도 된다. 이 프로그램을 실행하면 “hello world”라는 문자열이 화면에 표시될 것이다. 이것을 바꿔서 자신의 영문 이름이 화면에 표시되도록 해보자.



Posted by 살레시오
,

1.5 C언어의 표준안들    [DOC]    [SMTS]

 여기에서는 C언어의 국제 표준안들에 대해서 간략히 알아보도록 하겠다.

1.5.1 ANSI C 혹은 C89

 C 언어가 처음으로 만들어진 것은 1970년대초이고 이후 다양한 분야에서 다양한 사람들에 의해 사용되고 또 발전했다, 서로 다른 집단에 의해 변형된 C 언어가 어느 정도 같은 틀을 공유한다고 해도 1980년대에 들어서면서 다양한 C 언어들이 독자적으로 지원하는 확장 기술은 서로 호환되지 않게 되었다. 또한 C 언어가 미국 정부 프로젝트를 위해 사용되기 시작하면서 미국의 표준화 기구인 ANSI에 의해 1980년대 초반에 표준화를 시작되게 된다. 이후에 1989년도에 탄생한 C언어 표준이 지금까지 C언어 서적에서 인용되고 있는 ANSI C(정확히는 ANSI X3.159-1989)이다. 발표된 연도를 이용해서 줄여서 C89라고 불리기도 한다. 1990년도에는 국제 표준화 기구인 ISO가 몇 가지 형식부분만을 바꿔 ISO표준을 발표했고 이를 C90이라고 부르는데 결국 C89와 같은 것이다. ANSI C는 대부분의 컴파일러가 지원한다.

1.5.2 C99

 ANSI의 표준화 이후 C 언어 표준이 상대적으로 정적으로 남아 있었던 동안, C++는 표준화를 위하여 계속 진화하고 있었다. 1995년에 1990년의 C 표준에 대한 규약 수정안 1이 출판되었는데, 이는 약간의 세부 사항을 교정하고 국제적 문자 세트에 대한 보다 확장된 지원을 위한 것이었다. C 표준은 1990년대 후반에 더 개정되어, 1999년 ISO/IEC 9899:1999가 출간되었고, 여기서 명시한 규범을 흔히 C99라 부른다. 몇몇 추가점들을 기술하면 다음과 같다. (http://ko.wikipedia.org/wiki/C99 참조)


  • 인라인(inline) 함수의 지원.

  • 변수의 선언은 더 이상 파일 범위나 복합 명령어의 시작에서만 할 필요가 없음.

  • long long int, 선택적인 확장 정수형, 명시적 불린 자료형, 그리고 복소수를 나타내기 위한 complex 자료형 등 새로운 자료형 도입.

  • 가변 길이 배열(VLA: variable-length array) 지원.

  • // 으로 시작하는 한 줄 주석 지원.

  • IEEE 부동소수점 자료에 대한 개선된 지원.


 본 교재는 바로 이 C99를 기준으로 하여 문법을 설명한다.

1.5.3 C11

 C11은 ISO/IEC 9899:2011의 줄임말로 C 언어의 최신 개정된 표준을 의미한다. 이전까지 표준이던 C99의 후속으로 최종안이 2011년 4월에 제출되었고 검토를 거쳐 2011년 12월 8일에 최종 승인되었다. GCC 4.6, Clang 3.1, IBM XL C 12.1, MSVC 18 등이 C11의 일부 기능을 지원한다.


Posted by 살레시오
,

1.4 C 프로그램 개발 과정    [DOC]    [SMTS]

 C 프로그램을 개발하는 데 있어서 일반적으로 다음과 같은 도구들이 필요하다.


❶ 텍스트 에디터 (text editor)

  • 프로그램을 입력, 편집, 수정할 수 있는 도구.


❷ 컴파일러 (compiler)

  • ‘컴파일(compile)’은 프로그래밍 언어로 작성된 코드를 컴퓨터가 이해하고 실행할 수 있도록 기계어(machine language)로 번역하는 것을 의미한다.

  • ‘컴파일러’는 이러한 일을 수행하는 실행 프로그램이다.

  • 특별히 C 프로그램 코드를 기계어로 번역해 주는 것을 ‘C 컴파일러’라고 한다.


❸ 디버거 (debugger)

  • 디버거는 프로그램의 실행시키면서 프로그램의 동작을 확인하고 오동작을 수정할 수 있는 도구이다.


개발 편의성을 높이기 위해서 이 세 가지를 하나로 통합한 도구를 IDE (intergrate development environment)라고 한다.


C 언어로 프로그램을 개발하는 과정은 다음과 같이 요약할 수 있다.


  1. 사용자(프로그래머)는 C 언어 문법에 맞추어 프로그램을 작성한다.

  2. 이것을 컴파일하여 오브젝트(object)파일을 생성한다.

  3. 문법상 오류가 발생하였다면 소스코드를 수정한 후 2단계로 돌아간다.

  4. 오브젝트 파일을 링크(link)하여 실행프로그램(exe파일)을 생성한다.

  5. 프로그램을 실행하여 오동작이 일어난다면 수정한 후 다시 2단계로 돌아간다.


보통 ❷,❹번 과정은 IDE상에서 빌드(build)명령을 내리면 소스코드에 문법상 오류가 없다면 저절로 진행되어 실행파일이 생성된다. 따라서 오브젝트파일은 자동적으로 생성되어 링크하는 과정이 진행되므로 사용자 입장에서는 이 오브젝트 파일에 신경 쓸 필요가 없다.


[그림 1.4.1] C 프로그램 개발 과정 개념도


프로그램을 작성하다 보면 필연적으로 오류(error)가 발생한다. 오류는 크게 문법적인 오류와 논리적인 오류로 구분할 수 있다.


  • 문법적인 오류(syntex error)는 명령이 문법에 맞지 않다거나 혹은 단순히 타이핑을 실수했다든가 함수명이나 변수명을 잘 못 작성한 경우로서 컴파일러에서 체크하여 메시지를 발생하므로 수정하는 것은 그다지 어렵지 않다.

  • 논리적인 오류(logical error)는 프로그램의 실행이 의도와는 다르게 되는 것으러서 보통 버그(bug)라고 칭한다. 논리적인 오류를 수정하는 과정은 디버깅(debugging)이라고 하며 문법적인 오류를 수정하는 경우보다 그 작업이 복잡하고 어려우므로 디버거(debugger)라는 도구를 사용하게 된다.


여기서 "debug"라는 용어는 문자 그대로 "벌레를 제거한다"는 의미이다. 버그는 곤충을 뜻하는데 프로그램을 "디버깅(debugging) 한다."는 것은 작성된 코드 안에서 잘못된 부분이나 예기치 않게 발생 된 오류의 원인을 찾아 해결해 나가는 일련의 과정을 의미한다. "디버그"라는 용어가 만들어지게 된 유래에 관해서는 다소 논란의 여지가 있긴 하지만 가장 잘 알려진 이야기는 2차 세계대전이 끝난 직후인 1947년 하버드 대학에서 일어났던 마크Ⅱ(MARKⅡ) 컴퓨터와 그레이스 호퍼(Admiral Grace Hopper)의 일화이다.


[그림 1.4.2] 그래이스 호퍼와 ‘bug’ 리포트


1947년 여름, 당시 호퍼는 하버드 대학에서 마크2 컴퓨터를 이용해 연구 중이었는데 컴퓨터가 자주 고장을 일으켰다고 한다. 호퍼와 동료들은 고장의 원인을 찾기 위해 컴퓨터 내부를 들여다보며 조사하던 중, 릴레이(relay)의 접점 사이에 끼어 들러붙어 죽어있는 나방(moth) 한 마리를 발견하게 된다. 실제로 컴퓨터 시스템 안에 벌레가 있었고 이로 인한 누전으로 컴퓨터가 오작동한 것이다. 그녀와 동료들이 문제가 된 나방이 조심스럽게 제거되자(de-bugged) 컴퓨터는 다시 정상적으로 작동하게 되었다. 호퍼는 이때 제거했던 나방을 자신의 일지에 테이프로 붙여두고 "발견된 버그의 첫 실제 사례(first actual case of bug being found.)"라고 기록하였다.


[그림 1.4.3] 그래이스 호퍼의 기록


이 사건 이후 그레이스 호퍼는 컴퓨터 프로그램에서 오류의 원인을 찾고, 추적하고, 발견된 문제들을 제거하거나 수정하면서 해결해 나가는 일련의 과정을 "debugging"이란 용어로 표현하게 된다. 그리고 이후에는 컴퓨터 프로그래머들이 문제를 일으키는 오류나 잘못된 소스 코드를 가리켜 "bug"라고 표현하기 시작했다.

Posted by 살레시오
,

 비트 이동(shift) 연산자는 방향에 따라 두 가지가 있는데 <<연산자는 왼쪽 이동 연산자이고 >>는 오른쪽 이동 연산자이다. 쉬프트(shift)는 비트의 자리를 이동시킨다는 용어인데 이 연산자의 오른쪽에 적인 숫자의 자리수만큼 순차적으로 이동시킨다. 사용 문법은 var<<n (혹은 var>>n) 이며 변수 var을 n비트 좌측(혹은 우측)으로 이동시킨다.


unsigned char uca = 0b01101100;

unsigned char ucb = uca >> 2; // 각 비트를 오른쪽으로 두 자리씩 이동

unsigned char ucc = ucc << 3; // 각 비트를 왼쪽으로 세 자리씩 이동


비트들이 자리 이동을 하게 되면 밀려나서 버려지는 비트들이 있으며 반대로 채워야되는 자리가 생기게 되는데 두 가지 경우가 약간 차이가 있다. 먼저, 왼쪽으로 비트들을 이동시키는 << 연산자의 경우 비트들이 왼쪽으로 자리를 이동하게 되면 비는 공간을 0으로 채우게 되며 자리 이동으로 인해 밀려나가는 비트들은 모두 버려지게 된다.


반면, 오른쪽으로 비트들을 이동시키는 >>연산의 경우는 오른쪽으로 밀려나가는 비트들은 버려지지만 좌측에 생기는 빈 공간에는 부호가 없는 데이터형이면 0으로, 반대로 부호가 있는 데이터형은 부호를 유지시키기 위해서 원래 변수 값의 최상위비트(MSB)로 채운다. (주의할 것)


 예를 들어 (unsigned char) ucx=5 라면 ucx<<= 2 명령에 의해 원래 (0b00000101)이 (0b00010100) 십진수로 20이 된다. 왼쪽으로 쉬프트는 2를 곱하는 효과가 있으므로 2번 쉬프트하면 4를 곱한 효과가 난다.


unsigned char ucx = 0b00000101;

ucx <<= 2; // 0b00010100 이 된다.


반대로 ucx>>=2 는 결과값이 (0b00000001)이 된며 오른쪽으로 쉬프트하는 것은 2로 나눈 효과가 있게 된다. 이 경우 ucx변수가 부호가 없는 데이터형이기 때문에 최상위비트는 0으로 채워진다.


unsigned char ucx = 0b00000101;

ucx >>= 2; // 0b00000001 이 된다.


 만약 부호가 있는 데이터형 변수 (char) ca=-2 이라면 2진수로 표현하면 0b11111110 이다. 이것을 cA>>=1 연산을 한 결과는 0b11111111이 된다 (십진수로는 –1이다.). 이 경우는 부호가 있는 데이터형이기 때문에 최상위 비트가 원래 부호비트값인 1로 채워지는 것이다.


char ca = -2; // 이진수로 0b11111110 이다.

ca >>= 1; // 0b11111111 (십진수로 -1) 이 된다.


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


#include "stdio.h"
typedef unsigned char uchar;
int main()
{
  uchar ucA = 0x05, ucB, ucC;
  ucB = ucA << 3;
  ucC = ucA >> 1;
  printf("ucA : 0x%x\n", ucA);
  printf("ucB : 0x%x\n", ucB);
  printf("ucC : 0x%x\n", ucC);
}


ucA : 0x5
ucB : 0x28
ucC : 0x2


이진수로는 0b00000101, 0b00101000, 0b00000010 에 각각 해당된다.


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


c{c++},n{c0054}

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

C언어의 표준안들 개요  (0) 2015.05.24
1.4 C 프로그램 개발 과정  (0) 2015.05.24
C/C++의 bitwise-not 연산 (~)  (0) 2015.05.20
C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
Posted by 살레시오
,

 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 살레시오
,