2011년3월28일...변수, 메모리, scanf(), 정수 자료형, 상수, 마인드스톰 Spike

정리하면서 올리면 시간이 많이 드니 일단 노트에 필기한 순서대로 올리고,
후에 내용별 분류 카테고리를 추가하여 보기 좋게 정리할 것임.

 

 

1.데이터 이동

image

 

2.본질, 데이터

image

본질(모양)은 변하지 않으나 언어마다 다르게 부르듯이 cNum도 본질은 십진수로 255이나 음수를 표현하기 위해 -1로 정한 것이다.

 

image

메모리는 부팅 시 아무도 어떤 값이 들어 있는 모른다. 관리하기 좋게 자료형을 사용하고 의미를 두지 않으면 알 수 없는 쓰레기값이다. 처음으로 그 저장공간에 데이터를 넣어 가치를 부여하는 것을 초기화라고 한다.

2진수 1111 1111가 들어 있는 공간의 자료형이 char이면 -1이라는 값이 될 것이고,

unsigned char형이면 255라는 값이 될 것이다. 여기도 상기에서 논한 것과 같이 본질은 변하지 않고 만약 빨간 사각형의 공간을 short형으로 지정하면 다른 값이 될 것이다.

 

3.변수의 초기화

int iNum; -> 변수선언 int iNum = 0; -> 변수를 선언하고 0으로 초기화
iNum = 0; -> 변수를 0으로 초기화 (초창기엔 이 코드가 빨랐음)
※컴파일시 C코드는 쪼개어 진다.

 

4. 주석

// <- 그 줄만 주석처리

/* */ <- /*로 시작하여 */로 끝나는 부분을 모두 주석으로 처리

<사용 예>

int iNum = 0; //iNum을 선언하고 0으로 초기화 -> 코드에 대한 설명을 담.
/*unsigned*/ int iNum2 = 0; -> 부호있는 정수형으로

/* 주석1

주석2 */ -> 여러 줄 설명

 

5.예제2-1

clip_image002

 

image

 

① int num;

CU에서 메모리에 num이라는 기억공간을 만든 다고 하셨지만 언어적으로 그 공간을 사용하겠다고 정해 놓는 것이지 실제 CPU는 아무 일도 하지 않는 다고 생각한다.
메모리에 어떤 값이 저장되어 있으나 그것은 아무 의미가 없는 값이라 쓰레기값이라 부른다.


② num = 2147483647;

프로그램메모리에서 데이터이동 명령과 함께 데이터를 읽어와 CU에서 해독하여 num이라는 변수의 주소에 정수의 최대값을 넣는다.

 

image

 

num = num + 2;

1) 레지스터로 num의 주소에서 값을 읽어옴.
2) CU에서 덧셈명령을 해독하고 2라는 값을 ALU에서 레지스터와 같이 더하여 다시 레지스터로 저장함.

④num = num + 2;

num변수의 주소로 레지스터의 값을 전송.

 

 

image

 

⑤ printf(“최대값 보다 4가 큰 값은 %d.\n”, num + 2);

1) num의 값을 레지스터로 전송.
2) 레지스터와 2를 더하여 다시 레지스터에 저장.
3) GPU의 레지스터(메모리)로 CPU의 레지스터의 값을 전송. (부가적인 데이터와 명령은 설명 안 함.)
4) 그래픽카드의 메모리의 값이 모니터에 뿌려짐.

※레지스터에서 그래픽카드로 전송 후 다시 메모리로 전송하지 않았으니 num의 값은 유지됨.

 
image

정수의 최대값인 2147483647에 2를 더 한 값에 출력 전 다시 2를 더 하니 -2147483645가 된다.
최대값에 1을 더한 값은 정수의 최소값인 –2147483648


num = num – 2;

1) num의 값을 읽어와 레지스터에 저장.
2) CU는 -2라는 값의 2의 보수를 취하여 더하라는 명령을 해독하여 ALU를 제어해 레지스터의 값에 2를 뺌. 




image

 

⑦ num = num – 2;

num의 주소로 레지스터의 값을 전송.

 

⑨ printf(“최대값보다 2가 작은 값은 %d.\n”, num - 2);

1) num의 값을 레지스터로 전송.
2) 레지스터와 -2의 2의 보수를 더하여 다시 레지스터에 저장.
3) GPU의 레지스터(메모리)로 CPU의 레지스터의 값을 전송. (부가적인 데이터와 명령은 설명 안 함.)
4) 그래픽카드의 메모리의 값이 모니터에 뿌려짐.

※레지스터에서 그래픽카드로 전송 후 다시 메모리로 전송하지 않았으니 num의 값은 유지됨.

 

image

-2147483647에 2를 뺀 값에 출력 전 다시 2를 빼니 2147483645가 된다.
정수의 최대값에 2을 뺀 값이 출력된다.

즉, ①~⑧까지 과정을 거치면 아래와 같은 결과가 출력이 된다.

 

image

 

6.예제 2-2 scanf()

image

 

scanf(“%d”, &number);             -> 10진수 입력

scan: 스캔(복사)하다. 키보드를 스캔함.
f: funtion의 약자로 함수, 기능을 뜻함. 여기선 함수임.

%d뒤에 개행문자 넣지 말 것.      
‘&’ : ampersand, 앰퍼샌트 –> 후에 포인트할 때 하니 지금은 외울 것.

number의 주소를 인수로 전달하고 키보드로부터 10진수 입력을 받아 number에 넣으라는 함수.
이 scanf()함수를 만나면 멈춤 –> block  -> 엔터키를 누름 –> 탈출.

 

키보드 모니터
입력 (Input) 출력 (Output)
#include <stdio.h> –> 표준입출력을 사용하겠다.
stdio.h (표준 입출력 헤더 파일)에는 마우스입력이 없다. 마우스는 표준입출력이 아니다. (C표준)
8bit시절은 마우스가 필수가 아님.

printf()도 마찬가지로…

printf: 출력
f: funtion. 함수.

★funtion의 뜻인 기능에 관해…옛날 DOS의 추억 속으로

현재 윈도우의 F1키는 도움말이나 도스창 F1키는 과거에 친 명령어를 재생한다.
키보드의 F1~F12키에서 F가 funtion의 약자. 기능키. 함수키X

★소스를 변경해서 연습해보자.

Input

Output

설명

%d

%d

10진수를 입력 받아 10진수로 출력.

%x

%d

16진수를 입력 받아 10진수로 출력.

%d

%x

10진수를 입력 받아 16진수로 출력.

★ 형식지정자 앞에 붙은 숫자에 관하여

printf()에서 %3d라는 형식지정자는 3자리를 확보하여 오른쪽 정렬로 출력하라는 뜻임.
printf(“%3d”,10);이라는 명령문의 출력은 아래와 같이,

 

1

0

3자리를 확보하고 두 자릿수의 숫자를 출력하려니 최초 한자리는 빈 공간이고 다음 ‘1’ ‘0’이..
순서대로 출력이 된다.
그러나, printf(“%3d”,10000);과 같이 자릿수를 초과하는 숫자는..

1

0

0

0

0

모든 자리의 수를 다 표시한다. (하위 3자리만 짤려서 출력될 것이라고 생각하였으나 모두 출력됨.)

printf()에서 %-3d라는 형식지정자는 3자리를 확보하여 왼쪽 정렬하여 출력하라는 뜻임.
printf(“%-3d”,10); 이라는 명령문의 출력은 아래와 같이,

1

0

3자리를 확보하고 두 자릿수의 숫자를 출력하려니 ‘1’ ‘0’의 다음에 마지막은 빈 공간이 된다.
표시할 수가 큰 경우엔 %3d와 마찬가지로 모든 자리의 수가 출력이 된다.

7. 파생된 정수형

정수형

바이트 크기

범위

(signed) int

4

-2,147,483,648 ~ 2,147,483,647

unsigned (int)

4

0 ~ 4,294,967,295

short (int)

2

-32,768 ~ 32,767

unsigned short (int)

2

0 ~ 65,535

(signed) long (int)

4

-2,147,483,648 ~ 2,147,483,647

unsigned long (int)

4

0 ~ 4,294,967,295

unsigned int의 경우 상기의 표와 같이 int를 생략하여 unsigned만 타이핑하여도 되나,
알아보기 쉽게 int를 넣어주는 것이 좋을 것 같다.

앞으로 long형이 64bit크기가 될 수도 있는데 아래의 관계를 보면,

char (1Byte) < short (2Byte) < int (4Byte) == long (4Byte)

현재 VS6.0은 이런 식이나,

char ≤ short ≤ int ≤ long

C표준에는 이렇게 정의하고 있어 long이 1Byte가 될 수도 있고 int형보다 큰 8Byte가 될 수도 있다.

※앞으로 할 ATMEGA수업에선 int가 4Byte가 아닐 수도 있으니 sizeof연산자로 확인하여 볼 것.

 

8. 크기를 알아내는 sizeof연산자 (예제 2-3)

image

 

변수의 경우 괄호를 하지 않아도 되나 괄호를 붙여 줄 것.

 

9. 정수형 상수 constant

const : 예약어

image

13 = 12;    -> 상수는 대입 안 됨.
12 = A;     -> 상수는 대입 안 됨.
’A’ = A;     -> 문자도 상수다. 컴퓨터 내부에서 수치로 저장함. 문자 ↔ 숫자

 

10. 예제 2-6

image 

마지막 printf()의 020은 8진수로 10진수로 출력 시 16임.
                     0x20은 16진수로 10진수로 출력 시 32임.

 

image 

 

11. 레고 마인드스톰 RoboArm T-56 이론

 

image


자유롭게 움직일 수 있는 축(Joint)이 두 개이므로 2DOF(degree of freedom)
Joint1,2와 Link1,2를 합하여 arm(팔)이라고 한다. 

 

12. 레고 마인드스톰 Spike (전갈로봇)


clip_image002[5]

 

DSCN1818DSCN1819DSCN1820DSCN1821

전과 마찬가지로 나는 부품을 찾고 기본적인 모듈만 조립하고 본체는 진우가 담당.
험난한 1시간 정도의 조립과정을 거쳐 귀여운 전갈로봇이 완성되었다.

 

http://www.youtube.com/watch?v=Cmi6rcql8bY

앞으로 갔다 정지 후 뒤로 가기

 

http://www.youtube.com/watch?v=PYyXswoQm4Q

앞으로 갔다가 제자리서 회전 후 다시 제자리로 돌아오기

 

센서 없이 기본 동작만 하니 재미가 없다…라인 따라가기를 해보자.

image

빛 센서 두 개를 이용한 라인 따라가기 소스
한 개를 이용한 소스와 다른 점은 모든 센서가 흰 바탕일 때 직진이다.

 

DSCN1825DSCN1826DSCN1827DSCN1828


센서 두 개를 달았을 때가 센서를 하나 달았을 때 보다 이동속도가 2배 이상 향상된 것을 아래의..
동영상에서 확인하기 바란다.

 

센서를 하나 단 라인트레이서

 

 

센서를 두 개 달았으나 START에서 이탈

 

센서를 두 개 달았으나 START에서 이탈2

 

 

START지점 통과 성공!