1. 화면의 첫 번째 줄에는 영문 이름을, 두 번쩨 줄에는 학번을 표시하고 세 번제 줄에는 생년월일을 출력하는 프로그램을 작성하라.


  1. 정수형 변수 a, b, c 를 각각 선언하고 a에는 1, b에는 2를 대입한 후 c 에는 a와 b의 곱을 대입하는 프로그램을 작성하라. (두 수의 곱은 ‘*’ 연산자를 사용한다.)


  1. 10진수 32456을 16진수로 표시하고 16진수 A9B7 을 10진수로 표시하는 프로그램을 작성하라. 또한 2진수 110011110010을 10진수로 표시하라.


  1. float형 변수 pi 에 원주율(3.141592)를 저장하고 float형 변수 e 에 자연상수(2.718281)울 저장하라. 그리고 그 수를 float형 변수 sum에 저장하라.


  1. 자연상수(2.718281...)를 E라는 상수로 정의하라. 그리고 원주율(3.141592)를 PI로 정의하라. 이후에 float형 변수 sum을 두 수의 합으로 초기화하라. 문제 4번 과의 차이점이 무엇인가 설명하라.


  1. 숫자값인 164 을 계산해서 화면에 십진수와 16진수로 표시하는 프로그램을 작성하라.


  1. sizeof 연산자는 주어진 데이터형의 바이트수를 반환해주는 매크로이다. 예를 들어서 sizeof(short)는 short형이 2바이트를 차지하기 때문에 2를 반환한다. 이것을 이용하여 char, short, int, long, long long, float, double, long double 형의 바이트 수를 화면에 모두 표시하는 프로그램을 작성하라.



Posted by 살레시오
,

 C/C++ 에서 typedef명령은 데이터형을 식별자로 대체하여 사용하게 해주는 명령이다. (type definition 두 단어를 조합해서 만든 듯 하다.)  다른 포스트에서 설명한 #include, #define 과 같은 전처리 명령어와 달리 #이 붙지 않고 끝에 세미콜론 ; 이 붙는다는 점에 유의하자.


 예를 들면 다음과 같다.


typedef unsigned char uchar;
typedef int INCHES, FEET;
typedef unsigned long size_t;


첫 번째 줄의 예를 보면 unsigned char 형을 uchar라는 새로운 이름(식별자)으로 정의하였고 두 번째 줄은 int 형을 INCEHES와 FEET라는 새로운 이름으로 정의하였다. 이후로는 다음과 같이 변수를 정의할 수 있다.


uchar ucA, ucB = 10; // unsigned char 형
INCHES length, width; // int 형


여기에서 ucA와 ucB는 unsinged char형이고 length와 width는 int형 변수이다.


  이렇게 이름을 새로 정의함로써 얻어지는 장점들은 다음과 같다.


❶ 긴 이름의 데이터형을 짧은 이름으로 대체할 수 있다.

❷ 자료형에 추가적인 의미를 부여할 수 있다.

또한 이 typedef명령어는 나중에 소개할 열거형(enum)과 구조제(struct)와 조합해서 자주 쓰이기도 한다.



Posted by 살레시오
,

 printf()함수는 기본적으로 첫 번째 인자인 문자열을 화면에 표시해주는 역할을 하는 함수로서 stdio.h 헤더화일에 정의되어 있다. 함수와 헤더화일에 대한 개념은 차후에 설명하도록 하고 여기에서는 기본적인 사용법만 익히고 넘어가도록 하겠다. 이 함수를 사용하기 위해서는 반드시 프로그램 시작 부분에 stdio.h를 인클루드시켜야 한다.

#include <stdio.h>


printf()함수 안에서 변수의 값을 표시하는데 쓰이는 문자를 서식 문자’라고 한다. 변수의 출력에 많이 쓰이는 서식문자를 다음 표에 정리하였다.


[표 1] printf()함수의 서식 문자

구분

서식 문자

출력 형태

정수형

%d

10진수 정수

%x

16진수 정수

%c

문자

실수형

%f

10진수 실수 (float형)

%e

10진수 실수 (지수형 표기)

%lf

10진수 실수 (double형)

문자열

%s

문자열 출력

그리고 앞의 예제에서도 자주 사용되었듯이 ‘\n' 문자는 다음 줄 맨 첫 칸으로 돌아가라는 동작을 수행하게 하는 특수 문자이다. 이와같이 printf()함수 내에서 사용되는 문자 ’\’를 이스케이프(escape)문자라고 한다. 이것을 이용한 몇 가지 자주 사용되는 문자는 다음과 같다.

[표 2] printf()함수의 특수 제어 문자

문자

기능

\n

줄바꿈

\t

수평 탭(tab)

\a

‘삑’하는 beep음을 발생한다.

\\

역슬래시 문자(\) 자체를 표시

\“

따옴표 문자를 표시


한글자판에서는 역슬래시(backward slash)가 원화 기호 ₩로 표시되므로 유의하자.

#include <stdio.h>
int main() {
   char cA = 'A';
   unsigned short usA = 100;
   float fA = 1.5;
   printf("The cA is %c and %d in decimal.\n", cA, cA);
   printf("The usA is \n");
   printf("%d and 0x%x in hexadecimal.\n", usA, usA);
   printf("The fA is %f \n", fA);
   printf("Hello %s.\n", "world!");
}


The cA is A and 65 in decimal.
The usA is 100 and 0x64 in hexadecimal.
The fA is 1.500000
Hello world!.


위의 프로그램에서 usA값의 두 가지 출력 출력값과 문자열을 출력하는 세 번째 printf()함수의 사용법을 눈여겨 보도록 하자.




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

C/C++ 자료형 연습문제  (3) 2015.05.24
C/C++ 의 typedef 명령어  (1) 2015.05.24
C/C++ #define 문으로 상수 기호 정의하기  (0) 2015.05.24
C/C++의 구분 기호와 주석  (0) 2015.05.24
1.9 식별자와 예약어  (0) 2015.05.24
Posted by 살레시오
,

 #define은 상수를 이름으로 정의하거나 매크로 함수를 정의할 때 사용하는 전처리문이다. (전처리문이란 컴파일을 수행 하기 전 소스 코드를 변환시켜주는 명령어들을 말한다.)  #define을 잘 활용하면 가독성이 향상된 프로그램을 만들 수 있고 프로그램을 수정하기에 효율적으로 작성할 수 있다. 기본 형식은 다음과 같다.


#define NAME VALUE


NAME은 그 뒤에 있는 숫자를 대신해서 사용할 명칭이다. 맨 끝에 세미콜론(;)이 붙지 않음에 유의하자.

다음 예를 보자.


#include <stdio.h>
#define PI 3.14  // PI를 3.14로 정의
int main() {
   float fR = 3.0;
   printf("radius : %f\n", fR);
   printf("circumference : %f \n", 2*PI*fR);
   printf("area : %f \n", PI*fR*fR);
   printf("volume : %f \n", 4*PI*fR*fR*fR/3);
}


radius : 3.000000
circumference : 18.840000
area : 28.260000
volume : 113.040000


두 번째 줄을 보면 다음과 같이 작성되어 있는데

#define PI 3.14


이것은 3.14라는 실수값을 PI라는 이름으로 사용하겠다는 정의이다. 실제로 프로그램상에서 printf()함수 안에서 사용되었다. 이 코드는 전처리기에 의해서 컴파일 전에 다음과 같이 내부적으로 수정된다.


printf("원의 둘레: %f \n", 2*3.14*fR);
printf("원의 면적: %f \n", 3.14*fR*fR);
printf("구의 체적: %f \n", 4*3.14*fR*fR*fR/3);


따라서 처음부터 직접 위와 같이 작성하나 #define 문을 사용해서 PI라는 기호로 작성하나 내부적으로는 아무런 차이가 없다. 하지만 다른 사람이 볼 때 PI라는 ‘의미를 유추할 수 있는 기호’를 사용하는 것과 3.14라는 숫자를 직접 사용하는 것과는 차이가 있다.


 더 큰 문제는 3.14라는 상수 값을 예를 들어 3.1415로 변경시켜야 할 경우가 발생했을 때이다. 위와 같이 프로그램했을 경우 세 곳을 모두 고쳐야 하지만 #define문을 사용한 경우에는 정의한 곳 한 곳만 고치고 다시 컴파일 해주면 된다. 이 예에는 세 곳이지만 프로그램이 길어진다면 수십 곳, 수백 곳이 될 수도 있을 것이다.

 전술한 바와 같이 #define문으로 상수에 적절한 이름을 부여하는 것은 프로그램의 가독성 측면이나 수정의 용이함 등을 따질 때 그 활용도가 상당히 높다고 할 수 있다.



Posted by 살레시오
,

1.10  구분 기호와 주석    [DOC]    [SMTS]

1.10.1 구분 기호

 구분 기호(punctuator)는 C언어를 구성하는 요소들을 구분할 때 쓰이는 기호들이다. 다음 표에 기본적인 구분기호를 정리하였다. 현재 단계에서는 모두 알 필요가 없고 앞으로 실습을 진행하면서 하나하나 익히게 될 것이다.


표 1.10.1 구분 기호

기호

설명

사용 예

; (세미콜론)

실행문의 끝에 반드시 써야함.

int iA;
printf(“Hello world”);
return;

{ }

2개 이상의 실행문을 한 단위로 묶을 때 사용함.

{ iA++; iB = iA+iC; }

( )

함수명 뒤, 연산 등에 사용

main(), 2*(1+iA), (int)fA

< >

외부파일을 편입할 때

#include <stdio.h>

C프로그램은 실행문 끝에는 반드시 세미콜론(;)이 붙어야 한다. 초보자들이 흔히 하는 실수가 세미콜론 없이 줄바꿈을 하는 경우이다. 보통은 세미콜론이 붙으면 다음 줄로 넘겨서 프로그램을 작성하게 되지만 한 줄에 여러 실행문을 세미콜론으로 구별하여 나열하여도 된다.

1.10.2 주석

 주석(comment 또는 remark)은 프로그램에 대한 설명을 추가하는데 사용된다. C 프로그램에 주석을 다는 방법은 두 가지가 있는데 먼저 한 줄 주석은 더블슬래시( // ) 뒤에 한 줄 이내로 써주면 되고 두 번째로 주석문이 여러 줄일 경우는 시작기호 /* 와 종료기호 */ 사이에 넣어주면 된다.(C 언어의 경우 한 줄 주석은 C99 이후부터 지원한다.) 컴파일러는 주석 기호를 만나면 프로그램으로 취급하지 않고 무시한다.


 주석문은 컴파일러의 입장에서는 없어도 아무 상관없지만 프로그래머의 입장에서는 매우 중요하다. 그 이유는 다른 사람이 본인의 프로그램을 분석하거나 혹은 시간이 얼마간 지난 후에 본인이 작성한 프로그램을 다시 분석할 때에도 주석문이 꼼꼼하게 작성되어 있는 경우에는 도움이 되기 때문이다.


 전 장에서 자동으로 생성되었던 프로그램을 다음과 같이 수정해 보자.


ex01-02.c
/* 본 프로그램은
2015년 3월에 작성되었다.*/
#include <stdio.h>
int main() {
  printf("Hello world!\n"); // 문자열 출력
}
실행 결과
Hello world!

프로그램 서두에 /* ~ */ 로 둘러싸인 부분이 주석이다. 그리고 printf()함수가 있는 줄의 끝에 // 로 시작하는 한 줄 주석이 달려있다.(녹색 부분) 이 프로그램에서 주석이 없어도 실행에는 전혀 문제가 없다. 즉, 컴파일러 입장에서는 주석이 있으나 없으나 전혀 상관이 없다. 주석은 사람이 프로그램이 읽을 때 이해에 도움이 되는 설명을 덧붙이는데 사용된다.



Posted by 살레시오
,

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