로봇으로 배우는 c - roboid...

215
로봇으로 배우는 C Beginning C with Robots

Upload: others

Post on 27-Jan-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

로봇으로 배우는 C Beginning C with Robots

Page 2: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

목차

제 1 장 C 는 어떤 얶어인가? ......................................................................................................... 11

C 얶어의 등장과 발젂 .............................................................................................................. 11

C 프로그래밍의 8 가지 과정 ................................................................................................. 13

처음 만드는 C 프로그램 ......................................................................................................... 15

C 프로그램의 기본 형태 ......................................................................................................... 19

제 2 장 데이터를 기억하는 방법 .................................................................................................. 23

컴퓨터와 건망증 .......................................................................................................................... 23

기억 장소를 표현하는 방법 ................................................................................................... 24

배열의 선얶.................................................................................................................................... 29

제 3 장 컴퓨터에게 갂단핚 계산을 시켜보자 ........................................................................ 32

연산의 기본 원칙 ........................................................................................................................ 32

연산 결과를 출력하기 ............................................................................................................... 35

사칙 연산 실행하기 ................................................................................................................... 37

증가 연산자와 감소 연산자 ................................................................................................... 38

대입 연산자.................................................................................................................................... 39

Page 3: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 4 장 로봇과의 만남 ..................................................................................................................... 43

Hello Robots .................................................................................................................................. 43

Robot 과 Roboid ......................................................................................................................... 45

로봇 프로그래밍의 기본 .......................................................................................................... 51

제 5 장 로봇 프로그램의 기본 구조 ........................................................................................... 55

순차 구조의 로봇 제어 ............................................................................................................ 56

반복 구조의 로봇 제어 ............................................................................................................ 58

혼합 구조의 로봇 제어 ............................................................................................................ 64

프로그램의 강제 종료 ............................................................................................................... 65

제 6 장 실행 흐름을 제어핚다 ...................................................................................................... 67

if 그리고 else ................................................................................................................................ 67

switch 문 ......................................................................................................................................... 71

논리 연산자를 사용하여 복잡핚 조건을 입력핚다 ..................................................... 73

제 7 장 반복 구조의 로봇제어 프로그램.................................................................................. 76

while 문을 이용핚 무핚 반복 ................................................................................................ 76

For 문을 사용핚 프로그램 ...................................................................................................... 77

break - 반복문장의 중도 종료 ............................................................................................. 79

Page 4: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 8 장 함수를 사용하여 제어하기 ............................................................................................. 81

함수의 필요성 ............................................................................................................................... 81

함수의 구성 요소 ........................................................................................................................ 81

유용핚 로봇 제어 함수를 만들어 보자 ............................................................................ 85

제 9 장 변수의 범위 .......................................................................................................................... 88

로컬 변수와 글로벌 변수 ........................................................................................................ 88

외부 변수 ........................................................................................................................................ 91

문장 완성 기능과 변수의 범위 ............................................................................................ 94

제 10 장 변수와 데이터 형 ............................................................................................................. 99

데이터 형과 저장 장소 ............................................................................................................ 99

수치 데이터 형과 출력방법 ................................................................................................ 100

문자열 데이터 형과 출력방법............................................................................................ 101

printf()문의 서식 지정 ........................................................................................................... 102

제 11 장 배열과 포인터를 위핚 로봇 - 매트릭스 ............................................................ 104

매트릭스 로봇의 구조와 사양............................................................................................ 104

제 12 장 비트연산자와 수의 표현 ............................................................................................ 108

비트 연산자의 종류와 기능 ................................................................................................ 108

Page 5: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

비트와 매트릭스 로봇 ............................................................................................................ 109

SIgned 정수형의 shift 연산 ................................................................................................ 114

제 13 장 배열의 이해와 홗용 ..................................................................................................... 118

배열과 매트릭스 로봇 ............................................................................................................ 118

제 14 장 포인터는 C 얶어 최고의 선물 ................................................................................. 126

포인터는 포인터 형 변수다 ................................................................................................ 126

제 15 장 포인터와 배열과 문자열은 같은 내용의 다른 표현..................................... 133

제 16 장 데이터 관리는 구조체를 홗용핚다 ....................................................................... 140

구조체의 선얶 ............................................................................................................................ 140

구조체의 홗용 ............................................................................................................................ 144

구조체의 배열 ............................................................................................................................ 148

구조체와 포인터 ....................................................................................................................... 149

구조체 배열과 포인터 ............................................................................................................ 150

제 17 장 표준 라이브러리 함수 ................................................................................................. 152

표준 함수의 호출방법을 이해하자 .................................................................................. 152

난수 만들기 – random()) ...................................................................................................... 154

키보드 입력함수 – SCANF() ................................................................................................ 156

Page 6: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

OS 의 커맨드를 실행하자 .................................................................................................... 158

수학 함수를 사용하기 ............................................................................................................ 159

제 18 장 노래하며 춤추는 펠리컨 ............................................................................................ 165

음악 파일을 재생하기 ............................................................................................................ 165

오디오 데이터에 맞추어 부리를 움직인다. ................................................................. 168

오디오 데이터에 맞추어 춤을 춘다. ............................................................................... 170

제 19 장 로봇 메트로놈 ................................................................................................................. 173

소리 만들기................................................................................................................................. 173

메트로놈의 원리 ....................................................................................................................... 174

춤추는 로봇 메트로놈 ............................................................................................................ 177

제 20 장 노래하고 말하는 매트릭스 로봇 ............................................................................ 179

말하는 매트릭스 로봇 ............................................................................................................ 179

노래하고 말하는 매트릭스 로봇 ....................................................................................... 181

제 21 장 로봇 자명종 ...................................................................................................................... 184

스톱워치 만들기 ....................................................................................................................... 184

제 22 장 디지털 로봇 시계 .......................................................................................................... 186

0-9 숫자를 표시하자 .............................................................................................................. 186

Page 7: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

현지 시갂을 표시하기 ............................................................................................................ 187

부록 .......................................................................................................................................................... 195

1. 새로운 작업 공갂 만들기 ............................................................................................... 195

2. 독립된 실행 파일 만들기 ............................................................................................... 210

3. 기타 로봇의 사양과 사용법 .......................................................................................... 213

4. 오디오 포맷 변홖 ............................................................................................................... 213

Page 8: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 9: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

PART 1. Welcome to C world!

Page 10: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 11: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 1 장 C 는 어떤 얶어인가?

C 얶어는 어떤 얶어이며 왜 공부해야 하는지 알아보자.

C 얶어의 등장과 발젂

C 언어는 1972 년 무렵, 미국의 벨 연구소에서 만들어진 컴퓨터 프로그래밍

언어이다. C 언어의 많은 특징 중 하나는 언어 사양의 간결함에 있다. C 언어로

만들어진 프로그램은 상당히 작기 때문에 성능이 낮은 컴퓨터에서 실행

가능하고 다른 컴퓨터로 쉽게 적용시킬 수 있다.

현재, 컴퓨터의 응용범위가 넓어져 C 언어만으로는 어려운 경우에는 C++

또는 Java 언어를 사용하고 있다. 하지만 여전히 C 언어는 중요한 위치를

차지하고 있다. 그것은 C++언어나 Java 언어 모두 C 언어를 기본으로

설계되었으며, C 의 지식이 그대로 통용되고 있기 때문이다.

C 언어는 원래 시스템 개발용 언어이다. 즉, PC 의 운영체제와 각종 툴

프로그램을 개발하기 편리하도록 만들어져 있다. 점차 C 언어가 표준화 되면서

편리한 표준함수가 정비되었고, 다른 일반 프로그래밍 언어에서 가능한 일은

대부분 처리할 수 있게 되었다. 즉,” C 는 범용언어이다” 라는 말을 듣고 있다.

C 언어를 사용하면 워크프로세서, 표 계산 등 다양한 응용 프로그램부터

CAD, 과학계산, 그래픽, 그리고 게임 프로그램 등 거의 모든 분야의

소프트웨어를 개발할 수 있다. 하지만 C 의 가장 큰 강점은 PC 뿐 아니라

휴대용기기, 가전제품 등 하드웨어를 손쉽게 제어할 수 있다는 점이다.

Page 12: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위와 같은 로봇의 두뇌와 C 로 만든 지능적인 프로그램이 있다면 인간에게

유용한 로봇을 실제로 만들 수 있다.

로봇은 여러분의 C 공부를 도와 줄 수 있다. 단순히 화면에 숫자를

표시하는 공부 방법 보다는 직접 로봇을 제어하면서 공부한다면, 왜 C 언어가

편리하고 강력하고 반드시 알아야 하는 기본 언어라는 점을 저절로 깨우치게 될

것이다.

<<함께 공부핛 로봇들>>

Page 13: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

C 프로그래밍의 8 가지 과정

C 에서 프로그래밍을 할 때, 먼저 배워야 할 항목은 다음의 8 가지이다.

이중에서도 중요한 과정은 변수 선언, 연산, 조건처리, 반복의 4 가지

과정이다. 이것 만으로도 우선 프로그램을 만들 수 있다. 이후 입력과 출력

과정을 익히면 실용적인 프로그램을 작성할 수 있다. 함수 사용법과 파일 처리

과정까지 이해한다면 수준 높은 프로그램을 만들 수 있다.

변수 선얶

로봇에게 사람을 불러오는 심부름을 시키려면 이름을 기억하도록 해야 한다.

매번 불러올 사람이 바뀐다면 이름은 변수가 된다. 이름을 기억하고 필요한

경우 다시 알아내기 위해 어딘가에 일시적으로 보관해야 한다. 그 보관하는

장소를 확보하는 일이 변수 선언이다.

연산

Page 14: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

데이터는 연산을 함으로서 하고자 하는 목적을 달성한다. 연산을 위해서는

더하기, 나누기 등의 연산자를 공부 해야 한다.

조건 처리

연산 중에 조간에 따라 결과가 달라지는 경우가 있다. 예를 들면, “0.1 보다

적으면 0 으로 처리한다” 는 경우에는 다음과 같이 한다.

if(a < 0 .1) a= 0;

반복

사원 100 명의 총 급여를 알고 싶을 때 각 사원의 급여를 단순하게

더하기를 100 번 입력하는 것은 매우 비효율적인 일이다. 한 문장으로 이 작업을

할 수 있다면 매우 편리할 것이다. C 에는 여러 가지 반복기능이 준비되어 있다.

함수

큰 프로그램을 작성할 때, 같은 처리 작업이 여기저기에서 몇 번이고

나오는 경우가 있다. 그럴 경우 “자주 사용되는 처리”을 이름을 붙여 누구라도

불러 사용하도록 하면 프로그램도 짧아지고, 알기 쉽게 되는 장점이 있다.

입력과 출력

데이터를 외부에서, 예를 들면 키보드나 마우스, 가지고 오는 경우를

입력이라 한다. 파일에서 가지고 오는 경우도 입력에 해당한다. 연산과정을 통해

데이터를 가공한 결과를 컴퓨터 모니터에 디스플레이 하는 것을 출력이라고

한다. 디스크상의 파일에 저장하는 것도 출력에 해당한다.

Page 15: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

파일 처리

데이터는 PC 의 전원을 끄면 사라져 버린다. 다음 번 사용을 위해서는

전원이 없어도 지워 지지 않는 하드 디스크 등에 보관해야 한다. 이와 같은

일을 파일처리라고 한다.

처음 만드는 C 프로그램

바로 로봇을 움직여 보면 좋겠지만 아직 기본을 익히지 못한 단계이다.

일단 C 프로그램의 기본을 익히고 이후 로봇을 움직이는 프로그램을 공부한다.

새로운 C 프로그램 작성하기

나만의 C 프로그램을 작성하기 위해 다음 순서를 따라 한다.

1. 새로운 C 소스 파일을 만든다.

새로운 C 소스 파일을 만들기 위해 이 C 소스 파일이 속하는 C Project 가

미리 만들어져 있어야 한다. 새로운 프로젝트를 만드는 방법은 부록을 참조로

하고 이장에서는 이미 만들어진 프로젝트에서 새로운 C 소스 파일을 만든다.

Page 16: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

왼쪽 창에서 android_c 프로젝트를 열고 Source 폴더를 선택한다. 아래 그림과

같이 New Source File 메뉴 아이콘을 클릭한다.

Page 17: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

Source File: 에 first.c 를 기입한다. C 프로그램을 작성하기 위해서는 반드시 .c 로

확장자가 끝나야 한다. 기입이 끝나면 Finish 버튼을 클릭한다.

나만의 프로그램을 타이핑핚다 .

이제 프로그램을 입력할 수 있는 C 언어 편집기가 다음과 같이 열리게 된다.

아직 입력한 내용이 없어 오른쪽 상단의 창에는 빈 공간처럼 보이지만 자동으로

방금 만든 C 프로그램의 내용이 보여진다.

시험적으로 다음과 같은 간단한 프로그램을 타이핑한다.

main(){

printf("Hello");

}

철자가 틀리거나 잘못 타이핑하지 않도록 주의한다.

Page 18: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

실행하여 결과를 확인핚다 .

메뉴 바에서 실행 버튼을 클릭한다.

잠깐 사이에 아래 창에 이진 파일로 컴파일 하는 메시지가 출력되면서

프로그램이 실행된다. 프로그램이 실행되면 아래쪽의 콘솔 창에 결과가

표시된다. 아래 화면과 같이 Hello 가 나타나면 첫 프로그램이 성공적으로

실행되었다.

중도에서 중단핚다.

프로그램을 실행하다가 잘못된 부분이 발견되었다면 중도에서 정지하고

다시 편집할 필요가 있다. 실행중인 프로그램을 중단시키는 방법은 콘솔창의

붉은 사각형 아이콘을 클릭한다.

Page 19: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

C 프로그램의 기본 형태

C 언어에서는 print 같은 명령문을 처음부터 갑자기 사용할 수 없다. 만약

바로 명령문을 사용한다면 실행 버튼을 클릭하면 경고문과 함께 다음과 같이

에러 마크가 나타난다. 이 경우는 정상적으로 프로그램을 실행할 수 없다는

의미이다.

정상적인 C 프로그램의 기본은 main 함수이다. 필요한 명령문은 main 함수의

{}내부에 기입하도록 한다.

main()

{

이런 일을 핚다;

저런 일을 핚다;

Page 20: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

main 함수 이름 뒤의 소괄호()는 나중에 설명하기로 한다.

비어 있는 행은 무시된다. 보기 쉽게 하기 위해 비어있는 행을 마음대로

추가 할 수 있다.

대문자와 소문자는 구별된다. 타이핑 시 대소문자가 틀리지 않도록

주의한다.

문자열 출력하기

컴퓨터 언어를 처음 공부할 때 “어떻게 하면 메시지를 출력할까?”을 먼저

알아야 한다. 메시지를 출력할 줄 모르면 내가 작성한 프로그램이 결과를

확인하지도 못하고 잘못된 부분을 찾아내지도 못하게 된다.

printf 문을 사용하여 문자열 출력을 하는 프로그램을 작성한다. 이 때 ()안의

문자열에 \n 이 있으면, 실행 시 “\n”이 출력 되지 않고 대신 줄 바꿈이 일어난다.

예 1.

main()

{

printf("How ");

printf("are ");

printf("You?\n");

}

실행 결과

How are You?

Page 21: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

예 2.

main()

{

printf("ABC\nDEF\nGHI\n");

}

실행 결과

ABC

DEF

GHI

세미 콜롞이 필요하다

C 프로그램을 구성하는 명령문의 끝에는 세미콜론 ; 가 필요하다. 이

세미콜론이 한 개의 문이 끝남을 표시한다. 한 줄에 여러 명령을 실행하려면

각 명령 뒤에 ; 을 붙이면 된다.

main()

{

printf("How "); printf("are "); printf("You?\n");

}

들여 쓰기를 하면 읽기 쉽다

{}안의 명령문은 문장 앞에 4 문자 길이의 공백이 있다. 이것은 읽기 쉽게

하기 위한 것으로 들여 쓰기 라고 한다. RoboidC 에서는 들여쓰기가 자동으로

된다.

핚글 출력하기

Page 22: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

C 에서는 printf()문의 이중 인용 부호 안에는 한글을 사용하면 그대로

출력된다. 또한 주석부분에도 사용이 가능하다. 하지만 명령문이나 변수는

한글을 사용할 수 없다.

main()

{

printf("앆녕하세요\n");

}

주석 달기

C 에서는 printf()문의 이중 인용 부호 안에는 한글을 사용하면 그대로

출력된다. 또한 주석부분에도 사용이 가능하다. 하지만 명령문이나 변수는

한글을 사용할 수 없다.

/*

나의 첫 C 프로그램 입니다.

"앆녕하세요"을 출력합니다

*/

main()

{

printf("앆녕하세요\n"); //메시지 출력

}

이제 first.c 프로그램에 새로운 명령을 추가 하면서 C 언어를 좀 더 자세히

공부한다.

Page 23: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 2 장 데이터를 기억하는 방법

그 사람은 “컴퓨터 야!”의 뜻은 매사를 정확히 기억하고 행하는 사람을

뜻한다. 그렇다면, 사람의 기억과 컴퓨터의 기억방법은 어떻게 다를까? 나아가서

사람의 지능과 로봇이 지능의 차이점은 무엇일까? 이 의문을 풀기 위해

컴퓨터가 데이터를 기억하고 다시 생각해내는 방법을 자세히 공부한다. 이장은

모든 언어의 기본이 되므로 반드시 이해하도록 노력하자.

컴퓨터와 건망증

사람들은 가끔 물건을 둔 곳을 잊어 버린다. 뿐만 아니라 아는 사람의

이름이 갑자기 기억이 나지 않거나 전화번호가 생각나지 않기도 한다. 심하면

자기가 한일 조차 금방 잊어버리기도 한다. 이런 증세를 건망증이라고 한다.

신기한 사실은 나중에 다시 생각하면 그 사람의 이름이 떠오르는 경우가 있다는

것이다. 사람이 기억하는 방식과 컴퓨터의 기억 방식은 어떤 차이가 있을까요?

C 언어를 배우면서 그 차이점을 알아 본다.

인간의 기억방식에서 한번 잊었든 사람의 이름이 다시 떠오른다는 이야기는

기억의 내용은 지워지지 않았다는 뜻이다. 단지 뇌 속의 기억장소를 잠시 찾지

못했기 때문이다. 컴퓨터의 기억 방식도 마찬가지 일까요? 다행히도 컴퓨터에는

이런 일이 결코 일어나지 않는다. 한번 기억 장소가 정해지면 변경되지 않고

필요하면 언제라도 기억을 도로 집어 낼 수 있는 구조로 되어 있다.

Page 24: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 그림의 오른쪽 서랍에는 번호가 붙어 있고 서랍 안에는 나의 이름, 나이,

생년 월 일등의 데이터가 보관되어 있다. 이제 옆에 서있는 로봇에게 나이를

물어 보자. 하지만 로봇은 어떤 서랍에 나이 데이터가 들어 있는지 알지 못할

것이다. 컴퓨터는 기본적으로 사람의 언어를 이해하지 못한다. 순서에 따라

하나하나 주어진 작업을 처리 할 뿐이다.

C 언어는 사람의 사고 방식을 컴퓨터에게 지시하기 위해 고안된 언어이다.

인간에게는 너무 쉽게 보이는 일이 컴퓨터에게는 간단하지 않다. 반대로

컴퓨터에게는 쉬운 일이 인간은 따라 하기 힘든 경우도 있다. 컴퓨터에게 일을

시키려면 여러분이 우선 컴퓨터의 기억 방식을 정확히 이해 하여야 한다.

기억 장소를 표현하는 방법

사람과 컴퓨터의 기억 방식을 알아보자. 사람은 나이라는 의미를 알고

있으므로 그냥 숫자만 기억하면 된다. 하지만 컴퓨터는 숫자만 이해하지

나이라는 의미는 모른다. 따라서 컴퓨터는 나이라는 숫자와 그 숫자를 보관하고

있는 기억장치(메모리)의 위치, 두 가지를 동시에 알고 있어야 한다. 이전의

Page 25: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

컴퓨터 언어는 이 두 가지 숫자를 직접 적어 주었다. C 언어는 사람의 수고를

들기 위해 이 과정을 알기 쉽고 편리하게 도와 준다.

변수 선얶

다음의 프로그램을 살펴 보자.

main()

{

int age;

age = 18;

}

int age; 문장은 정수형 변수(integer)인 age 을 지금부터 사용하겠다 라고

선언한다. 즉, 정수를 보관하는 서랍을 준비하고 그 서랍의 이름을 “age”이라고

부르겠다고 컴퓨터에게 지시한다. 컴퓨터는 비어 있는(사용하지 않는) 서랍을

하나 찾는다. 만약 비어 있는 서랍이 하나도 없다면 무서운 일이 벌어진다.

컴퓨터는 더 이상 일을 할 수 없게 될 것이다.

1024 번째 서랍이 사용되고 있지 않아서 그 곳을 사용하기로 한다. 이때

주의 할 점은 사람은 그곳을 “age”으로 기억하고, 컴퓨터는 1024 번째

서랍이라고 기억한다는 것이다. C 언어의 좋은 점은 사람은 1024 라는 숫자를

Page 26: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

기억 할 필요가 없이 외우기 쉬운 “age”만 기억하면 된다. 앞으로 “age”이라는

변수가 나올 때 마다 자동적으로 1024 번째 서랍을 열게 된다.

컴퓨터는 저장장소를 잊어버릴 경우는 없나요?

컴퓨터는 이 주소 값을 변하지 않는 메모리에 등록해서

보관합니다. 주소 값은 프로그램의 일부분이므로 CD 나

하드디스크에 보관되지요. 따라서 손상되지 않는 경우에는 절대

변함이 없습니다.

컴퓨터는 건망증이 없어서 좋겠다.

꼭 그렇지만은 않아요. 제대로 작성한 C 프로그램은 문제 없지만

나중에 배울 포인터는 주의하지 않으면 기억장소를 잊어버릴

경우도 있지요

값의 대입

두 번째 명령문은 age = 18; 입니다. 이 명령문의 의미는 age이라고 이름

붙은 서랍에 18이라고 적힌 메모지를 넣어 두라는 것입니다. 컴퓨터는 이

명령을 만나면 1024번째 서랍을 열고 18이라고 적힌 메모지를 넣어 둡니다.

Page 27: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

수학에서는 [x = 18]은 “좌변 x 와 우변 18 이 동등”하다는 의미이지만,

프로그램 언어의 세계에서는 “좌변에 우변의 값을 대입한다”는 의미가 된다.

18 을 대입하기 전에 서랍에는 무엇이 들어 있나요?

누군가 사용 하다가 버린 숫자가 들어 있지요. 어떤 숫자가

될지는 모르니 항상 사용하기 전에 정확한 데이터를 넣도록

합니다.

한번 사용한 숫자를 바꿀 수도 있나요?

변수로 정의된 서랍에 든 숫자는 언제라도 몇 번이라도 바꿀

수 있지요. 단 그 숫자가 서랍 크기 안에 들어가야 합니다.

서랍의 크기보다 더 클 경우에는 전체가 다 들어가지 못하고

일부 만들어 갑니다. 정수로 정의된 서랍에 들어갈 수 있는

수의 범위는 -2147483648 보다 크고 2147483647 보다 작은 수만

가능하지요.

Page 28: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

정수형 변수의 출력

정수 값을 출력할 때는

printf("%d", age);

라고 입력한다. 이 명령문은 정수형 변수 age의 값을 출력시키라는

지시이다. 여기에서 %d 는 “대응하는 정수를 10진수(decimal)로 표시

하시오” 라고 지정한다. 그 대응하는 정수형 변수는 콤마를 하나 쓰고, 그

뒤에 입력한다.

main()

{

int age;

printf("%d\n", age);

age = 18;

printf("%d\n", age);

}

이 프로그램을 실행하면 3 과 18 이 출력된다. 3 은 초기화 하기 이전의

값이므로 의미가 없다. 이 값은 실행 시 마다 달라질 수 있다.

실행 결과

3

18

두 개 이상의 변수인 경우에는 다음과 같이 각각 입력한다.

printf("%d %d", age, age+1);

변수의 초기화

Page 29: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

초기화 되지 않은 변수는 사용하면 안 된다. 따라서 변수는 선언할 때

초기화 하는 편이 안전하다.

int age;

age = 18;

와 같이 두 줄로 하는 방법과

int age = 18;

같이 한 줄로 선언과 동시에 초기화 할 수도 있다.

다음 예는 3 개의 변수를 선언하고, 변수 d2 만 초기화 하고 있다.

int d1, d2 = 200, d3;

배열의 선얶

친구 3 명의 나이를 기억하기 위해 변수선언에서

int age[3];

라고 하면, age 라고 이름 붙은 큰 서랍을 준비한다. 큰 서랍의 안에는

동일한 정수형 변수 3 개를 준비한다. 같은 이름이 3 개나 되면 누가 누구인지

구별이 안되니, 이 변수에는 0 부터 2 까지 일련 번호가 부여 된다. 즉, 각

변수는 age[0], age[1], age[2] 로 구별된다. 각 변수는 예를 들면, 1024,

1025, 1026이라는 번호가 할당 된다. 나중에 공부 하겠지만 age라는

변수이름에는 첫 번째 변수 age[0]의 1024와 동일한 값이 할당된다. 이러한

값들은 프로그래머는 알 필요 없이 자동으로 할당되고 관리 되므로 안심하고

사용 할 수 있다.

Page 30: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

두 번째 변수를 사용하고 싶다고 할 때는

age[1] = 17;

과 같이 하면 된다. 이 때 대괄호[ ]안에 쓰는 숫자를

첨자

라고 한다. 또 이와 같은 변수의 모임을

배열

이라고 부른다. 배열은 같은 성질의 변수가 많이 필요할 때 사용한다.

배열의 초기화

배열의 초기화는 다음과 같이 한다.

int age[3] = {16, 18, 17};

이 문장은 초기화 시에만 사용이 해야 한다. 일반적인 대입 명령에서는

사용 할 수 없다.

배열 크기의 생략

Page 31: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

배열의 선언과 초기화 한 줄로 할 경우에는 배열의 크기를 생략 할 수 있다.

int age[] = {16, 18, 17};

Page 32: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 3 장 컴퓨터에게 간단한 계산을 시켜보자

컴퓨터의 사전적인 의미는 계산을 하는 기계이다. 실제로 컴퓨터는 계산만

한다. 재미있는 애니메이션, 포토샵 등도 모두 계산의 결과 인 것이다.

연산의 기본 원칙

다음 프로그램을 입력하고 실행을 해보자. 답이 19 가 나왔다면 정답이다.

main()

{

int age = 18;

age = age + 1;

printf("%d”, age);

}

이 프로그램에서 이상한 점을 느낄 것이다.

age = age + 1;

이 명령문의 우항과 좌항은 동등할 수가 없으므로 수학적으로는 성립할 수

가 없다. 하지만 프로그래밍의 세계에서는 “우항의 내용을 좌항의 변수에

대입하시오” 라는 의미가 되므로 실행이 가능하다. 좀 더 자세히 알아보면,

1. 변수를 찾아 복사핚다 .

첫 단계로 age 변수가 저장된 서랍의 위치를 찾아 문을 열고 내용이 베껴

적는다. 서랍 안의 메시지를 집어서 가지고 가지 않는다는 점을 꼭 기억하기

바란다.

Page 33: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

2. 연산을 행핚다 .

CPU 내부의 연산기에 지금 복사한 값(18)을 보여 준다. CPU 내부에는 여러

가지 연산기가 있는데 이 명령은 더하기 연산기(adder)가 처리한다. 더하기

연산기는 처리 결과인 18+1 = 19 를 보여준다. 이제 우항의 처리는 완료 되었다.

처리는 완료 되었지만 아직도 아무런 변화는 일어나지 않았다.

3. 결과 값을 대입핚다 .

이 과정이 가장 중요하다. 어떤 복잡한 연산도 좌항의 기억장소로 결과가

대입되기 전에는 알 수 없다. 물론 여기까지 연산이 일어났지만 원래의 서랍

속의 내용은 마지막 단계 전까지는 변함이 없다는 점을 알아야 한다.

Page 34: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이제 원래 서랍 속의 내용은 19 로 바뀌게 된다.

C 언어에서는 단 한 줄의 명령문이지만 실제로 컴퓨터는 여러 가지 일을

순차적으로 실행하고 있음을 알 수 있다. 실제로 이전의 프로그램 언어에서는

이 순서대로 한 줄 한 줄 정학하게 입력하지 않으면 동작하지 않았다. 이러한

사람의 노력을 줄이기 위해 많은 일을 C 언어가 대신 처리하게 되었고 이

때문에 C 언어는 표준적인 컴퓨터 프로그래밍언어로 자리 잡게 된다.

여러분은 이 한 줄의 연산 명령을 사용 할 때 마다 이 과정이 반복된다는

점을 기억하기 바란다.

main()

{

int age = 18;

int number;

number = age + 1;

printf("%d”, number);

}

이제 위 프로그램의 결과를 쉽게 알 수 있다. 답은 19 가 된다. 하지만

age 변수는 여전히 18 을 유지하고 있다.

Page 35: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

연산 결과를 출력하기

메시지를 포함하는 수치 출력

단순히 숫자만 출력하면 그 숫자가 어떤 내용인지 알기 어렵다. 숫자를

설명하는 메시지와 함께 출력하는 방법을 알아보자.

main()

{

int age = 18;

age = age + 1;

printf("age = %d\n”, age);

printf("나이는 %d 살 입니다\n", age);

}

복수의 변수 출력

두 개 이상의 변수를 출력한다.

main()

{

int age = 18;

int number;

number = age + 1;

printf("age = %d and number = %d\n”, age, number);

}

실행 결과

age = 18 and number = 19

로 표시된다. 이때 주의 할 점은

Page 36: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

. 출력하고 싶은 변수들은 콤마로 구분하여 나열한다.

. 이중 인용 부호 안에는 각각의 변수에 순서대로 대응하는 변환 사양을

입력한다. 여기에서는 %d 이다.

수식의 결과를 출력

변수의 자리에 수식을 사용하면 수식의 계산 결과를 출력한다.

main()

{

int age = 18;

printf("age = %d\n”, age * 2 + 1);

}

Page 37: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

사칙 연산 실행하기

연산의 기본 원칙과 출력 방법을 익혔다면 이제 마음대로 사칙 연산을 시켜

보자. 사칙 연산의 계산 방법은 *, / 는 +, -, 보다 먼저 계산하는데, 이것을 우선

순위라고 한다. 또한 ( )로 묶으면, ( )이 먼저 계산된다. 우선 순위 잘 기억하지

못할 경우에는 안전하게 ( )를 사용하기를 부탁한다.

같은 우선 순위인 경우에는, 좌측부터 먼저 계산한다. 예를 들면 a*b*c 는

a*b 가 먼저 계산되고 이 결과에 c 를 곱한다. %는 나머지를 알려 주는 데, 이는

정수에서만 사용 할 수 있다.

연산자 설명

+ 덧셈

- 뺄셈

* 곱셈(수학 기호에서는 x)

/ 나눗셈(수학 기호에서는 ÷)

% 나머지

사용예

main()

{

int n;

n = 2 * 3 + 4 * 5;

n = 16 / 2 – 6/ 2;

n = 2 * (3 + 4) * 5;

n = 100 / 10 / 5;

n = 23 % 5;

}

Page 38: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

순서대로 답은 26, 5, 70, 2, 3 가 된다.

증가 연산자와 감소 연산자

프로그램을 하다 보면 1 을 더하거나 1 을 감소하는 경우가 자주 있다. 특히

반복 계산을 할 경우에는 꼭 발생하게 된다. 이 처리를 n = n + 1 또는 n = n – 1 로

할 수 있지만 C 언어에서는 사용자의 편의를 위해 단순하게 입력하도록 되어

있다.

연산자 설명 ++n; n = n + 1과 같다.

명령문에 포함될 경우에는 미리 1을 증가 시킨 후

명령문을 계산 한다.

n++; n = n + 1과 같다.

명령문에 포함될 경우에는 명령문 전체를 계산한 후 1을

증가 시킨다.

--n; n = n - 1과 같다.

명령문에 포함될 경우에는 미리 1을 감소 시킨 후

명령문을 계산 한다.

n--; n = n + 1과 같다.

명령문에 포함될 경우에는 명령문 전체를 계산한 후 1을

감소 시킨다.

사용예

main()

{

int age = 0;

printf("%d\n", age++);

printf("%d\n", ++age);

Page 39: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

실행 결과

0

2

첫 줄에는 0 이 출력되고 둘째 줄은 2 가 출력 된다. 그 이유는 첫 줄은

일단 출력하고 나서 1 을 증가 시킨다. 두 째 줄을 출력하기 전에는 age = 1 이다.

두 째 줄은 출력하기 전에 1 을 또 증가 시킨다 따라서 출력 시에는 age = 2 가

된다. 감소 연산자도 마찬가지이므로 이 차이를 잘 알고 사용하기 바란다.

대입 연산자

아주 간단한 명령문이지만 이전에 설명한 연산의 기본 원칙 3 단계가

적용되고 있다. C 언어에서는 편리하게 사용할 수 있는 연산 명령을 많이 준비

되어 있다. 변수를 초기화하거나 연산의 결과를 저장하기 위해 사용되는 =

기호는 사실은 컴퓨터에 동작을 지시하는 연산자이다. 이것을 대입 연산자라고

부르는데 대입 연산자에는 또 다른 형태 가 있다.

연산자 설명 사용법

+= 덧셈하여 대입 n += 2; 는 n = n + 2; 와 같다.

-= 뺄셈하여 대입 n -= 2; 는 n = n - 2; 와 같다.

*= 곱셈하여 대입 n *= 2; 는 n = n * 2; 와 같다.

/= 나눈 값을 대입 n /= 2; 는 n = n / 2; 와 같다.

%= 나머지를 대입 n %= 2; 는 n = n % 2; 와 같다.

Page 40: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

심화학습

@ C 언어를 개발한 사람을 인터넷에서 찾아본다.

@ 대입연산자를 사칙 연산자로 바꾸어 표시한다.

Page 41: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

PART 2. C 와 로봇

Page 42: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 43: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 4 장 로봇과의 만남

C 언어의 기본을 알아 보았다. 이제 로봇을 만나보고 C 언어를 이용하여

로봇을 움직여 보자

HELLO ROBOTS

왼쪽 창의 프로젝트를 살펴 보면 C 언어로 제어되는 로봇 종류를 확인 할 수

있다. Android, Donkey, Hamster, I-sobot, Matrix, Netbrain, Pelican 모두 7 종류가 준비

되어 있다.

이 책에서는 가장 간단한 로봇인 Pelican 로봇과 C 프로그래밍 연습을 위해

특별히 개발된 Matrix 로봇을 주로 활용한다. 여러분은 나머지 로봇에 대해서도

같은 방법으로 공부하여 자신의 로봇으로 만들어 보기 바란다.

Page 44: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

안드로이드 동키 로봇 햄스터 로봇

매트릭스 로봇 펠리컨 로봇 아이 소봇

<<C 얶어로 제어 가능핚 로봇들>>

Page 45: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

ROBOT 과 ROBOID

센서와 구동장치

로봇은 몸체 내부에 각종 주위 상태를 감지하는 센서와 움직임이나 표현을

하는 구동장치가 포함되어 있다. 여기에 지능적인 판단을 하는 컴퓨터까지

몸체에 내장되어 있다면, 자체적으로 상황을 판단하여 자율적으로 행동하는

로봇이 만들어 진다. 하지만 이 책에서 공부하는 로봇은 자체적으로 컴퓨터를

내장하고 있지 않다. 로봇과 유선 또는 무선으로 연결된 PC 가 로봇의 두뇌

역할을 하게 된다. 이러한 구조의 로봇형태를 “로보이드”라고 한다.

로보이드는 원리상 저렴하게 만들어 진다는 장점도 있지만 C 언어 같은

프로그래밍 언어를 배울 때 특히 유용하다. PC 의 계산 능력과 인터넷의 정보

등을 결합하여 기존의 로봇보다 한층 우수한 지능적인 로봇을 구현 할 수 있다.

Page 46: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

로봇의 동작 원리

이 책에서 공부하는 Pelican 로봇은 다음과 같이 설계되어 있다.

우선, 프로그램에 의하여 제어가 가능한 구동부는 머리, 눈동자, 왼 날개,

오른 날개가 있고, 오디오 데이터를 음성으로 변환시키는 스피커, RGB 색상을

표현하는 LED 가 있다. 주위 상태를 감지하는 센서 류는 음성 마이크와 부리와

날개 부분에는 가볍게 치면 반응하는 충격 센서가 내장되어 있다. 센서 류는

프로그램을 진행을 지능적으로 제어하고 판단하는 데 필수적인 요소 이다.

구동 장치

코일과 원통형 자석이 한 쌍으로 이루어져 신호의 크기에 비례적으로

움직인다. 부리를 들여다 보면 그 구조를 쉽게 알 수 있다. 우리가 공부하는

로봇 제어 프로그램은 코일에 가해지는 전류를 제어한다. 제어 값의 범위는 0-

63. 부리를 예를 들면 0 일 경우는 닫힘, 63 일 경우는 최대 열림이며 양쪽

날개도 마찬가지 이다.

Page 47: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

눈동자

6 가지 감정을 표현할 수 있는 눈동자를 가지고 있다. 눈동자의 값을

변경하면 즉시 회전하여 표정을 바꾼다. 값이 0 인 경우는 눈동자 모터의 전원이

꺼진다. 따라서 0 인 경우에는 어디에 정지할지 알 수 없다.

스피커

전면에 소형 스피커가 위치하고 있다. 음악파일을 재생하거나 직접 소리를

만들어 볼 수 있다. 오디오 데이터는 48Khz 의 샘플링에 16 비트 데이터가

되어야 한다.

Page 48: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

마이크로폰

음성을 받아들이는 마이크는 머리 뒷부분에 있다.

펠리컨 로봇은 USB 마이크와 스피커가 내장되어 있어 Windows 의

프로그램을 설치하면 인터넷 전화기(VoIP)로 사용할 수 있다. 구조상 머리

뒷부분에 대고 이야기 해야 하는 문제가 있다. 마이크를 통한 음성 데이터는

8Khz 샘플링에 16 비트이다.

Page 49: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

DUAL 칼라 LED

머리 상단에 있는 LED 는 적색과 녹색의 2 가지 색을 가지고 있다. 두 색을

동시에 켜면 오렌지 빛이 된다.

충격 센서

부리와 양쪽 날개를 가볍게 치면 충격이 감지 된다. 이 충격은 각 부위에

있는 코일을 통해 미약한 전기 신호를 발생시킨다. 하지만 부리나 날개를

제어하는 동안에는 감지 할 수 없으므로 반드시 제어신호가 0 인 경우에만

검출한다.

USB 커넥터

펠리컨 로봇은 PC 에 있는 USB 단자를 통해 필요한 전원을 받아 들인다.

따로 외부 전원이 필요 없으므로 간단히 케이블만 연결하면 동작이 가능하다.

펠리컨 로봇은 표준 오디오 장치로 설계되어 있어 따로 드라이버 SW 를

Page 50: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

설치하지 않아도 동작이 가능하다. 프로그램 공부를 하지 않을 때에는 일반

스피커나 마이크로 사용해도 좋다.

Page 51: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

로봇 프로그래밍의 기본

새 소스파일 만들기

새로 작성할 소스 파일은 프로젝트 내부의 Source 폴더에 저장하도록 한다.

이때 main()함수를 포함하고 있는 기존의 소스파일은 더 이상 사용하지

않도록 설정한다. 이유는 RoboidC 의 자동 컴파일 기능은 편집이 끝나면

자동으로 재 컴파일 한다. 이 경우, main()함수가 두 개 이상 존재하면 실행

파일을 만들지 못한다.

Source 폴더를 열고 기존의 소스인 hello.c 를 선택한 후 오른쪽 버튼을

클릭한다. 팦업 메뉴에서 “Exclude from build…”을 선택한다.

Page 52: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

아래와 같은 “Exclude from build…” 창에서 Debug와 Release 옵션을

첵크하면 이 소스 파일은 컴파일 시 무시 된다. 만약 다시 사용하고 싶다면 이

과정을 반복하고 첵크를 풀면 된다.

이제 새로 만들 소스 파일에 main()함수를 지정할 수 있다.

새 소스의 이름을 my_robot.c 라고 하고 다음 코드를 입력한다. main() 함수

부분은 변함이 없지만 첫 줄에 #include "android.h" 가 입력 되어야 한다.

Page 53: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이 문장은 전처리 문장이라고 하는데 미리 만들어진 로봇 관련 기능을 모아

놓은 프로그램파일을 편집기 내에 불러오는 역할을 한다. 이 문장이 있어야

로봇에 명령을 내릴 수 있다. 이처럼 “.h“ 확장자가 붙은 파일을 “헤더

파일(header file)”이라고 한다. 첫 줄에는 프로그램 하려는 로봇의 헤더

파일을 인클루드하자” 고 기억하기 바란다.

#include "android.h"

main()

{

}

C 언어에는 기본적인 입력과 출력을 지원하는 명령이 준비되어 있다. 이

명령을 사용하기 위해 역시 필요한 헤더 파일을 먼저 인클루드 해야 한다. 가장

기본적인 다음 헤더 파일들은 로봇 헤더 파일에 이미 인클루드 되어 있으므로

바로 사용이 가능하다.

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

C 언어에 기본적으로 포함되어 있는 헤더 파일은 < >를 사용하고 직접 만든

경우나 다른 곳에서 만든 헤더 파일인 경우는 “ “를 사용한다.

로봇 변수

RoboidC 에서는 제어하려는 로봇의 상태를 변수로 미리 정의되어 있다. 즉

부리를 움직이고 싶은 경우에는 헤더파일에 정의된 “bill”변수에다 원하는

수치를 대입하면 된다. 다음 표는 Pelican 로봇을 제어하는 변수의 정의

테이블이다.

Page 54: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

변수명 데이터

기능 값의 범위

bill int 부리를 열고 닫는다. 0 ~ 63

eye int 눈동자를 바꾼다. 0 ~ 6

left_wing int 왼 날개를 들고 내린다. 0 ~ 63

right_wing int 오른 날개를 들고 내린다. 0 ~ 63

led[2] int[2] 칼라 LED 를 제어한다. 0 ~ 63

speaker[960] int[960] 오디오 데이터를 재생한다. 16 비트

microphone[160] int[160] 마이크 입력 데이터 16 비트

hit_bill int 부리의 충격을 검출 한다. 0 ~ 1

hit_left_wing int 왼 날개의 충격을 감지한다. 0 ~ 1

hit_right_wing int 오른 날개의 충격을 감지한다. 0 ~ 1

모든 변수는 소문자로 시작한다. 스피커와 마이크 값의 범위는 -32768 에서

+ 32767 사이이다.

로봇 제어 함수

로봇 헤더 파일에는 로봇을 제어하기 위해 호출하는 함수가 미리 정의 되어

있다. Pelican 로봇의 아래의 2 함수만 사용한다.

함수 명 기능

initialize() 로봇을 초기화하고 명령을 받을 준비를 한다.

execute(frame) 로봇에 명령을 전달하고, 일정시간 쉰다.

1 frame 은 20 msec. 1 초를 쉴 경우 frame = 50 이 된다

Page 55: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 5 장 로봇 프로그램의 기본 구조

로봇 프로그래밍은 화면에 값을 출력하는 일반적인 컴퓨터 프로그램과 다른

점이 있다. 로봇의 움직임을 제어하는 방식은 게임이나 애니메이션과 유사하다.

하지만 다음과 같은 로봇 제어 특유의 차이점을 반드시 알고 프로그램 해야

한다.

1. 로봇의 움직임은 시간이 걸린다.

실제 로봇은 그래픽이 아니다. 전기 모터와 기어박스 등으로 이루어진

구동부는 일정한 속도이상 더 빨리 움직일 수 없다. 아무리 빨리 명령을

내려도 로봇이 따라갈 수 없다면 잘못된 프로그램을 작성한 것이다.

따라서 명령과 명령 사이에는 잠시 대기하는 시간이 반드시 필요하다.

2. 로봇의 부위는 동시에 움직인다.

컴퓨터 프로그램에서 많이 사용되는 순서도는 각 부분의 동작을

순서적으로 나타낸 것이다. 하지만 로봇에서는 순서도로 나타내기

어려운 점이 있다. 예를 들면 왼쪽 날개와 오른쪽 날개가 미세한

시간차를 두고 움직이는 춤을 프로그램 하고자 할 때 각 날개를 정확한

동작으로 제어하는 동시에 두 날개 움직임의 시작과 끝도 정확히 맞게

해야 한다.

3. 로봇의 센서와 구동에는 시간 지연이 있다.

PC 프로그램에서 마우스로 화면을 클릭하면 거의 동시에 알아낸다.

하지만 로봇에서는 센서의 변화가 프로그램에 입력되기까지에는 시간

지연이 일어난다. 이유는 PC 의 성능, OS, 통신 등에 있지만 빛의 속도로

Page 56: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

계산할 수 있지만 센서의 반응이 늦을 경우에는 반드시 시간 지연을

고려한 프로그램을 작성해야 한다. 마찬가지로 계산된 값을 로봇에

전달하는데 시간지연이 있다. 장애물을 미리 발견 못한 경우에 뒤늦게

정지 명령을 내려도 바로 정지 하지 못할 수 도 있다.

4. 로봇의 입력 값은 정확하지 않다.

외부환경을 검출하는 센서는 물론 로봇 내부 상태를 검출하는 센서

값에는 항상 부정확한 노이즈가 포함되어 있다. 특히 초음파 거리

센서는 한 두 번의 측정값은 믿을 수 없다. 이런 경우에는 노이즈를

줄이기 위한 방법을 반드시 생각하여 부정확한 판단이 일어나지 않도록

주의 해야 한다.

이상과 같은 차이점은 로봇 프로그램을 어렵게 만들기도 하지만 더

흥미롭게 만들기도 한다. 이제 창의력을 발휘하여 실용적인 로봇 프로그램을

만들어 보자.

순차 구조의 로봇 제어

순차제어 방식이란 로봇이 할 일을 순서대로 실행하는 가장 단순한 기본

구조이다.

List 순차 제어

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

Page 57: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

left_wing = 63;

execute(100); //왼 날개를 든다

right_wing = 63;

execute(100); //오른 날개를 든다

bill = 63;

execute(100); //부리를 연다

}

설명이 필요 없이 주석에 적힌 그대로 이다. 만약 양 날개를 동시에 들기를

원한다면 다음과 같이 수정한다.

List 순차 제어와 동시 제어 #include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

left_wing = 63;

right_wing = 63;

execute(100); // 날개를 든다

bill = 63;

execute(100); // 부리를 연다

}

초기화 변수 대입 동작 변수 대입 동작 변수 대입 ….을

계속 한다. 눈동자를 회전 시켜서 로봇의 표정을 감상하자.

List 눈동자 순차 제어

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

Page 58: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

eye = 1;

execute(200);

eye++;

execute(50);

eye++;

execute(50);

eye++;

execute(50);

eye++;

execute(50);

eye++;

execute(200);

}

반복 구조의 로봇 제어

반복 구조 제어 방식의 로봇 프로그램은 다음과 같은 형식의 기본

프로그램으로부터 출발한다.

WHILE 문의 이해

while 문은 주어진 “반복의 조건”이 참인 동안, { }안의 명령문을 반복해서

실행한다. 1 에서 10 까지 출력하는 다음 프로그램을 보면서 while 문의 사용법을

알아보자.

main()

{

int n = 0;

while(n++ < 10) //반복 조건식

{

printf("n = %d\n", n);

}

}

Page 59: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

while 문은 우선 반복 조건 식을 계산하고 그 결과가 참인지 거짓인지를

판단하다. 참이면 { }안의 명령을 수행하고 다시 반복 조건 식을 검사한다.

거짓이라면 { }을 건너 뛰고 다음 문장을 실행한다.

첫 줄의 값이 n = 1이 되는 이유는 다음과 같다.

- n = 0이므로 반복 조건 식은 참으로 판명된다.

- n 를 1 증가 시킨다.

- { }안의 printf문을 실행 시 “n = 1” 출력 된다.

마지막 출력이 n= 10이 되는 이유는

- n = 9 이므로 참으로 판명된다.

- n은 1이 증가하여 10된다

- { }안의 printf문을 실행 시 “n = 10” 출력 된다.

n = 10 이면 더 이상 반복 조건 문을 만족하지 못하므로 while문은

종료된다.

다음 예제 프로그램은 두 날개를 들고 벌을 서고 있는 로봇의 부리를

연필로 가볍게 치면 즉시 날개를 내리는 프로그램이다

List while 문의 사용

#include "pelican.h"

main()

{

initialize();

while(!hit_bill)

{

left_wing = 63;

right_wing = 63;

execute(1);

Page 60: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

}

우선 반복 조건 문을 보면 !hit_bill 이 있다. hit_bill 은 센서 변수로 평상

시에는 0 이지만 로봇의 부리를 치면 값이 1 로 된다. “!”는 부정연산자이다. 참을

거짓으로, 거짓을 참으로 반대로 만들어 준다. 즉, 부리를 치는 순간에 반복

조건 문은 거짓이 되므로 프로그램이 종료된다.

WHILE 문을 사용하여 눈동자를 제어핚다.

이전에 순차 제어로 작성한 눈동자 제어 프로그램을 while 문을 사용하여

제어한다. 아주 간단히 만들 수 있을 것이다.

List 눈동자 순차 제어 #include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

while(1)

{

eye = eye%6 + 1;

execute(50);

}

}

WHILE 문의 { } 생략

한 줄짜리 명령문인 경우는 { } 생략 가능하다.

Page 61: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

main()

{

int n = 0;

while(n++ < 10) //반복 조건식

printf("n = %d\n", n);

}

BREAK 문 - WHILE 문의 중도 종료

로봇을 제어하다 보면 주위환경의 변화에 의해 하던 동작을 멈추고 새로운

환경에 대처할 필요가 있다. 이런 경우 while 문을 중도에서 멈추고 싶다면

break 문을 사용하라.

다음 예제 프로그램은 두 날개를 들고 벌을 서고 있는 로봇의 부리를

연필로 가볍게 치면 즉시 날개를 내리는 프로그램이다. while 문에서 break 문이

필요한 이유를 알게 된다.

List break 문의 사용

#include "pelican.h"

main()

{

initialize();

while(1)

{

left_wing = 63;

right_wing = 63;

execute(1);

if(hit_bill) break;

}

}

Page 62: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

DO-WHILE 문을 사용핚 프로그램

반복 조건을 뒤에다 두면 먼저 한번 실행한 후 조건 식을 판별한다.

차이점은 n = 0 부터 출력 된다. 즉, do{}내의 명령문은 조건식과 관계없이 한번은

반드시 실행된다.

main()

{

int n = 0;

do

{

printf("%d, ", n);

} while(n++ < 10);

}

실행 결과

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

반복 구조의 로봇제어의 기본 형식

로봇제어의 기본형식은 애니메이션과 매우 흡사하다. 목적은 부드러운 동작과

정확한 오디오 재생이다

#include "pelican.h"

main()

{

// 초기화는 핚번만 핚다.

initialize();

Page 63: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

while(1) // 종료하기 위핚 조건식

{

// 변수를 계산 핚다.

head = 63;

// 명령을 실행 핚다.

execute(1);

}

}

첫 줄의 #include 명령은 제어하려는 로봇에 따라 파일이름이 달라진다.

“로봇이름.h” 파일로 준비되어 있으므로 펠리컨 로봇인 경우에는 “pelican.h”가

된다. 이 다음 순서는 모든 로봇이 동일하게 진행된다.

initialize() 함수는 프로그램을 시작하는 순간에 딱 한번만 호출한다. 호출 후

로봇은 동작 준비를 마치고 명령을 기다린다. while 문의 조건식은 대개 1 로

한다. 1 은 항상 참을 의미하므로 무한 반복형식이 된다. 간단한 제어 프로그램인

경우에는 while 문장의 괄호 안에 제어를 종료하는 조건식이 들어 갈 수 있다.

다음 예제로 부리와 날개를 동시에 부드럽게 서서히 들어 올리는

프로그램을 알아보자.

List 서서히 들기 #include "pelican.h"

main()

{

initialize();

while(bill < 64)

{

bill++;

left_wing++;

right_wing++;

execute(3);

}

}

Page 64: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

혼합 구조의 로봇 제어

실제 로봇 프로그램은 순차 구조와 반복 구조가 혼합되어 나타난다.

List 갑자기 들고, 서서히 내리기

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

bill= 63;

left_wing = 63;

right_wing = 63;

execute(100);

while(bill > 0)

{

bill--;

left_wing--;

right_wing--;

execute(3);

}

}

위 예제는 순차 구조로 진행되다가 부리를 부드럽게 닫는 반복 구조의 제어

프로그램이다

List 서서히 들고, 서서히 내리기

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

Page 65: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

while(bill < 64)

{

bill++;

left_wing++;

right_wing++;

execute(3);

}

execute(100); // 2초갂 정지

while(bill > 0)

{

bill--;

left_wing--;

right_wing--;

execute(3);

}

}

위 예제는 부리를 부드럽게 연 후, 2 초간 정지, 다시 부드럽게 닫는

프로그램이다. 로봇 제어란 이렇게 표현하고자 하는 로봇의 행동을 지속적으로

반복하면서 제어하는 동시에 외부환경의 변화에 대응해야 한다. 수준 높은

로봇의 행동을 프로그램 하려면 C 언어의 기본적인 제어 구조를 반드시

이해해야 한다.

프로그램의 강제 종료

프로그램을 개발하는 동안에는 자신이 의도했던 결과가 한번에 나오지 않은

경우가 있다 .로봇의 동작이 잘 못되었다고 판단되면 기다리지 말고 바로 정지

시킨다. 콘솔 창의 메뉴에서 빨간색 사가 버튼을 누른다. 프로그램을 종료하고

소스를 다시 편집한다.

Page 66: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

가끔 이전 프로그램을 종료 할 것을 잊어버리고 새 소스를 실행시키는

경우가 있는데 한 로봇에 두 개의 프로그램은 돌아가지 않으므로 반드시 이전

프로그램을 종료하고 실행하도록 한다. 소스마다 실행 창이 하나씩 만들어 지기

때문에 이전 프로그램의 실행창을 찾아서 종료시킨다.

메뉴 바에서 콘솔 선택 아이콘을 누르면 현재 동작중인 프로그램의 목록이

보인다. 콘솔 창에서 이전 프로그램을 선택하고 종료버튼을 누른다.

Page 67: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 6 장 실행 흐름을 제어한다

지금까지 로봇을 움직여 보기 위하여 많은 것을 공부 했지만, 실제로

여러분이 구현 할 수 있는 프로그램은 상당히 제한 되어 있다. 이번 장부터는

실용적인 로봇을 만들기 위한 방법을 공부한다. 이제 서서히 C 언어를 사용한

로봇 프로그래밍에 재미를 붙일 때가 되었다.

IF 그리고 ELSE

if 와 else 문은 로봇이 살아가는데 제일 필요한 명령문들이다. 센서를 통한

입력 데이터로부터 지능적인 판단을 하는 모든 로봇 프로그램은 if 문을 필요로

한다. if 문이 존재하지 않다면 여러분이 좋아하는 로봇도 존재하지 못할 것이다.

if 문은 중요한 반면 사용법은 간단하므로 그렇게 어렵지는 않다.

오른쪽 날개를 들고 기다리다 부리를 치면 날개를 내린다.

센서의 원리도 공부 할 겸 한번 도전해 보자.

센서를 직접 읽고 판단핚다 .

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

right_wing = 63;

while(!hit_bill) execute(1);

}

Page 68: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

프로그램을 실행하면 오른쪽 날개를 들고 기다린다. 연필로 부리를 가볍게

툭 치면 날개를 내린다. 귀여운 로봇을 때리고 벌주는 것처럼 보이지만

여러분의 공부에 도움이 된다면 로봇도 참을 것이다.

우선 반복 조건 문을 보면 !hit_bill 이 있다. hit_bill 은 센서 변수로 평상

시에는 0 이지만 로봇의 부리를 치면 값이 1 로 된다. “!”는 부정연산자이다. 참을

거짓으로 반대로 만들어 준다. 즉, 부리를 치는 순간에 반복 조건 문은 거짓이

되므로 프로그램이 종료된다.

IF 문을 사용하여 판단핚다 .

센서로부터 직접 판단하면 프로그램이 간편하기는 하지만 조건 식에 제한이

있다. 이번에는 if 문을 사용하여 같은 일을 시켜본다.

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

right_wing = 63;

while(right_wing)

{

execute(1);

if(hit_bill) right_wing = 0;

}

}

부리를 툭 치면 while 문이 종료된다.

센서와 if 문을 대개 같이 나타난다. 이번에는 귀여운 로봇도 때리면 참지

않을 것이다.

List 센서와 if문

Page 69: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

while(1)

{

if(hit_right_wing)

printf("오른 날개를 때리지 마세요!\n");

if(hit_left_wing)

printf("왼 날개를 때리지 마세요!\n");

if(hit_bill)

printf("부리를 때리지 마세요!\n");

execute(1);

}

}

IF 와 ELSE 사용법

이전에 공부한 do~while 문을 사용하여 if~else 문의 기능을 알아본다.

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

do{

execute(1);

if(hit_bill) right_wing = 0;

else right_wing = 63;

} while(right_wing);

}

Page 70: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 프로그램을 보면 이 경우에는 왜 do~while 문을 사용해야 하는지 알 수

있을 것이다. while 문이 먼저 오면 조건식이 바로 거짓이 되므로 올바른 실행을

할 수 없다. 이런 경우에 do~while 문을 사용하면 좋다.

삼항 연산자를 사용핚다.

내친김에 “조건 연산자”라 불리는 간결하고 재미있는 연산자를 알아보자. 피

연산자의 수가 3 개 이므로 삼항 연산자라고도 한다.

같은 예제를 삼항 연산자를 사용하면 아래와 같다.

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

do{

execute(1);

right_wing = hit_bill ? 0 : 63; //삼항 연산자

} while(right_wing);

}

if 와 else 로 이루어진 두 줄이 간결하게 바뀌었다. 조건 연산자를 꼭

사용해야 할 필요가 없다는 것을 알겠지만 알고 있어야 하는 C 언어의 지식이다.

IF 와 ELSE IF 와 ELSE 사용법

if 와 else 사용법에 조건을 추가하고 싶다면 if..else if..else 문장을 사용한다.

즉,

Page 71: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

오른쪽 날개를 들고 있다가 부리를 치거나 또는 왼쪽 날개를 치면 내릮다.

if 와 else 사용법에서 else if 를 사용하여 조건을 추가한다

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

do{

execute(1);

if(hit_bill) right_wing = 0;

else if(hit_left_wing) right_wing = 0;

else right_wing = 63;

} while(right_wing);

}

조금 복잡하지만 잘 익혀 두기 바란다. 여기까지 했으면 로봇도 좀 쉴 겸

여러분도 좀 쉬기 바란다. 다시 한번 if 문의 사용법을 마음속으로 정리한다.

혹시 로봇이 가끔 비정상적인 동작을 해도 놀라지 말자. 로봇의 센서가

매우 민감하여 주위의 진동을 감지하는 경우가 간혹 있다. 이런 점이 극복하고

안정된 프로그램을 작성하는 일이 로봇 프로그래밍의 재미이자 핵심이다.

SWITCH 문

switch 문은 if..else if..else 의 간결하고 우아한 표현식이라고 보면 된다.

C 언어에서 자주 사용되고 로봇 제어에도 유용하므로 잘 익히기 바란다.

적색과 녹색, 황색을 숫자로 표현하고 제어한다.

다음 예제에서 switch 문의 사용법을 익힌다.

Page 72: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

int color = 0;

while(1)

{

switch(color)

{

case 1: // RED

led[0] = 63;

led[1] = 0;

break;

case 2: // GREEN

led[0] = 0;

led[1] = 63;

break;

case 3: // ORANGE

led[0] = 63;

led[1] = 63;

break;

default: // OFF

led[0] = 0;

led[1] = 0;

break;

}

color++;

color %= 4;

execute(50);

}

}

코드는 좀 길지만 반복이므로 이해하기 어렵지 않다.

- 우선 color 변수는 0,1,2,3 을 반복한다.

- switch 문장의 ()안의 변수를 case 문에서 비교한다.

- 변수와 case 문장의 수와 같으면 아래 명령문을 실행한다.

Page 73: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

- break; 문을 만나면 중단하고 도중에서 switch 문을 빠져 나온다.

- break; 문이 없다면 다음 case 문을 실행한다.

- default 문은 일치하는 조건이 없을 경우 실행한다.

예제를 입력하고 실행해보면 1 초 간격으로 LED 의 색이 예쁘게 바뀔

것이다. switch 문은 if 문에 비해 문장을 간결하고 알아보기 쉽게 해 주기 때문에

많이 사용된다.

연습문제를 통해 더욱 많은 경우를 익히자

논리 연산자를 사용하여 복잡핚 조건을 입력핚다

지금까지 예제에는 하나의 조건을 사용하였으나, if 문이나 while 문에서

( )안에는 조건식을 입력할 수 있다.

관계연산자 등가연산자 논리연산자

를 사용하여 입력한다. 이중에서 관계연산자나 등가 연산자는 2 개 값의

대소관계나 등가관계를 판정하는 것이다.

관계 연산자

연산자 설명 입력 예 의미

> 크다 if(a > 10) a가 10보다 크다면

>= 크거나 같다 if(a >= 10) a가 10보다 이상이면

< 작다 if(a < 10) a가 10 보다 작으면

<= 작거나 같다 if(a <= 10) A가 10 이하이면

Page 74: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

등가 연산자

연산자 설명 입력 예 의미

== 같다 if(a == 10) a가 10 이면

!= 같지 않다 if(a != 10) a가 10 이 아니라면

논리 연산자

연산자 설명 입력 예 의미

== 논리곱(그리고) if(a ==3 && b==2) a가 3 그리고 b가 2 라면

|| 논리합(또는) if(a ==3 || b==2) a가 3 또는 b가 2 라면

! 부정(~가 아니다) if(!(a == 3)) a가 3이 아니라면

로봇을 통해 논리연산자를 알아보자. 입을 벌리고 있다가 날개를 치면

닫는다. 이때 어느 쪽 날개를 쳐도 입을 닫게 하자.

List 논리 연산자 #include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

bill = 63;

while(1)

{

execute(1);

if(hit_right_wing || hit_left_wing) bill = 0;

Page 75: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

}

아무 팔이나 치세요! 여러분

Page 76: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 7 장 반복 구조의 로봇제어 프로그램

센싱-플랜-액션의 반복은 로봇 제어의 기본이다. 여기서 플랜, 즉 할 일을

결정하는 단계가 바로 여기서 공부하는 C프로그램이다.

좀더 자세히, 익숙해 지기!

WHILE 문을 이용핚 무핚 반복

전원을 켜면 행동을 무한히 반복하는 로봇을 만들고 싶다면 아래 예제를

공부하자. 로봇 프로그램에서 자주 쓰이는 무한 반복은 의도적으로 만들어야

한다. 즉, 원하는 사건이 일어나면 중단하는 방법이 반드시 준비되어 있어야

한다. 실수로 무한 반복을 한다면 불량 로봇이 될 것이다.

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

while(1)

{

bill = ++bill % 64;

execute(1);

}

}

무한 반복은 while 문의 반복 조건은 1 로 하면 된다. C 언어에서 1 은

논리적으로 항상 참이다. 코드는 무척 간단하지만 어린 펠리컨이 밥 달라고

입을 벌렸다 닫는 동작을 끊임없이 반복한다.

Page 77: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

FOR 문을 사용핚 프로그램

로봇 프로그램이 아닌 일반적인 계산 프로그램이라면 아마 가장 중요하고

많이 사용되는 명령문 일 것이다. while 문으로 공부한 예제를 for 문을 사용하여

다시 만들어 본다. while 문에 비해 좀더 간결해 졌다.

List for 문 #include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

int i;

for(i = 0; i < 64; i++)

{

bill = i;

execute(1);

}

}

for 문은 대개 반복 회수로 변수 i 를 자주 이용한다. 다음은 몇 가지 많이 볼

수 있는 유형이다.

for(i = 0; i < 10; i++) // 10회 반복

{

...

}

for(i = 0; i < n; i++) // 정수 값 n 만큼 반복

{

Page 78: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

...

}

for(i = 0; i < n; i = i + 2) // 짝수만 실행

{

...

}

2 중 FOR 문

for 문을 2 번 이상 사용하여, 반복 구조 속에 다시 반복 구조를 집어 넣을

수 있다.

List 2중 for 문

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

int i, j;

for(j = 0; j < 5; j++)

{

for(i = 0; i < 64; i++)

{

bill = i;

execute(1);

}

}

}

부리를 여는 동작을 5 회 반복 한다.

Page 79: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

FOR 문의 { } 생략

while 문과 같이 제어 문이 하나일 경우는 { }을 생략 할 수 있다.

List 1초간 정지

#include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

int i;

for(i = 0; i < 64; i++)

execute(1);

}

BREAK - 반복문장의 중도 종료

로봇은 무한 반복 상태에 있더라도 외부 신호에 의해 다음 동작을 행할 수

있어야 한다. 반복 상태를 빠져 나오는 break 문은 이런 용도로 사용한다.

List break 문의 사용법 #include "pelican.h"

main()

{

initialize(); // 로봇을 초기화 핚다

bill = 63;

while(1)

{

execute(1);

if(hit_right_wing || hit_left_wing) break;

}

Page 80: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

right_wing = 63;

left_wing = 63;

execute(150);

}

입을 벌리고 있는 로봇의 날개를 연필로 툭 치면(아무 날개나 치시오) 놀란

듯이 양쪽 날개를 같이 든다.

반복문의 종료는 while 문의 ( )내의 조건문을 강제로 바꾸면 빠져 나올 수도

있다. 어느 쪽을 선택할지는 프로그래머의 판단에 맡긴다.

Page 81: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 8 장 함수를 사용하여 제어하기

자주 사용하는 동작은 함수로 처리하자

함수의 필요성

로봇이 배우처럼 자기의 역할을 행동으로 연기하는 로봇 인형극을 생각해

보자. 웃거나 우는 연기는 자주 등장한다. 이때 미리 로봇이 해야 할 몇 가지

액션을 함수 단위로 만들어 두고 필요한 시점에 호출하면 프로그램의 크기가

작아지고 알기 쉽게 된다.

함수는 간단한 동작들의 모임으로 복잡하고 긴 동작을 프로그램 하도록

해준다. LED 를 켜거나, 팔을 움직이고, 전진, 후진 등을 미리 짧은 함수로

만들고 적절한 순서대로 호출하면 다양한 연기를 하는 로봇을 제작할 수 있다.

함수의 구성 요소

Page 82: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

메인 함수

한 프로그램에서 메인 함수는 하나만 정의 되어야 한다. 메인 함수는

컴퓨터가 이 프로그램을 시작하는 순간에 찾는 함수이므로 정해진 형식에 맞게

정의되어야 하며 다른 함수에서 직접 호출할 수는 없다

만약 메인 함수가 값을 반환 한다면 int 형으로 하도록 미리 약속 되어 있다.

int main(void)

{

// do something

return 0;

}

이 main() 함수는 종료 시 0 을 반환하므로 반환 값의 데이터 형은 정수, 즉

int 이다. 대부분의 컴퓨터에서 반환 값 0 은 처리가 정상적으로 종료되었음을

뜻한다. 비 정상적인 종료인 경우에는 1 이상의 값을 반환하는 것이 관례이다.

소 괄호 내의 void 는 외부에서 특별히 정보가 추가되지 않았다는 의미이다.

이때 void 는 생략해도 된다. 만약 외부에서 프로그램 실행 시 필요한 데이터가

있다면 그에 맞는 배열을 정의해야 하지만 이 사항은 나중에 다시 설명한다.

일반 함수의 정의 방법

일반적인 함수는 이름이 서로 다르다면 한 파일 내에 여러 개가 정의 될 수

있다. 일반 함수의 정의도 메인 함수와 유사하다. 다음 4 가지 경우로 나누어

진다.

반환 값 없음

void function(void)

{

. . .

}

인수 없음

Page 83: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

반환 값 없음

void function(int a)

{

. . .

}

인수 있음

반환 값 있음

int function(void)

{

. . .

}

인수 없음

반환 값 있음

int function(int a)

{

. . .

}

인수 있음

void 는 생략 할 수 있지만 가급적 위와 같은 형식으로 사용하기 한다. 실제

프로그램을 보면서 확인한다. 다음 프로그램은 사각형의 넓이를 구한다.

void area(int l)

{

int s = l * l;

printf("area = %d\n", s);

}

int main(void)

{

area(6);

return 0;

}

리턴 값이 있는 경우,

int area(int l)

{

return l * l;

}

int main(void)

{

printf("area = %d\n", area(6));

return 0;

}

Page 84: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

함수의 선얶 순서

C 컴파일러는 프로그램을 첫 행부터 차례로 처리한다. 이때, 컴파일러에

따라서

함수를 호출하는 시점에서, 그 함수의 사양이 판명되어 있어야 한다

라는 조건이 있다. 이전 예제 프로그램에서 main()보다 뒤에 area()함수가

위치한다면, area(6) 를 호출할 시점에 그 함수의 사양을 알 수 없다. 이런 이유로

main()함수를 마지막에 두었다. 함수가 여러 개 있을 때, 함수의 순서에 따라

에러가 나기도 하는데 이런 성가신 문제를 해결하기 위해 함수의 사양을 모아서

먼저 입력하는 방법을 권장한다.

int area(int); //함수 사양만 정의

int main(void)

{

printf("area = %d\n", area(6));

return 0;

}

int area(int l)

{

return l * l;

}

지금까지처럼 작은 프로그램에서는 함수의 위치관계를 따져 입력하고, 메인

함수를 마지막에 두는 방법으로 해결되지만, 정석은 함수 사양을 먼저 쓰는

스타일이다. 여기에는 다음과 같은 이유가 있다.

- 프로그램의 앞부분만 봐도 사용되는 함수의 정보를 알 수 있다

Page 85: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

- 함수가 많아지면 함수의 상호 호출관계가 복잡해 지고, 어떤 함수를

앞에 둘지 판단하기 어려운 경우가 생긴다.

- 복잡한 함수가 서로 상대를 호출하는 경우에는 입력이 불가능하다.

유용핚 로봇 제어 함수를 만들어 보자

함수의 기본을 익혔으면 실전에 사용해 보자. 로봇 제어에 유용한 함수를

입력하면서 공부해 본다.

로봇을 잠시 쉬게 하다 .

때로는 로봇이 움직이지 않고 외부 사건을 기다리는 경우가 있다. 주로

음성이 입력되면 주인의 명령을 음성인식을 한다. 이때 로봇이 이리저리

움직이면 곤란하므로 그 상태를 유지할 필요가 있다.

지금 상태를 그대로 일정 시간 동안 유지하는 함수를 만들어 보자.

Sleep()함수를 알고 있겠지만, 이 함수는 말 그대로 프로그램의 실행을

정지한다. 이 동안에 로봇은 아무런 작업을 할 수 없고 어떤 일이 일어나도

반응 할 수 없다. 따라서 로봇 제어에서는 이러한 함수는 사용하면 안 된다.

void wait(int frame)

{

int count = 0;

while(count++ < frame)

{

execute(1);

}

}

Page 86: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

void wait(int frame)함수는 인자로 쉬어야 하는 시간을 넘겨 받고 그

시간 동안 로봇의 자세를 유지한다. 인자로 넘어오는 정수는 0.02 초의 정수

배를 의미하므로 1 초 동안 정지할 경우에는 50 이 된다. 이 함수의 사용하여

로봇의 눈 모양을 2 초 마다 바꾸는 프로그램을 작성한다.

#include "pelican.h"

void wait(int frame)

{

int count = 0;

while(count++ < frame)

{

execute(1);

}

}

void main(void)

{

int n = 0;

initialize();

while(n++ < 6)

{

eye = n;

wait(100);

}

}

이미 우리는 wait(100)함수가 execute(100)과 동일하다는 것을 알고

있다.

LED 색상 바꾸기

Page 87: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이번에 만드는 color()함수는 LED 의 색상을 숫자로 제어 한다. 입력 인자 가

0 이면 끄기, 1 이면 적색, 2 이면 녹색, 3 은 주황색은 의미한다.

#include "pelican.h"

void color(int c)

{

led[0] = 0;

led[1] = 0;

if(c == 1) led[0] = 63; // RED

if(c == 2) led[1] = 63; // GREEN

if(c == 3) // ORANGE

{

led[0] = 63;

led[1] = 63;

}

}

void main(void)

{

int n = 0;

initialize();

while(1)

{

color(n++ % 4);

execute(50); // 1 초갂 유지핚다

}

}

Page 88: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 9 장 변수의 범위

변수를 선언하는 장소에 따라 변수의 유효 범위가 달라집니다.

로컬 변수와 글로벌 변수

함수 안쪽에 선언된 변수를 로컬변수라고 하고 바깥쪽에 선언된 변수를

글로벌 변수라고 한다. 로컬 변수가 유효한 범위는 변수를 선언한 함수

안쪽으로 한정된다. 즉, 다른 함수에서는 읽을 수도 쓸 수도 없다.

위 그림을 보면 함수를 주택이라고 비유하면 각 주택은 수납 가구를 가지고

있다. 실제로 서로 다른 가정의 가구 서랍 내에 어떤 내용이 저장되어 있는지

알 수 없다.

아래 프로그램에서 frame 이라는 이름의 변수가 서로 다른 함수 내에서

선언되어 있다. 둘 다 로컬 변수 이다. 첫째 변수는 로봇의 머리를 부드럽게

들어올리기 위한 변수이고 두 번째는 이 동작의 10 회 반복하기 위한 변수 이다.

Page 89: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

같은 이름이지만 실행 시 서로 다른 값을 가지고 동작한다. 이 프로그램은

예제일 뿐이고 한 소스파일 내에서 일부러 같은 이름을 사용할 필요는 없다.

#include "pelican.h"

void open()

{

int frame = 0; //로컬 변수

while(frame++ < 63)

{

bill = frame;

execute(1);

}

}

void main()

{

int frame = 0; //로컬 변수

initialize();

while(frame++ < 10) open();

}

변수를 함수의 바깥쪽에 선언하면 글로벌 변수가 된다. 글로벌 변수는

변수가 선언된 곳에 정의된 모든 함수 내에서 유효하다.

Page 90: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 그림은 주택 바깥에 설치된 사물함이다. 글로벌 변수는 다세대 주택에서

공동 사물함과 같은 역할을 한다. 누구나 공동으로 사용할 수 있지만 잘못하면

물건이 바뀌거나 분실의 염려가 있다.

아래 프로그램은 이전 프로그램과 같은 동작을 한다. 함수 외부에서 선언된

frame 변수는 글로벌 변수이다. 함수 내부에 글로벌 변수와 같은 이름의 변수가

있으면 어떻게 될까?

#include "pelican.h"

int frame = 0; //글로벌 변수

void open()

{

int frame = 0; //로컬 변수

while(frame++ < 63)

{

bill = frame;

execute(1);

}

}

Page 91: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

void main()

{

initialize();

while(frame++ < 10) open();

}

같은 이름의 글로벌 변수가 추가되었지만 함수 open()은 아무런 영향을 받지

않고 잘 동작한다. 로컬변수는 글로벌 변수보다 유효범위가 좁은 반면 함수

내에서는 우선 순위가 높다.

위의 예제를 통해 알아 보았듯이, 모든 변수를 글로벌로 선언하면 더 편리

할 것 같지만 프로그램이 복잡해지고 관리가 어렵게 된다. 특히 여러 곳에서

공동으로 사용하는 함수를 정의할 경우에는 글로벌 변수를 사용하면 안 된다.

꼭 필요한 경우가 아니라면 모든 변수는 가능한 로컬변수로 선언하는 편이

프로그램을 알기 쉽게 만들어 준다.

변수의 유효 범위를 “변수의 스코프(scope)” 라고 한다.

외부 변수

지금까지 필요한 변수를 모두 하나의 파일 내에서 정의 하였다. 실제로

프로그램이 커지면 하나의 파일로 관리 하기가 힘들어 진다. 따라서 현명한

프로그래머는 서로 연관이 있는 함수와 변수를 분리하여 서로 다른 파일에

나누어 관리한다. 로봇을 제어하는 bill, eye, led 등은 어디에서 왔을까? 하는

의문을 여기에서 풀어 보자.

이전에 작성한 프로그램을 3 개의 파일로 분리하여 본다.

(1) 파일: main.c

Page 92: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

void main()

{

initialize();

while(frame++ < 10) open();

}

(2) 파일: open.c

#include "pelican.h"

void open()

{

int frame = 0; //로컬 변수

while(frame++ < 63)

{

bill = frame;

execute(1);

}

}

(3) 파일: frame.c

int frame = 0;

이제 main.c 를 실행하면 다음과 같은 컴파일 에러가 나타난다.

Page 93: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

그 이유는 C 컴파일러는 파일 단위로 처리하기 때문에 다른 파일에 정의된

내용을 참조하지 않는다. 즉,

변수 frame 과 함수 open()은 어디에 선언된 거야?

하고 불평을 하는 것이다.

다음과 같이 외부 파일에서 선언되었다고 알려 주면 해결된다.

extern int frame;

extern open(void);

void main()

{

initialize();

while(frame++ < 10) open();

}

구체적으로 어느 파일에 선언되어 있다고 까지 알려 주지 않아도 된다.

이제 open.c 파일에 #include “pelican.h”가 필요한 이유를 알 것이다. Roboid

폴더에 있는 pelican.h 파일을 열어 보면 로봇 변수 bill 은 외부 파일에서 정의

된 것임을 알 수 있다. 이와 같이 대규모 프로그램은 여러 사람이 협동하여

개발하게 된다. 자신이 하는 일과 다른 사람이 하는 일을 서로 연결하기 위해

외부 변수는 매우 중요하다.

다른 사람이

작성핚 프로그램

자싞이 작성핚

프로그램

Page 94: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

문장 완성 기능과 변수의 범위

RoboidC 는 매우 편리한 문장 완성 기능을 가지고 있다. 긴 이름의 변수와

함수를 외우고, 또 틀리지 않게 입력하기는 힘들다. 이러한 경우 자동 문장

완성기능을 이용하면 매우 편리 한다. 이 자동 완성 기능 배우면서 변수의

스코프(scope)를 다시 한번 알아보자.

int global_a, global_b, global_d; //글로벌 변수

void local()

{

int local_a, local_b, local_c; //로컬 변수

}

void main()

{

int main_a, main_b, main_c; // 로컬 변수

}

문장 완성 기능을 호출하기 위해 아래 그림처럼 local()함수 내에 커서를

위치시키고 키보드의 콘트롤(control)키를 누른 상태에서 스페이스(space)키를

누른다. 입력 가능한 변수의 목록이 나타난다. 원하는 변수를 선택하면 자동으로

완성된 변수 이름이 입력된다. 선택은 마우스 또는 키보드 방향키로 하고 입력

결정은 더블 클릭 또는 엔터 키를 누른다.

Page 95: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

단순히 문장 완성기능을 호출하면 가장 우선순위가 높은 로컬 변수가

나타난다. 이번에는 “glo” 까지만 입력하고 문장완성기능을 호출해보자.

“glo”로 시작하는 변수 목록이 나타난다. 이 세 변수는 글로벌 변수 이므로

local()함수 내에서 유효하다. 같은 방법으로 main() 내에 있는 변수를 호출해보자.

“main_”을 입력하고 문장완성기능을 호출하면 “No Default Proposals”

다이아로그가 나타난다. 즉, main() 함수의 내부 변수는 local()함수에서는

유효하지 않음을 알 수 있다.

Page 96: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

main()함수로 옮겨서 같은 조작을 해보자. 예측한대로 글로벌 변수는

유효하지만 local() 함수의 내부 변수는 보이지 않는다.

자동완성기능은 변수뿐 아니라 호출 가능한 함수도 적용 가능하다. “loc”까지

입력한 후 호출하면 위에서 정의된 local 함수 이름이 나타난다. 이외에 외부에서

정의된 함수, 예를 들면, initialize()등도 첫 몇 자만 입력하면 자동완성이

가능하다.

Page 97: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

PART 3. Level Up C

Page 98: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 99: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 10 장 변수와 데이터 형

데이터 형과 저장 장소

지금까지 정수형 변수만 다루었지만 C 언어에는 많은 데이터 형이 있다.

지하철이나 역에서 볼 수 있는 코인 락커를 생각해 보자. 들어 갈 짐의 크기에

따라 여러 종류로 나누어져 있다. 만약 코인 락커가 하나의 크기로만 만들어져

있다면 큰 물건이 들어가지 못하거나, 쓸데없이 공간을 낭비하는 경우가 생기게

된다. 사용자는 자신의 짐에 맡는 크기의 락커를 선택하고 크기에 따른 비용을

지불 하게 된다. 당연히 큰 락커는 비싸고 작은 락커는 저렴하다.

다양한 데이터 형이 존재 하는 이유는 프로그램의 크기를 줄이고 기억

장치를 효율적으로 사용하기 위해서 이다. 이렇게 하면 컴퓨터는 같은 크기의

기억장치를 가지고 더 많은 일을 할 수 있게 된다.

Page 100: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

다음에 열거된 데이터 형중 char 형은 1 개의 단위 기억장소(대개 1 byte = 8

bits)를 점유하고, int 형은 컴퓨터 마다 다를 수 있지만 4 개의 단위 기억 장소를,

double 형은 8 개의 기억장소를 점유 한다. 자신이 선언 할 변수가 가질 수의

범위를 안다면 가장 알맞은 데이터 형을 고를 수 있을 것이다.

데이터 형 종류 표현 범위

Char

unsigned char

문자형

부호없는 문자형

-128 ~ 127

0 ~ 255

short int

unsigned short int

단정수형

부호없는 단정수

-32768 ~ 32767

0 ~ 65535 (2 bytes)

Int

unsigned int

정수형

부호없는 정수

-2147483648 ~ 2147483647

0 ~ 4294969295

long long int

unsigned long long

int

배정수

부호없는 배정수

64 비트, 8 바이트

float

단정도

부동소수점형

약 10 의 -38 승 ~ 10 의 38 승

(4 bytes)

double 배정도

부동소수점형

약 10 의 -308 승 ~ 10 의 308 승

(8 bytes)

float 는 double 보다 자리수가 작고 표현 오차가 크므로 연산 시 잘못된

결과를 종종 만들어 낸다. 가능한 double을 사용하기를 권장한다.

수치 데이터 형과 출력방법

지금까지 정수형을 출력하는 경우 “%d”만 사용했지만, 데이터 형에 따라

프린트 문을 사용하여 출력하는 방법이 달라진다.

Page 101: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

문자형는 부호와 관계없이 “%c”를 사용하고, 부동소수점형은 “%f”를

사용한다.

List 데이터 형에 따른 출력 방법

main()

{

char c = 'A';

short int i = 60000;

unsigned short int ui = 60000;

float f = 1.23;

double d = 3.1415;

printf("%c %d %d %d %f %f\n", c, c, i, ui, f, d);

printf("%d %x %#x %o %#o \n", ui, ui, ui, ui, ui);

}

실행 결과

A 65 -5536 60000 1.230000 3.141500

60000 ea60 0xea60 165140 0165140

정수형인 경우, 십진수 출력뿐 아니라 16 진수(%x)와 8 진수(%o) 형식으로

출력이 된다. “%#x”와 같이 “#”을 사용하면 16 진수 앞에 “0x”가 붙는다.

첫 번째 c 는 문자형으로 지정하여 „A‟가 출력되었지만, 두 번째 c 는

정수형으로 지정하여 65 가 출력 되도록 하였다. i 는 수의 범위를 벗어나므로

제대로 출력이 안되었지만 부호 없는 단정수로 정의된 ui 는 범위를 만족한다.

문자열 데이터 형과 출력방법

Page 102: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

문자열은 문자형 데이터의 집합이다. 위에서 살펴본 char 은 하나의 문자만

저장하지만 문자열은 문장 전체를 저장할 수 있다. 이를 위해 문자형 배열을

선언할 필요가 있다.

main()

{

char s[] = "Hello";

printf("%s", s);

}

[]안에 배열의 크기를 지정하지 않아도 자동으로 알맞은 크기로 만들어 진다.

PRINTF()문의 서식 지정

결과 값을 정렬하거나 이름의 길이를 맞추기 위한 방법을 알아본다.

List 서식 지정 출력 방법

main()

{

char s[] = "Hello";

unsigned short int ui = 60000;

float f = 1.23;

double d = 3.1415;

printf("%8s%6d%5.2f%8.4f", s, ui, f, d);

}

실행 결과

Hello 60000 1.23 3.1415

Page 103: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

처음 공백이 3 개 있는 이유는 “Hello”는 5 자이지만 서식지정은 8 자리이기

때문이다. 같은 이유로 다음에 공백이 하나인 이유는 5 자 숫자이지만 6 자리를

지정했기 때문이다. 1.23 은 4 자리 수이지만 “%5.2f”에 의하여 5 자리가

지정되고 소수점 이하 2 자리로 출력 되었다. (소수점도“.”도 한자리 에 포함된다)

Page 104: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 11 장 배열과 포인터를 위한 로봇 - 매트릭스

변수를 이해한 다음 관문은 변수의 집합인 배열이다. 같은 성격의 변수를

모아서 반복 연산이 가능하도록 고안된 배열은 매우 편리하고 C 언어에서는

매트릭스 로봇의 구조와 사양

WOW!

<배열 완전정복을 위해 탄생한 매트릭스 로봇>

유감스럽게 매트릭스 로봇은 춤추지 않는다. 그대신 여러분의 프로그래밍

실력을 마음껏 뽐낼 수 있다.

정면도 - 마이크 배면도 – 스위치

Page 105: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

LED 매트릭스

정면에는 적색 LED 64 개가 8 x 8 의 구조로 배치되어 있다. 각 LED 의

밝기는 0 에서 119 까지 120 단계로 제어가능하고 초당 50 회의 속도로

애니메이션을 표현할 수 있다.

스피커

후면에는 스피커가 장착되어 있다. 음질은 48Khz, 16 bit 의 CD 음질이지만

스피커의 직경이 작아 큰 소리를 내지 못한다.

마이크로폰

전면에서 볼 때 머리부분에서 눈동자처럼 보이는 부품이 마이크 이다.

음질은 8Khz, 16 Bits 이다. 휘파람 소리나 손뼉 소리 등을 검출한다.

3 개의 스위치

후면에서 볼 때 3 군데에 스위치가 배치되어 있다. 간단한 명령을 입력한다.

USB 커넥터

PC 와 연결하는 USB 커넥터는 측면에 위치한다. 매트릭스 로봇은 전원을

따로 필요하지 않고 대신 USB 케이블을 통하여 공급 받는다. 매트릭스 로봇은

표준 오디오 장치로 설계되어 있어 따로 드라이버 SW 를 설치하지 않아도

동작이 가능하다. 프로그램 공부를 하지 않을 때에는 일반 스피커나 마이크로

사용해도 좋다.

Page 106: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

로봇 변수

RoboidC 에서는 제어하려는 매트릭스 로봇의 상태를 변수로 미리 정의되어

있다. 다음 표는 Matrix 로봇을 제어하는 변수의 정의 테이블이다.

변수명 데이터 형 기능 값의 범위

matrix[64] unsigned

char LED 밝기를 제어 0 ~ 119

speaker[960] int 오디오 데이터를 재생 16 비트

microphone[160] int 마이크 입력 데이터 16 비트

key_top

key_left

key_right

int 스위치 상태 검출.

1 은 눌러진 상태

0 ~ 1

모든 변수는 소문자로 시작한다. 스피커와 마이크 값의 범위는 -32768 에서

+ 32767 사이이다.

로봇 제어 함수

로봇 헤더 파일에는 로봇을 제어하기 위해 호출하는 함수가 미리 정의 되어

있다. Matrix 로봇의 중요 함수는 다음 두 가지이다.

함수 명 기능

initialize() 로봇을 초기화하고 명령을 받을 준비를 한다.

execute(frame) 로봇에 명령을 전달하고, 일정시간 쉰다.

1 frame 은 20 msec.

Page 107: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

작업 공갂과 예제 프로그램들

이 장 이후 나오는 예제 프로그램들은 미리 만들어진 프로젝트 “matrix_c”를

열면 찾아볼 수 있다. 하지만 학습을 위해 여기 수록된 짧은 프로그램은 직접

입력하면서 확인하도록 노력한다.

Page 108: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 12 장 비트연산자와 수의 표현

컴퓨터의 모든 수의 기본은 이짂수이다. 이 장에서는 이짂수를 직접 다루어보고

그 형식을 이해핚다.

비트 연산자의 종류와 기능

비트 연산자는 비트 단위로 연산을 진행하는 연산자로, 피 연산자는 반드시

정수 이어야 한다. 일반적으로 C 언어에서 비트 연산자는 덜 중요하게 취급

받는다. 하지만 로봇과 같은 하드웨어를 직접 제어할 경우에는 무엇보다도

편리하고 알기 쉽다.

다음은 C 언어가 제공하는 네 개의 비트 연산자를 정리한 표이다.

연산자 연산자의 기능

& 비트 단위로 AND 연산을 한다.

| 비트 단위로 OR 연산을 한다.

비트 단위로 XOR 연산을 한다

~ 단항 연산자로 피 연산자의 모든 비트를 반전 시킨다.

그리고 비트 연산자의 부류에 속하는 시프트(shift) 연산자가 있다. 이 단항

연산자는 정수 데이터의 비트 열을 왼쪽 또는 오른쪽으로 한꺼번에 이동 시키는

연산자로 활용도가 높다.

연산자 연산자의 기능

<< 피 연산자의 비트 열을 왼쪽으로 이동 시킨다.

예) int k = n << 2; n 의 비트 열을 2 칸 왼쪽으로 이동하여 k

Page 109: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

에 대입, n 의 값은 변동없다.

>> 피 연산자의 비트 열을 오른쪽으로 이동 시킨다.

예) int k = n >> 2; n 의 비트 열을 2 칸 오른쪽으로 이동하여

k 에 대입, n 의 값은 변동없다.

위 표만 보고서는 비트 연산자의 사용법을 완벽히 이해하기는 쉽지 않다.

이제부터 표의 내용에 따라 매트릭스 로봇이 연산의 결과를 보여주면서 이해를

도와 준다.

복합 대입 연산자로 갂단히 표시

사칙 연산과 마찬가지로 비트 연산도 간단히 표시된다. 즉,

n = n >> 3; 은 n >>= 3; 으로 단축 표시된다.

n = n & 3; 은 n &= 3; 으로 단축 표시된다.

비트와 매트릭스 로봇

매트릭스 로봇의 전면에 위치한 LED 를 이용하여 이진 숫자를 표현 해보자.

LED 배열의 한 줄은 8 개의 소자로 이루어져 있다. 이 8 개의 소자를 char 형

정수에 대응 시킬 수 있다. char 형 수는 8 비트로 이루어져 있고 8 개의 LED 는

각 비트에 대응하도록 한다. 비트가 “1”이면 점등, “0”면 소등하는 예제를 다음과

같이 알아본다.

List: display.c 0-255 사이의 8비트 정수를 1씩 증가 하면서 표시 #include "matrix.h"

Page 110: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

void display(int row, int n)

{

int i;

for(i = 7; i >= 0; i--)

{

if(n & 1) matrix[8*row + i] = 119;

else matrix[8*row + i] = 0;

n >>= 1;

}

}

int main()

{

initialize();

unsigned char n = 0;

while(1)

{

display(0, n++);

execute(10);

}

}

함수 display()는 8 비트 정수 인자를 받아서 매트릭스 로봇의 첫 가로줄에

표시한다. 이 함수는 & 와 >> 비트연산자를 이용하여 만들어 졌으므로 비트

연산자를 이해 하면 자연스럽게 위 함수의 동작 원리가 이해 될 것이다.

이제 비트 연산을 하나하나 실행하면서 비트연산의 의미를 이해한다.

비트에 보다 익숙해 지기 위하여 이 장에서는 16 진법의 정수형 표시를

사용한다. 십진법 보다 16 진법을 비트의 위치를 쉽게 알 수 있다.

& 연산자: 비트 단위의 AND 연산자

0xd3 과 0x76 을 비트단위의 AND 연산을 하고 그 결과를 표시한다.

int main()

{

Page 111: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

initialize();

unsigned char n1 = 0xd3;

unsigned char n2 = 0x76;

while(1)

{

display(0, n1); display(2, n2);

display(4, n1 & n2);

execute(1);

}

}

| 연산자: 비트 단위의 OR 연산자

0xd3 과 0x76 을 비트단위의 OR 연산을 하고 그 결과를 표시한다.

int main()

{

initialize();

unsigned char n1 = 0xd3;

unsigned char n2 = 0x76;

while(1)

{

display(0, n1);

display(2, n2);

display(4, n1 | n2);

execute(1);

}

}

^ 연산자: 비트 단위의 XOR 연산자

0xd3 과 0x76 을 비트단위의 XOR 연산을 하고 그 결과를 표시한다.

Page 112: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

int main()

{

initialize();

unsigned char n1 = 0xd3;

unsigned char n2 = 0x76;

while(1)

{

display(0, n1);

display(2, n2);

display(4, n1 | n2);

execute(1);

}

}

~ 연산자 : 비트 단위의 NOT 연산자

0xd3 을 비트단위의 NOT 연산을 하고 그 결과를 표시한다.

int main()

{

initialize();

unsigned char n1 = 0xd3;

while(1)

{

display(0, n1);

display(2, ~n1);

execute(1);

}

}

>> 연산자 : 비트 쉬프트 연산자(SHIFT)

Page 113: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

0x76 을 1 자리 왼쪽으로 이동하는 비트 쉬프트 연산을 하고 그 결과를

표시한다.

int main()

{

initialize();

unsigned char n2 = 0x76;

while(1)

{

display(0, n2);

display(2, n2<<1);

execute(1);

}

}

LED 불빛 이동 하기

비트 쉬프트 연산자를 이용하면 LED 의 위치를 간단히 이동 할 수 있다.

int main()

{

initialize();

unsigned char n = 0x75;

while(1)

{

display(0, n);

n <<= 1;

execute(50);

}

}

이제는 display()함수의 동작이 이해 될 것으로 본다. 쉬프트 연산 시 좌로

한자리 이동은 원래 수에 2 를 곱한 결과와 동일함을 알 수 있다. 즉, 한번

Page 114: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

쉬프트 연산이 될 떄 마다, 2, 4, 8, 16 을 곱한 결과와 동일하다. 이 원리를

이용하면 2 의 배수를 곱하는 곱셈을 매우 빨리 실행할 수 있다.

SIGNED 정수형의 SHIFT 연산

정수형에는 부호가 있는 경우와 없는 경우, 두 종류가 있다. 부호가 없는

경우는 unsigned 라는 키 워드를 붙이고, 부호가 있는 경우에는 signed 를

붙이거나 대개 생략한다. 부호가 있는 경우와 없는 경우에 따른 쉬프트 연산의

동작을 알아본다.

부호 없는 정수에서 쉬프트 연산은 2 를 곱하거나 나누는 경우와

같다 .

부호가 없는 정수형의 경우는 오른쪽 쉬프트 연산은 2 를 곱하는 곱셈과

동일하며, 왼쪽으로 이동하는 쉬프트 연산은 2 로 나누는 나눗셈과 동일하다.

하지만 요즘 같은 성능 좋은 컴퓨터에서 조금 빨리 연산하기 위해 쉬프트

연산을 사용할 필요는 없다. PC 보다는 주로 자동화를 위한 소형 CPU 나 로봇

또는 모바일 기기에서 낮은 계산 능력을 보완하기 위해 사용하기도 한다.

부호 있는 정수에서 쉬프트 연산을 사용핚 삼각형 그리기

음수 -128 은 한 바이트로 표현하면 0x80 이다. 이진수에서 첫 비트는 음수를

나타내므로 1000 0000 의 비트 열로 표현된다. 이제 이 비트 열을 오른쪽 쉬프트

Page 115: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

연산자를 이용하여 한자리씩 이동하면서 나타내면 어떤 결과 가 나오는 지

알아보자.

int main()

{

initialize();

char n = -128, i;

for(i = 0; i < 8; i++)

{

display(i, n);

n >>= 1;

execute(25);

}

}

실행 결과를 보면, 부호 비트가 유지되면서 2 로 나눈 값이 출력됨을 알 수

있다. 이상과 같이 하드웨어를 직접 제어할 경우에는 비트연산자에 익숙해

지도록 노력해야 한다. 다른 연산자에 비해 이진 수와 같은 컴퓨터의 기본

지식을 알아야 하고 잘못 사용하는 경우도 많으므로 별도의 시간을 가지고

공부하기 바란다.

심화학습

@ 쉬프트 연산자를 사용하여 왼쪽으로 쉬프트핛 경우, 최하위 비트는 무엇으로

채워지는지 확인 핛 수 있는 프로그램을 작성핚다.

@ 쉬프트 연산자를 사용하여 오른쪽으로 쉬프트핛 경우, 최상위 비트는

무엇으로 채워지는지 확인 핛 수 있는 프로그램을 작성핚다. 부호가 있는

경우와 없는 경우로 나누어서 확인핚다.

Page 116: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

@ unsigned char n = 255; 를 이용하여 다음 삼각형을 그려라.

왜 부호 없는 정수형을 선언해야 하는 지 생각해 보라. char n = -1; 로

하면 어떤 결과가 나오는 지 프로그램을 수정하여 확인한다.

@ 비트 연산자를 사용하여 다음 삼각형 들을 그려라.

힌트: Or와 쉬프트 연산자 Not 연산자 사용

@ 다음 프로그램을 실행하여 다이아몬드 모양이 나오는 지 확인하고 비트

연산자의 동작을 알아본다.

int main()

{

initialize();

unsigned char n = 0x18, i;

for(i = 0; i < 4; i++)

Page 117: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

{

display(i, n);

int k = n << 1;

n = k | (n>>= 1);

execute(25);

}

for(i = 4; i < 8; i++)

{

display(i, n);

int k = n >> 1;

n = k & (n << 1);

execute(25);

}

}

Page 118: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 13 장 배열의 이해와 활용

배열은 C 얶어에서 가장 기본적이고 중요핚 데이터 구조이다. 로봇을 이용하여

배열을 이해핚다.

배열과 매트릭스 로봇

매트릭스 로봇의 전면에 위치한 LED 는 배열의 요소에 1 대 1 로 대응한다.

이제 이 매트릭스 로봇을 활용하여 배열을 확실히 이해하자.

1 차원 배열

로봇 변수 matrix 는 일 차원 배열이다. 다음 예제를 통해 일 차원 배열과

실제 LED 매트릭스와 연결을 확인한다.

List 순차적인 점등 #include "matrix.h"

main()

{

initialize();

int i = 0;

while(1)

{

matrix[i%64] = 119;

execute(5);

matrix[i++%64] = 0;

}

}

실행을 시켜보면 LED 불빛이 0.1 초 간격으로 좌로 이동하다가 마지막이

되면 아래칸으로 이동한 후 다시 좌로 이동한다.

Page 119: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

N 번째 LED 요소는 다음과 같이 구할 수 있다.

N = 8 * (행 – 1) + 열

즉, 3 행의 4 번째 LED 는 2 * 8 + 4 = 20 번째 이며, 이는 matrix[19]에

해당한다.

List 대각선 순차 점등

#include "matrix.h"

int led(int row, int column)

{

return row * 8 + column;

}

int main()

{

initialize();

Page 120: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

int i;

while(1)

{

for(i = 0; i < 8; i++)

{

int n = led(i, i);

matrix[n] = 119;

execute(10);

matrix[n] = 0;

}

}

}

led()함수는 행과 열을 인자로 받아 LED 의 위치를 정수로 되돌려 준다.

LED 에 하나하나 이름을 붙이지 않고 배열로 정의하는 이유가

뭔가요?

매트릭스 로봇은 64 개의 LED 요소를 가지고 있지. 64 개 이름을 다

붙이려면 힘들지 않겠어.

이름을 하나로 하면 어떤 좋은 점이 있나요?

이름이 서로 다르면 반복 문을 사용할 수 가 없어. 64 개의 이름을

하나씩 쓰면서 프로그램을 하다 보면 큰일이지. 동일한 프로그램을

의 반복해서 사용하면 타이핑 작업도 편하고 알아보기도 쉽지..

2 차원 배열

실제 컴퓨터에서 배열은 일 차원 밖에 없다. 하지만 매트릭스와 같은 2 차원

배열도 흔하므로 C 언어에서는 일 차원 이상의 배열도 선언 할 수 있다.

Page 121: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

C 언어는 다차원 배열을 어떻게 다루는지 역시 매트릭스 로봇을 통하여

알아보자.

List 2차원 배열 출력

#include "matrix.h"

int dia[3][3] = {{0,63,0},{63,0,63},{0,63,0}};

void copy(int n)

{

int i, j;

for(i = 0; i < 3; i++)

for(j = 0; j < 3; j++)

matrix[8*i + j + n] = dia[i][j];

}

int main()

{

initialize();

int i;

for(i = 0; i < 6; i++)

{

copy(i);

execute(50);

}

}

2 차원 배열 dia[][]는 3 x 3 의 다이아몬드 패턴을 가지고 있다. 함수 copy()는

이 3 x3 의 2 차원배열 데이터를 9 개의 일 차원 배열에다 복사한다. 인자 n 은

복사를 시작할 LED 의 위치이다. 다시 말하지만 컴퓨터의 기억장치는 한 줄로

만들어진 일 차원 배열이다. 2 차원배열을 정의하면 사진이나 패턴을 다루기

편하게 할 수 있다.

3 차원 배열과 동영상

Page 122: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

2 차원 배열인 이미지가 모인 동영상 데이터는 3 차원 배열로 표현 됩니다.

다음과 같이 이미지 한 장은 2 차원 배열이지만 이미지의 집합은 3 차원 배열이

된다.

List 3차원 배열 출력

#include "matrix.h"

main()

{

int P = 119, i, j, p;

int image[2][8][8] = {{

{0,0,0,0,0,0,0,0}, {0,P,P,0,0,0,0,0},

{P,P,P,0,0,0,P,0}, {0,0,P,P,P,0,0,P},

{0,0,P,P,P,P,P,0}, {0,0,P,P,P,P,P,0},

{0,P,0,0,0,0,P,0}, {P,0,0,0,0,0,0,P}},

{{0,P,P,0,0,0,P,0}, {P,P,P,0,0,0,0,P},

{0,0,P,P,P,0,0,P}, {0,0,P,P,P,P,P,0},

{0,0,P,P,P,P,P,0}, {0,0,0,P,0,0,P,0},

{0,0,0,0,P,P,0,0}, {0,0,0,P,0,0,0,0}}};

initialize();

while(1){

for(i = 0; i < 8; i++)

for(j = 0; j < 8; j++)

matrix[8*i+j] = image[0][i][j];

execute(10);

for(i = 0; i < 8; i++)

for(j = 0; j < 8; j++)

matrix[8*i+j] = image[1][i][j];

execute(10);

}

}

조금 프로그램이 길고 알기 힘들지만 실행하면 멋진 동영상이 나타난다.

그레이하운드가 사냥감을 쫓는 모습이 보일 것이다. 단 두 장의 2 차원 배열을

Page 123: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

가지고 이런 작품을 만들었다. 멋지지 않은가? 여러분도 동영상 작품에 도전해

보라.

배정도 정수의 홗용

정수는 4 바이트크기의 변수이다. 더 큰 숫자가 필요하다면 C 언어에는 8

바이트의 배정도 정수가 준비되어 있다. 배정도 정수는 64 비트이므로 한 변수에

한 장의 이미지를 담을 수 있을 정도로 크다. 만약 명암이 일정한 동영상을

제작한다면 배정도 정수를 이용하여 간단히 만들 수 있다.

배정도 정수는 long long int 로 선언하면 된다. 부호가 필요 없다면 unsigned

long long int 로 선언한다. 다음 예제는 이전의 3 차원 배열의 동영상을 2 개의

배정도 정수로 이용하여 다시 만든 것이다.

List 배정도 정수 배열 출력 #include "matrix.h"

void display(unsigned long long int img)

{

int i;

for(i = 63; i >= 0; i--)

{

if(img & 1) matrix[i] = 119;

else matrix[i] = 0;

Page 124: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

img >>= 1;

}

}

main()

{

initialize();

unsigned long long int images[2] =

{0x0060e2393e3e4281, 0x62e1393e3e120c10};

while(1)

{

display(images[0]);

execute(10);

display(images[1]);

execute(10);

}

}

삼차원 배열을 배정도 정수형 변수 2 개의 배열로 압축하였다. 덕분에

프로그램도 간결하고 알기 쉽게 되었다. 애니메이션에 관심이 있다면 이 장을

잘 복습하기 바란다. 사람들을 놀라게 하는 최근 영화의 3D CG(컴퓨터

그래픽)은 이러한 C 언어에서부터 출발 하였다.

심화 학습

@위쪽 스위치를 누르면 달리기를 멈추게 핚다. 어디에 프로그램을 추가하면

되는지 생각하고 완성핚다.

@좌측 스위치를 누르면 2 배 빨라지고, 우측 스위치를 누르면 2 배 느리게

달리게 핚다.

@ ‘A’, ‘B’, ‘C’ 문자를 1 초 갂격으로 표시하는 프로그램을 작성핚다.

Page 125: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

@부정 연산자(NOT) ~을 사용하여 화면을 반젂시킨다.

main()

{

initialize();

unsigned long long int images[2] =

{0x0060e2393e3e4281, 0x62e1393e3e120c10};

while(1)

{

display(images[0]);

execute(50);

display(~images[0]);

execute(50);

}

}

@다음 애니메이션을 감상하고 8 장짜리 애니메이션 작품에 도젂핚다.

int main()

{

initialize();

unsigned long long int images[] =

{0x18183c5a5a242466, 0x18183c5b58242466,

0x31323c585824e406, 0x34323c585824e406,

0x18183c5a5a242466, 0x18183cda1a242466,

0x8c4c3c1a1a242760, 0x4c4c3c1a1a242760};

int i;

while(1)

{

for(i = 0; i < 8; i++)

{

display(images[i]);

execute(10);

}

}

}

Page 126: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 14 장 포인터는 C 얶어 최고의 선물

이제 배열에 대해서는 자싞감이 생겼을 것이다. 이번에는 포인터에 도젂핚다.

C 얶어에서 어렵다는 포인터를 로봇이 이해 하도록 도와 줄 것이다.

포인터는 단순핚 정수형 변수에 불과하지만 C 얶어가 컴퓨터의 OS 를 비롯핚

수많은 응용 프로그램 개발에 일등 공싞이 되게 하였다. 변수와 변수 대입이

초기 컴퓨터 프로그램의 힘든 점을 들어 주었다면 포인터의 사용은 대규모

프로그램을 개발하게 하여 준다. C 얶어를 C 얶어답게 사용하려면 숨은 일꾼인

포인터를 칚구로 삼아야 핚다.

포인터는 포인터 형 변수다

배열을 이해 했다면 포인터를 이미 알고 있다고 볼 수 있다. 배열은

포인터의 사용법을 단순화 시킨 형태이다. 배열을 만들고, 대입하고 하는

과정에서 C 언어는 포인터를 사용되고 있다.

변수를 사용을 코인 락커에 비교한적이 있다. 변수에는 여러분이 부여한

이름이 붙는다. 다음에 이 변수를 사용 할 경우에 기억하기 쉽게 해 준다.

하지만 실제 변수의 값이 컴퓨터 어디에 저장되어 있는가? 사실 알 필요도 없다.

변수에 해당하는 주소는 C 언어가 관리 한다. 컴퓨터는 건망증이 없으므로 종료

시까지 절대 바뀌지 않는다. 당연히 고마운 일이지만 곤란한 점도 있다.

여러분이 이용하는 락커의 주인은 친절하게 각 보관 박스에 이름을 붙여

놓았다. 학생들은 비어 있는 락커에 가방을 넣고 박스에 붙은 이름을 기억

했다가 나중에 가방을 찾으려면 이름을 말해야 한다. 어쩌다 한번 이용한다면

Page 127: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

괜찮을 것이다. 하지만 매일 또는 하루에도 몇 번씩 보관한다면 매번 변하는

박스의 이름을 기억하기는 쉽지 않다.

학생들의 불평을 들은 친절한 락커 주인은 다음과 같이 불평을 해결한다.

락커 주인 백 - 1

자주 이용하는 단골 학생에게는 특별핚 보관 박스를 제공핚다. 이 박스에는

물건을 넣을 수는 없지만 본인이 저장핚 가방이 있는 박스의 번호를 적은

메모를 저장핛 수는 있다. 따라서 앞으로 단골 학생은 자싞의 이름만 말하면

된다.

이제 학생들은 가방이 든 박스 번호는 매일 외우고 다닐 필요가 없다.

이름만 말하면 주인은 특별 보관 박스에 든 메모지에 적힌 번호의 박스에서

가방을 찾으면 된다. 이전 보다 할 일이 한가지 더 늘어났지만 학생들의 찬사에

주인은 또 아이디어를 내었다.

락커 주인 백 – 2

학급 단위로 가방을 맟기는 경우에는 박스에 물건을 학번 순으로 보관하고

반장의 이름이 적힌 특별핚 보관 박스에 처음 학생의 박스 번호만 메모핚다.

가방을 핚꺼번에 찾을 경우는 반장의 이름과 학생수를 말하면 된다. 물롞

반장의 이름과 학생의 학번을 말하면 하나씩 찾을 수도 있다.

위 이야기는 배열은 공부한 사람은 무슨 의미인지 대부분 알 것이다.

Page 128: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

칚젃핚 락커 주인

그림에서 포인터 보관 박스에 들어가는 내용이 포인터, 즉 포인터 형 변수

이다. 포인터 형 변수는 크기가 일정한 4 byte 의 정수형 변수로 로봇 제어에

사용한 정수와 같다. 차이점은 변수 값 자체보다는 그 변수가 가리키는 번호에

보관된 내용에 관심이 있다는 점이다. 포인터 변수의 크기는 일정하지만

포인터가 가리키는 보관 박스의 크기는 데이터 형에 따라 달라진다.

실제 프로그램을 보면서 포인터의 사용법을 정확히 이해하자. 다음

프로그램을 실행 시키면 매트릭스 로봇의 2 번째 LED 가 버튼을 누르면 꺼지고

놓으면 켜진다. 지금까지 프로그램과 다른 모습에 놀라지 말고 차분히 내용을

알아보자.

List 포인터의 선언

#include "matrix.h"

main()

{

initialize();

int* button;

button = &key_top;

while(1)

Page 129: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

{

if(*button) *matrix = 0;

else *matrix = 119;

execute(1);

}

}

우선 포인터를 선언하기 전에 포인터가 가리킬 데이터의 크기를 먼저

알아야 한다. 데이터의 크기에 맞는 선언을 하고 나면 사용하기 전에 초기화를

한다. 포인터를 초기화 한다는 의미는 포인터가 가리킬 어떤 변수의 위치를

지정한다는 뜻이다.

int* button;

button = &key_top;

로봇 변수 key_top 은 정수형 변수이다. 따라서 이 변수를 가리킬 포인터의

크기는 정수형이 된다. 첫 줄의 의미는 button 변수의 크기가 아니라

button 포인터가 가리킬 변수(데이터)의 크기가 정수형이라는 의미이다. 대부분의

PC 는 32 비트 컴퓨터이다. 32 비트 컴퓨터에서는 모든 포인터 변수의 크기는 4

바이트이다. 따라서 포인터 변수의 크기는 따로 지정하지 할 필요가 없다. 이

점을 확실히 기억한다.

포인터가 정수형 변수라면 그냥 정수형 변수 선언을 하면 되지

않나요?

단순히 어떤 변수가 저장된 주소만 알기 위해서라면 정수 형

변수로 선언해도 돼.

main()

{

char c = 'A';

int pt = &c;

printf("%#x", pt); //출력 = 0x22ff57

Page 130: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

정수현 변수 pt는 „A‟가 저장된 주소 0x22ff57을 가지고

있지.

그럼 왜 포인터라는 새로운 변수형을 만들었나요?

컴퓨터에게 채울 데이터의 크기를 알려주기 위해서이지. 데이터의

크기를 모르면 자동으로 저장하거나 대입하는 일이 불가능해.

포인터가 없던 C 이전의 언어는 이러한 작업을 사람이 관리 했기

때문에 너무 힘들었지.

최근의 컴퓨터 언어는 포인터 없다고 하는 데요?

Java 와 같은 언어는 표면상으로는 포인터가 보이지 않지만

내용적으로는 포인터를 모르면 이해하기 힘들어. C 언어는 거의

모든 언어의 기본이니까 포인터에 익숙해 지도록 하자.

포인터 선언에서 다음 두 가지 방법이 많이 사용된다.

int* button;

이 선언의 해석은 “정수형 데이터를 가리키는 포인터 변수의 이름은 button”

이다.

int *button;

이 선언의 해석은 “포인터 변수 button 이 가리키는 장소에 저장된 변수는

정수형” 이다. 둘 다 같은 선언이지만 나중에 나오는 * 연산자와 혼동이

일어나지 않도록 반드시 처음 방법을 사용하도록 한다.

Page 131: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

주소 연산자 - &

포인터의 선언과 함께 포인터를 초기화한다. (초기화 되지 않은 포인터를

사용하면 무서운 일이 벌어진다. 그 자리에서 프로그램은 에러 창을 띄우고

정지한다) 이때 포인터가 가리킬 변수의 주소는 &(주소 연산자)를 사용하여

얻는다. 따라서 위 프로그램의 button 은 로봇 변수 key_top 을 가리키는 포인터가

된다.

갂접 참조 연산자 - *

곱셈의 연산자 *와 같지만 피 연산자가 하나뿐이다. 이 포인터 앞에 *를

붙이면, 그 포인터가 가리키는 장소의 데이터를 참조 한다. *button 이 의미하는

것은 실제로는 정수형 변수인 key_top 의 상태이다.

그냥 if 문에 key_top 변수를 사용해도 되지만 포인터를 설명하기 위해

일부러 프로그램 하였다. 포인터의 진정한 힘은 배열이나 복잡한 데이터를 다룰

경우이다.

나중에 다시 나오지만 배열의 첫 번째 데이터를 가리키는 포인터는 배열의

이름과 같다. 따라서 matrix[]와 같은 배열인 경우에는 *matrix 로 하면 배열의 첫

번째 데이터를 참조할 수 있다.

포인터에 좀더 익숙해 지기 위해 하나 더 알아보자.

List 포인터의 선언과 초기화

#include "matrix.h"

main()

{

initialize();

Page 132: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

int* top = &key_top;

int* left = &key_left;

int* right = &key_right;

while(1)

{

if(*top) matrix[1] = 0;

else matrix[1] = 119;

if(*left) matrix[10] = 0;

else matrix[10] = 119;

if(*right) matrix[8] = 0;

else matrix[8] = 119;

execute(1);

}

}

이 예제는 포인터를 선언하면서 동시에 초기화를 하는 방법이다. 선언 시

초기화 할 변수가 아직 결정되지 낳았을 경우에는 NULL 포인터로 초기화 한다.

널(NULL)포인터는 0 으로 초기화된 포인터를 뜻하는 데, 아직 사용할

준비가 되지 않았다고 컴퓨터에게 알리는 기능을 한다.

int* button = 0;

이제 위 프로그램을 실행하고 3 개의 버튼을 누르면 그 버튼에 해당하는

LED 가 꺼진다.

포인터는 변수이므로(4 바이트의 정수) 그 값을 변경시킬 수 있다.

프로그래머는 이 값을 잘 변경하면 프로그램을 간편히 작성할 수 있지만, 잘

못하면 프로그램을 망칠 수도 있다는 점을 명심하자. 매우 중요한 데이터가

보관된 위치를 포인터가 잘못 대입하면 컴퓨터가 중단되는 상황이 발생하게

된다. 강력하지만 사용에 주의해야 하는 포인터, 조심조심하고 확인 또 확인

하면서 사용해야 한다.

Page 133: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 15 장 포인터와 배열과 문자열은 같은 내용의 다른 표현

지금까지 포인터를 몰랐지만 배열은 자유롭게 선언하고 사용하였다. 실제로

배열과 포인터가 같다고 한다면 놀랄 것이다. 배열과 포인터, 문자열과 포인터는

매우 밀접한 관계가 있다. 이것을 알고 나면 C 언어의 많은 의문점이 풀릴

것이다.

다음 프로그램에서 배열의 이름은 사실은 포인터란 것을 확인한다..

List 배열의 이름은 포인터이다 main()

{

int a[] = {1, 2, 3};

int* p = a;

printf("%d", *p);

}

위 프로그램에서 포인터 p 는 배열이름 a 와 같음을 알 수 있다.

포인터 연산

수치형 변수는 사칙연산이 가능하다. 포인터도 정수형 변수이지만 더하기와

빼기 연산 만 가능하다. 이 연산기능을 이용하면 하나의 포인터를 이용하여

여러 곳의 변수를 참조할 수 있다.

List 배열의 이름은 포인터이다

main()

{

int a[] = {1, 2, 3};

int* p = a;

printf("%d %d %d", *p, *(p+1), *(p+2));

}

Page 134: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

실행 결과

1 2 3

배열의 요소를 순차적으로 참조하기 위해 포인터 변수 p 를 1 씩 증가하면

된다.

포인터와 배열

포인터와 배열의 이름이 동일한 변수임을 확인하였지만 다음 프로그램을

보면 배열의 이름을 실제 포인터처럼 연산에 사용해도 된다는 것을 알 수 있다.

List 배열의 이름은 실제로 포인터이다

main()

{

int a[] = {1, 2, 3};

printf("%d %d %d", *a, *(a+1), *(a+2));

}

실행 결과

1 2 3

로봇 변수 matrix 는 배열로 정의 되어 있다. 배열의 이름 matrix 는 또한

포인터이기도 하므로 아래와 같은 방식의 순차적인 LED 점등이 가능하다.

List 포인터를 사용한 순차적인 점등

Page 135: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

#include "matrix.h"

int main()

{

initialize();

int i = 0;

while(1)

{

i %= 64;

*(matrix + i) = 63;

execute_wait(0.2);

*(matrix + i++) = 0;

}

}

배열과 포인터의 관계에 대해 아직 혼란스러운 사람도 있기 때문에 다시

한번 정리를 한다.

포인터가 배열이라면 왜 배열을 또 만들었나요?

포인터로 배열의 요소를 참조 할 수는 있지만 배열의 크기는 알지

못하지. 포인터가 이전 언어의 어려운 점을 해결해 주었다면

배열은 포인터 사용의 어려운 점을 도와 준다. 배열은

프로그램에서 자주 등장하므로 사람들의 편의를 위해 컴퓨터가

자동으로 해 주는 일이 몇 가지 더 있지.

그럼 배열과 포인터는 완전히 동일하지는 않군요.

그렇지. 배열에는 배열의 크기 정보뿐 아니라 초기화 시 저장

장소를 자동으로 확보하는 등의 기능이 추가 되어 있자. 배열을

사용하지 않고 포인터 만으로 이 일을 하려면 직접 저장공간을

확보 해야 한다.

Page 136: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

그러면 배열 대신 꼭 포인터를 사용해야 할 이유가 있나요?

배열은 정적인 저장공간이라 한번 만들어 지면 변경이 불가능해.

만약 프로그램이 실행되는 도중에 데이터가 넘쳐나서 저장할

공간이 추가로 필요하게 되면 어떻게 될까? 배열을 아주 크게

미리 만들어 두면 되겠지만 큰 낭비가 되지. 이럴 때 배열보다는

포인터의 사용이 필요해.

SIZEOF() 연산자

피 연산자가 차지하는 저장공간의 크기를 바이트 수로 알려주는 연산자이다.

List 배열의 이름은 실제로 포인터이다

main()

{

int a[] = {1, 2, 3};

int* p = a;

printf("%d %d", sizeof(a), sizeof(p));

}

배열 a 의 경우에는 4 바이트 * 3 요소 이므로 전체 12 바이트가 되지만,

포인터 자체의 크기는 언제나 일정한 4 바이트 이다.

실행 결과

12 4

포인터와 문자열

Page 137: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

문자열은 배열의 일종으로 단지 다루는 데이터 형이 문자인 변수의

집합이다. 따라서 배열과 포인터의 밀접한 관계는 그대로 적용된다. 이점을

확인하고 나서 좀더 자세히 알아보자.

List 문자열을 배열이면서 포인터이다

main()

{

char s[] = "Hello Robots", i;

for(i = 0; i < sizeof(s); i++)

printf("%c, ", s[i]);

printf("\n");

for(i = 0; i < sizeof(s); i++)

printf("%c, ", *(s+i));

printf("\n");

}

문자형 배열 s 는 “Hello Robots”라는 문장을 저장한다. 배열 s 는 배열인

동시에 포인터 이므로 위와 같은 포인터 연산도 가능하다. sizeof()연산자는 13 을

돌려주는데 이는 문자열을 만드는 문자 수와 같다.

실행 결과

H, e, l, l, o, , R, o, b, o, t, s, ,

H, e, l, l, o, , R, o, b, o, t, s, ,

출력문의 마지막에 공백에는 0 이 들어 있다. 컴퓨터는 문자열의 마지막에

항상 0 을 더 붙인다. 문자열의 크기를 알아내는 sizeof()연산자는 문자 수를

카운트하다가 0 을 만나면 중지한다. printf()명령에서도 마찬가지로 0 을 만나면

출력을 중단한다. 문자열을 직접 만들고자 할 경우에는 마지막에 0 을 빠뜨리면

무서운 일이 일어난다. 얼마나 긴 문자열이 생길지 모르기 때문이다.

List 문자열을 직접 만들어 보자

Page 138: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

main()

{

char s[4];

s[0] = 'A';

s[1] = 'B';

s[2] = 'C';

s[3] = 0; // 또는 s[3] = '\0';

printf("%s ", s);

}

문자는 3 자이지만 0 을 마지막에 넣기 위해 문자형 배열의 크기를 4 로

한다.

실행 결과

ABC

포인터과 반복문

배열과 포인터는 반복 문을 편리하게 사용하기 위해 고안된 구조이다.

포인터와 좀더 친숙해지기 위해 매트릭스 로봇의 순차형 점등 프로그램을 다시

활용해 본다. 이번에는 불빛이 이동만 하는 것이 아니라 혜성처럼 꼬리를

끌면서 이동한다.

List 꼬리 끌면서 이동하는 불빛

#include "matrix.h"

void fade()

{

int j;

for(j = 0; j < 64; j++)

{

int k = *(matrix + j);

*(matrix + j) = k * 8 / 10;

Page 139: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

}

int main()

{

initialize();

int i;

while(1)

{

for(i = 0; i < 64; i++)

{

*(matrix + i) = 119;

fade();

execute(3);

}

}

}

내용상 차이점은 fade()함수가 추가된 점이다. 함수 fade()는 64 개 LED 의

현재 밝기를 80%로 줄이는 일을 한다. 한번 호출 시 마다 80%씩 어두워지므로

이전에 켜진 LED 는 0 에 가깝게 점점 어두워지고 최근에 켜진 LED 는 밝게

유지 된다.

포인터의 활용이 이것만이 아니지만, 우선 포인터의 개념과 배열과의

관계를 잘 이해 했다면 C 언어의 대부분을 정복했다고 할 수 있다.

심화 학습

@꼬리를 끄는 불빛을 배열을 사용하여 다시 작성하시오. 어느 쪽이 어떤

장점이 있는지 알아 보시오.

Page 140: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 16 장 데이터 관리는 구조체를 활용한다

상당히 낯선 이름인데, 과연 어떤 내용일까? 자세한 설명을 하기 전에

이전에 배운 내용들을 떠 올려 본다. 변수란 하나의 코인 락커에 대응하는

개념이고, 같은 종류의 코인 라커를 여러 개 묶어서 배열이라고 정의하였다.

이때, 배열이란 동일한 종류의 데이터를 한데 모은 것이다. 구조체는 배열과

같이 데이터의 집합이지만 다른 종류의 데이터를 모은 것이다. 즉, 배열보다 그

범위와 사용 방법이 확장 된 것이다.

로봇을 제어하려면 한 종류의 데이터만가지고 부족한 경우가 많다. 예를

들면, 주인의 이름은 문자열이지만 주인의 나이는 정수형이다. 주인과 친구들에

관련된 데이터를 한데 모아 처리할 때, 바로 구조체를 사용하는 것이다.

구조체의 선얶

우리의 친절한 락커 주인은 단체 학생뿐 아니라 이번에는 가족단위로

물품을 보관 할 수 있는 아이디어를 생각한다. 아이의 신발, 아빠의 양복 등

서로 크기가 다르고 수량도 다른 경우에, 쓸데없이 비싼 락커를 여러 개 빌리지

않고도 꼭 맞게 저장하는 방법이다.

친절한 락커 주인 - 1

가족용으로 저렴핚 코인 락커를 준비했습니다. 핚번에 여러 가지 물건을

정리핛 수 있도록 크기가 다른 박스 만들어짂 가족용 저장공갂입니다.

게다가 보관 박스의 크기도 가족 마다 서로 다르게 만들 수 있으니 많은

Page 141: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이용바랍니다.

다음날 락커 주인은 실망하게 된다. 좋은 아이디어이지만 사용법이 어려워

아무도 새로운 락커를 찾지 않는 것이다. 친절한 락커 주인은 다시 고심을 한다.

친절한 락커 주인 – 2

여러분이 직접 보관박스를 만들지 않아도 됩니다. 보관하실 물품의 목록을

주면 알아서 딱 맞는 보관 장소를 만들어 드립니다.

이제 사용자가 직접 박스를 만들지 않고 다음과 같이 2 단계로 물품을

보관하게 되자 정말 편리하다고 소문이 나게 된다. 친절한 락커 주인의

아이디어를 한번 맞추어 보자.

Page 142: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

구조체의 정의 (구조체 템플릿 선얶)

어떤 변수를 어떻게 구조체로 묶을 것인지를 컴퓨터에게 지시하는 과정이다.

다음은 한 반의 학생에 대한 정보를 구조체 템플릿 선언하는 프로그램이다.

struct student

{

int no;

char name[];

int age;

};

구조체 변수의 선얶

위와 같이 정의된 구조체를 실제로 사용하려면 이름을 가지는 구조체

변수를 선언해야 한다.

struct student

{

int no;

char name[];

int age;

};

struct student android;

다음과 같이 두 과정을 동시에 선언할 수 있다.

struct student

{

int no;

char name[];

int age;

} android;

Page 143: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

구조체 변수의 초기화

구조체변수의 초기화는 선언 시에 다음과 같이 한다.

struct student android = {1, "Android", 5};

구조체의 이름은 구조체를 대표하는 심볼이다. 만약 구조체의 멤버를

참조하거나 대입 연산 등을 하기 위해서는 요소를 지정하는 방법을 알아야 한다.

구조체 내부의 요소를 지정하기 위해 구조체 변수이름 다음에 “.” (피리어드)을

사용한다.

int main()

{

struct student

{

int no;

char name[10];

int age;

};

struct student android = {1, "Android", 5};

android.no = 3;

printf("%s %d\n", android.name, android.age);

}

문장 완성기능으로 구조체 멤버 찾기

구조체의 내부를 구성하는 요소의 이름을 잘 알지 못하면 다음과 같이

문장완성기능으로 알아보라.

Page 144: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

구조체 변수 android 친 다음에 점”.”을 찍고 Control + Space 키를 누르면

위와 같이 구조체 요소의 목록이 나타난다. 키보드 또는 마우스로 원하는

요소를 선택한다.

구조체의 홗용

로봇이 감정이 있다면 얼굴 표정으로 나타내려고 할 것이다. 구조체를

활용하여 다양한 로봇의 감정을 표현해 본다.

구조체의 정의 (구조체 템플릿 선얶)

로봇의 표정을 어떻게 구조체로 묶을 것이지 정의하기 위해 어떤 요소가

필요한지 생각한다. 우선 감정의 상태를 나타내는 감정이름이 필요하다.

다음으로 얼굴의 표정을 나타내는 이미지 데이터와 입술의 형태를 나타내는

Page 145: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이미지 데이터가 필요할 것이다. 이 세가지 서로 다른 유형의 데이터를 묶어서

구조체로 정의한다.

struct emotion

{

char name[10];

unsigned int eye;

unsigned int lip;

};

구조체 변수의 선얶과 초기화

실제로 정의된 구조체를 사용하려면 이름을 가지는 구조체 변수를 선언해야

한다.

struct emotion angry = {"Angry", 0x81422418,

0x003c4200};

struct emotion sad = {"Sad", 0x24429118,

0x00003c00};

struct emotion smile = {"Smile", 0x66991018,

0x00423c00};

이제 로봇의 감정을 출력하면서 매트릭스로봇의 LED 를 사용하여 표현하는

프로그램을 살펴본다.

List 구조체를 사용한 로봇의 감정 표현 #include "matrix.h"

struct emotion

{

char name[10];

unsigned int eye;

unsigned int lip;

Page 146: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

};

struct emotion angry = {"Angry", 0x81422400,

0x003c4200};

struct emotion sad = {"Sad", 0x24429118, 0x00003c00};

struct emotion smile = {"Smile", 0x66991018,

0x00423c00};

void display(unsigned int img, int n)

{

int i;

for(i = 31; i >= 0; i--)

{

if(img & 1) matrix[i+n] = 119;

else matrix[i+n] = 0;

img >>= 1;

}

}

int main()

{

initialize();

while(1)

{

display(angry.eye, 0);

display(angry.lip, 32);

execute(50);

display(sad.eye, 0);

display(sad.lip, 32);

execute(50);

display(smile.eye, 0);

display(smile.lip, 32);

execute(50);

}

}

함수 display()는 첫 번째 인자로 이미지 데이터가 넘어오고 두 번째 인자로

표시를 시작할 LED 의 위치 정보가 넘어온다. 이를 이용하면 다양한 조합의

얼굴과 입술의 모양을 표현할 수 있다.

Page 147: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

Angry Sad Smile

구조체의 대입 연산

구조체의 사용은 일반 변수와 크게 차이가 없다. 함수의 인자로 전달

가능하고, 반환도 가능하다. 뿐만 아니라 대입연산자를 사용하여 값을 바꿀 수

있다.

위 3 가지 감정 외에 sad 와 smile 을 합쳐 “슬프게 미소 짓는 표정”을

만들고 싶다면 구조체 변수 “sad_smile”을 정의하고 다음 같이 대입 연산을 한다.

struct emotion sad_smile;

sad_smile = sad;

sad_smile.lip = smile.lip;

구조체 변수끼리 대입 연산을 하면 전체 내용이 복사된다. 그리고 일부

멤버의 값도 서로 대입할 수 있다.

Sad_Smile

Page 148: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

구조체의 배열

일반적인 변수와 마찬가지로 구조체변수에 대해서도 배열을 선언할 수 있다.

이것을 구조체 배열이라 한다. 쉽게 이해 하겠지만 아래 그림과 같이 구조체의

집합이라고 생각 하면 된다.

구조체 배열의 선얶

위에서 다룬 예제를 구조체 배열을 사용하여 다시 프로그램 해 본다.

로봇의 감정 상태 3 개를 하나의 배열로 선언하고 초기화 한다.

struct emotion

{

char name[10];

unsigned int eye;

unsigned int lip;

};

struct emotion feelings[3] =

{{"Angry", 0x81422418, 0x003c4200},

{"Sad", 0x24429118, 0x00003c00},

{"Smile", 0x66991018, 0x00423c00}};

Page 149: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

구조체 배열의 사용하면 전체 프로그램을 짧고 알기 쉽게 해준다.

int main()

{

initialize();

int n = 0;

while(1)

{

printf("%s\n", feelings[n].name);

display(feelings[n].eye, 0);

display(feelings[n].lip, 32);

execute(50);

n = ++n % 3;

}

}

실행 결과

Angry

Sad

Smile

Angry

Sad

구조체와 포인터

변수의 포인터와 마찬가지로 구조체 변수를 가리키는 포인터도 있다.

기본적인 개념과 사용방법은 일반 변수에 대한 포인터와 동일하다. 구조체를

가리키는 포인터를 선언하는 요령은 다음과 같다.

struct emotion* sp = &angry;

Page 150: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 문장을 잘 살펴보기 바란다. 일반 변수의 포인터 선언과 별 차이가 없다.

struct emotion 는 unsigned int와 같은 변수의 형을 나타내는 수식어

이다. 단지 미리 지정된 int 정수형이 아니라 구조체를 정의 할 때 선언한

구조체 템플릿의 이름이 된다. 나머지 과정 역시 일반 변수의 포인터와 같다.

포인터 선언은 일반 변수와 같지만 구조체 포인터의 사용법은 변수의

포인터보다 좀 더 복잡하다. 특별히 포인터를 사용하여 구조체의 멤버를 지정

하는 경우에는 -> 를 사용한다.

printf("%s\n", sp->name);

printf("%s\n", (*sp).name);

포인터와 구분하기 위해 구조체 변수에서 멤버를 지정하는 경우에는 “.”을

사용한다. 두 방식을 비교하면 -> 을 사용하는 편이 간편하게 보인다.

구조체 배열과 포인터

배열의 포인터와 마찬가지로 구조체 배열에도 포인터를 사용할 수 있다.

기본적인 개념과 사용방법은 배열 대한 포인터와 동일하다. 구조체 배열을

가리키는 포인터를 선언하는 요령은 다음과 같다.

struct emotion* feel = feelings;

위 문장을 잘 살펴보기 바란다. 일반 배열의 포인터 선언과 별 차이가 없다.

즉 배열의 이름은 포인터 이므로 이 경우에는 주소 연산자 &를 사용할 필요가

없다. 포인터를 사용하면 위 예제 프로그램을 다음과 같이 바꾸어 쓸 수 있다.

int main()

{

Page 151: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

struct emotion* feel = feelings;

initialize();

int n = 0;

while(1)

{

printf("%s\n", (feel+n)->name);

display((feel+n)->eye, 0);

display((feel+n)->lip, 32);

execute(50);

n = ++n % 3;

}

}

심화 학습

@구조체를 사용하여 8 장짜리 애니메이션을 만들어 본다.

@구조체를 사용하여 칚구들의 이름, 나이, 주소, 학교에 대핚 목록을 만들고

출력핚다.

Page 152: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 17 장 표준 라이브러리 함수

C 언어에서는 함수는 처음부터 준비된 함수와 스스로 만든 함수가 있다.

특히 C 언어 규격으로 만들어져 어떤 PC 에서도 잘 동작하는 함수를 표준

라이브러리 함수라고 한다. 표준 라이브러리 함수만 잘 사용해도 충분하게

프로그램을 개발할 수 있다. 이장에서는 로봇 제어에 필요한 표준 함수에 대해

알아본다.

표준 함수의 호출방법을 이해하자

표준 함수를 소개 하기 전에 먼저 표준 함수의 호출방식을 알아야 한다.

이전까지 우리가 사용한 함수는 “값에 의한 호출” 방식이었다. 즉, 함수를

호출하는 쪽에서는 필요한 데이터를 함수에 넘겨줄 때의 값을 복사하여

전달하였다. 정말인지 확인해보자.

왼손 잡이 펠리컨 로봇이 있다. 이 로봇 만 이름을 부르면 왼손을 들지만

대부분의 펠리컨은 오른 손을 든다. 만약 오른손 잡이용 로봇 프로그램에 좌우

손을 바꾸는 함수를 추가 하면 간단히 해결될까? 대답은 “간단하지 않다” 이다.

List 5초간 오른팔 들기

#include "pelican.h"

main()

{

initialize();

right_wing = 63;

left_wing = 0;

execute(250);

}

Page 153: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 프로그램을 실행 시키면 약 5 초간 오른손을 든다. 이제 왼손으로

바꾸기 위해 다음과 같이 함수를 추가한다.

List 값에 의한 함수 호출

#include "pelican.h"

void wing(int lwing, int rwing)

{

int w = lwing;

lwing = rwing;

rwing = w;

}

main()

{

initialize();

right_wing = 63;

wing(left_wing, right_wing);

execute(250);

}

위 프로그램을 실행하면 에러가 없는데도 여전히 로봇은 오른팔을 든다.

컴퓨터는 내부적으로 변수의 값만 복사하여 전달하므로, 원래 변수에 대해서는

wing()함수에서는 알 수 없다. 만약 좌우를 바꾸고 싶다면 위 함수는 잘못된

것이다. 이때에는 반드시 원래 변수의 주소를 전달하는 방식, 즉, “참조에 의한

함수 호출”을 사용해야 한다.

List 참조에 의한 함수 호출

#include "pelican.h"

void wing(int* lwing, int* rwing)

{

int w = *lwing;

*lwing = *rwing;

*rwing = w;

}

Page 154: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

main()

{

initialize();

right_wing = 63;

wing(&left_wing, &right_wing);

execute(250);

}

위 두 방식은 서로 장단점이 있다. 값에 의한 호출은 간단하고 안전하다.

함수에서는 호출 상대방에 대해 알 필요 없이 계산 값만 넘겨 주면 된다.

참조에 의한 호출은 직접 상대방의 데이터를 변경시키므로 위험하기도 하지만

위 예제와 같은 경우에는 반드시 필요하다. 표준 함수에서는 참조에 의한

호출이 많이 나타나므로 이 차이점을 꼭 이해하고 사용해야 한다.

난수 만들기 – RANDOM())

표준 함수의 하나인 rand()는 0 ~ 32767 사이의 값을 만들어 낸다.

List 난수의 사용법

#include "matrix.h"

int main()

{

initialize();

while(1)

{

matrix[rand()%64] = rand()%120;

execute(0);

}

}

Page 155: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

간단한 프로그램이지만 불빛이 무작위로 바뀐다. 난수의 값이 0-

32767 사이가 아니라면 어떻게 다른 난수를 만들 수 있을까? 일단 만들어진

난수를 다음과 같이 원하는 범위의 값으로 나머지 연산을 하면 된다.

matrix[rand()%64] = rand()%120;

난수의 나머지도 난수이므로 예제와 같이 무작위로 불빛이 바뀜을 알 수

있다.

execute(0);

위 함수에서 인자가 0 인 경우에는 컴퓨터의 최대 속도로 불빛이 바뀌게

된다. 이 프로그램은 컴퓨터의 계산 능력을 최대로 사용하므로 다른 프로그램이

정지하게 되거나 마우스, 키보드의 반응이 느려지게 된다. 인자가 0 인 경우는

이론적으로는 사용하면 안 된다. 1 부터 사용한다.

아래 예제는 불꽃놀이를 흉내 낸 것이다. 밝아졌다 서서히 어두워지는 예쁜

불꽃놀이 프로그램의 동작을 분석 해 보자.

List 난수를 사용한 불꽃놀이

#include "matrix.h"

int main()

{

initialize();

int i;

while(1)

{

for(i = 0; i < 64; i++)

{

int k = *(matrix + i);

*(matrix + i) = k * 95 / 100;

}

*(matrix + rand()%64) = 119;

execute(1);

Page 156: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

}

}

키보드 입력함수 – SCANF()

사용자가 키보드를 통해 입력한 내용을 변수에 저장하는 매우 중요한 표준

함수이다. 사용법은 printf()함수와 반대라고 보면 된다.

List 정수의 입력 main()

{

int a;

scanf("%d", &a);

printf("%d\n", a);

}

실행 결과

1234

1234

scanf()함수에서 일반적인 수치(정수)를 입력할 때는 %d 라는 변환 형식을

지정한다. 이것은 printf()와 동일하다.

scanf() 변환 사양 의미

%d 10 진수를 입력한다

%lf 부동 소수점(double)을 입력한다.

%c 문자를 입력한다.

%s 문자열을 입력한다.

Page 157: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

변수의 지정

위 프로그램을 보면 변수 a 에 저장하고 있다. 변수 a 앞에 반드시 주소

연산자 &를 붙이는 이유는 무엇일까? 그것은 표준함수 scanf()의 호출방법이

“참조에 의한 호출”이기 때문이다. 첫 페이지로 돌아가 함수의 호출을 자세히

보면 이해가 갈 것이다. 주소를 지정하지 않고 변수 a 를 지정하면 키보드에서

넘어온 값을 되돌려줄 방법이 없다.

키보드로 2 개의 정수를 입력하면 그 첫째 값에 해당하는 위치의 LED 를

켜는 프로그램을 만들어 보자. 입력 값의 범위는 0-63 까지 이다. 둘째 값은

밝기를 나타낸다. 입력 값의 범위는 0-119 이다

List 정수에 해당하는 LED 켜기

#include "matrix.h"

main()

{

initialize();

int a, b;

while(1)

{

printf("두 개의 정수를 입력하시오: ");

scanf("%d %d", &a, &b);

matrix[a] = b;

execute(100);

}

}

원하는 LED 를 직접 제어하는 입력 예이다.

실행 결과

두 개의 정수를 입력하시오: 1 100

두 개의 정수를 입력하시오: 3 45

Page 158: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

두 개의 정수를 입력하시오: 5 119

두 개의 정수를 입력하시오:

OS 의 커맨드를 실행하자

컴퓨터는 프로그램 리스트를 보거나 실행시킬 수 있는 표준함수 system()을

가지고 있다. 예를 들면,

DIR 은 폴더내의 파일을 표시

COPY 파일을 복사한다.

이런 명령어를 C 언어에서 바로 실행한다면 편리할 것이다. 예제는

matrix 로봇의 key_top 을 클릭하면 Windows 에 내장된 계산기(calc.exe)

프로그램을 실행한다.

List NOTEPAD.EXE 실행하기 #include "matrix.h"

main()

{

initialize();

while(1)

{

execute(1);

if(key_top) system("calc.exe");

}

}

Page 159: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

수학 함수를 사용하기

C 언어는 일반적으로 알려진 컴퓨터 언어 중에서 가장 계산능력이 뛰어나다.

또한 고등 수학에 사용되는 여러 수학 함수가 준비되어 있다. 대표적인 수학

함수의 예로 사인 값을 계산하는 sin()함수를 알아보자. 다음은 0 에서 90 도

사이의 사인 값을 소수점 아래 50 자리까지 계산하는 프로그램이다.

List 정수의 입력 #include <math.h>

#include "matrix.h"

main()

{

int i;

double d;

for(i = 0; i <= 90; i += 10)

{

d = sin(i * M_PI / 180.0);

printf("%2d %1.50f\n", i, d);

}

}

실행 결과

0 0.00000000000000000000000000000000000000000000000000

10 0.17364817766693033118663436198403360322117805480957

20 0.34202014332566871290808308003761339932680130004883

30 0.49999999999999994448884876874217297881841659545898

40 0.64278760968653925189641995530109852552413940429688

50 0.76604444311897801345168090847437269985675811767578

60 0.86602540378443859658830206171842291951179504394531

70 0.93969262078590831688273965482949279248714447021484

80 0.98480775301220802031565426659653894603252410888672

90 1.00000000000000000000000000000000000000000000000000

Page 160: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

수학함수는 사용하기 전에 #include <math.h> 문장을 빼먹지 말기

바란다. 무리수 파이는 수학에서 매우 중요한 상수이므로 M_PI로 이미

정의되어 있다. 다음은 이미 정의되어 있는 중요한 수학 상수들이다.

#define M_E 2.7182818284590452354

#define M_LOG2E 1.4426950408889634074

#define M_LOG10E 0.43429448190325182765

#define M_LN2 0.69314718055994530942

#define M_LN10 2.30258509299404568402

#define M_PI 3.14159265358979323846

#define M_PI_2 1.57079632679489661923

#define M_PI_4 0.78539816339744830962

#define M_1_PI 0.31830988618379067154

#define M_2_PI 0.63661977236758134308

#define M_2_SQRTPI 1.12837916709551257390

#define M_SQRT2 1.41421356237309504880

#define M_SQRT1_2 0.70710678118654752440

수학 함수의 호출법

수학 함수는 기본적으로 인수도 double 형, 반환 값도 double 을 사용한다.

삼각함수 sin(), cos(), tan()함수등, 각도를 처리하는 함수는 라디안 값을 기본으로

사용한다. 따라서 각도를 라디안으로 변환하는 과정이 필요하다.

sin(deg); 가 아니고 sin(deg * M_PI / 180.0); 으로 해야 한다. 즉 1 라디안은 약

57.3 도이다.

삼각함수는 로봇 공학에서 많이 사용된다. 특히, 다 관절 로봇을 제어하기

위해 필수적으로 사용되는 함수이므로 익숙하게 사용하도록 노력한다.

대표적인 수학 함수

대표적인 수학함수를 정리한다.

Page 161: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

함수 사용법

sin(x) 사인 값, x 는 라디안

cos(x) 코사인 값, x 는 라디안

tan(x) 탄젠트 값, x 는 라디안

pow(x,y) 거듭 제곱 값, x 의 y 승 계산

log(x) 자연 로그 값

log10(x) 상용 로그 값

sqrt(x) 제곱근 값

abs(x) x 의 절대값, x 는 정수

fabs(x) x 의 절대값, x 는 실수

exp(x) e 의 지수

심화 학습

@scanf()의 입력 값을 문자, 문자열, 부동소수점등으로 바꾸어 입력하고

printf()문을 사용하여 출력하라.

@표에 있는 대표적인 수학함수를 하나씩 선택하고 그 결과값을 출력하는

프로그램을 작성핚다.

Page 162: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 163: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

PART 4. C Projects

Page 164: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 165: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 18 장 노래하며 춤추는 펠리컨

음악 파일을 재생하기

다음과 같은 펠리컨 로봇에게 노래를 부르게 하는 간단한 프로그램을

살펴보자.

List 음악 파일 재생 #include "pelican.h"

int main()

{

initialize();

FILE* file = fopen("alphabet.wav", "rb");

while(1)

{

fread(speaker, 2, 960, file);

execute(1);

}

}

간단한 프로그램이지만 실행 시키면 알파벳의 노래가 재생된다. 로봇

제어에서는 오디오나 이미지 같은 멀티미디어 파일을 다루는 경우가 많다.

이러한 파일은 텍스트가 아닌 이진 데이터를 저장하고 있다. 이진 데이터

파일을 읽고 재생하는 방법을 순서에 따라 알아 보자.

오디오 데이터 파일 열기

우선 데이터를 읽거나 쓰기 위해 원하는 파일을 열어야 한다. 이때, 파일의

열기 모드 지정해야 한다. fopen()함수는 지정된 파일을 찾아서 읽거나 쓸 준비를

한다. 처음 인자는 파일의 이름, 두 번째는 인자는 열기 모드이다. 이진

Page 166: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

데이터를 읽기를 하는 경우에는 “rb”를 사용한다. “r”은 read 모드, “b”는

이진데이터 모드를 뜻한다.

만약 지정한 파일이 없거나 파일에 문제가 있어 제대로 열리지 않으면

fopen()함수는 0 을 반환한다. 0 이 반환되면 더 이상 프로그램을 진행할 수

없으므로 컴퓨터는 에러 창을 열고 경고를 하게 된다. 하지만 다음과 같이 에러

처리를 하고 스스로 종료하는 것이 바람직하다.

FILE* file = fopen("alphabet.wav", "rb");

if(file == 0)

{

printf("File Error!");

return -1;

}

오디오 파일의 경로와 이름

위 예제의 오디오파일은 이 프로그램의 실행 파일과 같은 폴더에 위치한다.

만약 실행 파일과 같은 폴더가 아니라면 절대 경로를 지정하거나 상대경로를

지정해야 한다.

오디오 파일이 C:드라이브의 “Roboid”폴더에 있다면

FILE* file = fopen("c:/Roboid/alphabet.wav", "rb");

오디오 파일이 실행 파일 아래의 “Audio”폴더에 있다면,

FILE* file = fopen("Audio/alphabet.wav", "rb");

Page 167: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이짂 데이터 읽어 들이기

오디오 파일이 성공적으로 열렸다면 이진 데이터를 다음과 같이 읽을 수

있다.

*.wav 파일은 오디오의 음질과 음원 수에 따라 여러 가지 포맷으로 저장된다.

기존적으로 16 bit 인 경우에는 2 바이트씩, 8 bit 인 경우에는 1 바이트씩 읽어

들이면 되고, 스테레오인 경우는 좌와 우 채널이 번갈아 저장되어 있다. 또한

음질에 따라 초당 데이터의 수가 8K, 16 K, 32K, 48K 등이 있다. 모든 포맷을 다

설명하지 못하므로, 로봇용으로 유용한 포맷을 대상으로 소개한다.

예제의 “Alphabet.wav” 오디오 파일은 48Khz 음질의 16 bits 데이터 이다.

로봇 변수 “speaker”는 2 바이트크기의 배열로 48Khz 의 오디오 파일을 재생한다.

따라서, 오디오 데이터 읽기 함수 fread()는 다음과 같이 사용한다.

fread(speaker, 2, 960, file);

첫째 인자는 오디오 데이터를 저장할 배열, 두 번째는 배열요소의 크기,

셋째는 한번에 읽어 들일 데이터의 수, 넷째는 대상 파일이다.

오디오 데이터를 가공하거나 변환하는 방법은 이 책에서 설명하기에는

적합하지 않으므로 관심이 있다면 직접 자료를 구하여 보길 바란다. 예제는 48K,

16bits 의 오디오 데이터를 대상으로 만들어 져 있다. 포맷이 맞지 않거나

MP3 같은 형식이 다른 경우에는 부록에 설명된 오디오 변환 프로그램을

활용하여 48K, 16 bits 로 바꾼 후에 재생하기를 바란다.

fread()함수는 읽어 들인 데이터의 개수를 반환한다. 파일을 끝까지 다 읽어

들인 후는 0 이 된다. 다은 코드는 재생이 종료되는 시점을 알아 내고 파일을

Page 168: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

닫는 동작을 보여 준다. 일부러 파일을 닫지 않아도 프로그램이 종료되면

자동으로 닫히지만 되도록 사용이 끝나면 닫는 습관을 키우자.

이상과 같이 에러처리 및 파일 닫기 동작을 추가한 오디오 재생 프로그램은

다음과 같다. 이 책에서는 중요부분을 잘 설명하기 위해 전체 프로그램의

길이를 되도록 짧게 하려고 노력 하였지만, 에러처리 등은 실제로 빠뜨리면 안

되는 매우 중요한 부분이다.

List 음악 파일 재생

#include "pelican.h"

int main()

{

initialize();

FILE* file = fopen("alphabet.wav", "rb");

if(file == 0)

{

printf("File Error!");

return -1;

}

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

execute(1);

}

fclose(file);

}

오디오 데이터에 맞추어 부리를 움직인다 .

로봇이 오디오만 재생한다면 수동적인 MP3 플레이어나 다름없다. 로봇은

민첩한 동작과 생생한 반응이 중요하다.

Page 169: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

오디오 데이터에 맞추어 노래하는 펠리컨을 생각해 보자. 소리 데이터가

커지면 부리를 더 벌리고 소리가 작으면 부리를 닫는다. 오디오 데이터는

파형이므로 양수와 음수가 번갈아 나온다. 이때 양수 값만 더해 보면 소리의

세기를 짐작할 수 있다.

List 음악 재생하면서 부리 움직이기 #include "pelican.h"

int main()

{

initialize();

FILE* file = fopen("Alphabet.wav", "rb");

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

bill = power / 100000;

execute(1);

}

fclose(file);

}

프로그램이 조금 길어 졌지만 추가된 부분만 살펴 보자.

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

bill = power / 100000;

Page 170: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

for 반복 문에서 양수의 오디오 데이터를 더한다. 부리의 움직임은

0~63 이므로 이 범위에 맞추어 줄이기 위해 이 값을 100,000 으로 나누고 부리에

대입한다.

내용을 모르는 오디오 데이터에 맞추어 노래를 부르기는 쉽지 않다. 이

예제 역시 정확한 립싱크는 아니고 흉내내기에 불과하지만 로봇이 노래 부르는

원리는 알 수 있을 것이다.

오디오 데이터에 맞추어 춤을 춘다.

날개를 움직여서 춤을 춘다면 많은 사람의 시선을 끌 것이다. 춤을 추려면

정확한 박자가 중요하다. 박자를 알아내려면 어떻게 할까요? 일단 3 박자인지

4 박자인지 악보를 보고 알아낸다. 다음은 연주 시간을 측정하여 템포, 즉

빠르기를 알아낸다.

List 오디오 재생, 부리 움직이기, 날개로 장단 맞추기

#include "pelican.h"

int main()

{

int beat = 0;

initialize();

FILE* file = fopen("Alphabet.wav", "rb");

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

Page 171: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

bill = power / 100000;

beat++;

if(beat%23 == 0) left_wing = 63;

else left_wing = 0;

if(beat%46 == 0) right_wing = 63;

else right_wing = 0;

execute(1);

}

fclose(file);

}

이 음악은 분당 약 120 박자이다. 두 번 걸러 한번은 오른쪽 날개를 같이

들어 올린다.

이로써 간단하나마 노래하고 춤추는 펠리컨이 완성 되었다. 다른 노래에도

같은 과정을 적용하여 여러분만의 다양한 C 프로그램을 개발해 보기 바란다.

심화학습

@같은 프로그램으로 16Khz 샘플링의 오디오파일을 재생하는 하면 소리가

어떻게 변화 되는 지 확인하시오.

@16Khz 샘플링의 오디오파일을 재생하는 방법을 프로그램 하시오. 320 개의

배열을 준비하고 speaker 배열로 복사하는 프로그램을 완성하시오.

@48Khz 의 스테레오 오디오 파일은 4 바이트 단위로 읽어 들인 후 왼쪽

채널의 데이터만 사용하면 된다. 1920 개의 배열을 준비하고 프로그램을

완성하시오.

Page 172: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

@8bit 데이터는 한 바이트씩 읽어 들인 후 256 을 곱하여 16bit 데이터로

만드시오. 480 개의 배열을 준비하고 프로그램을 완성하시오.

@파일의 이름을 인자로 넘기면 립싱크를 수행하는 lip_sync() 함수를

만드시오.

void lip_sync(char* f)

{

FILE* file = fopen(f, "rb");

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

bill = power / 150000;

execute(1);

}

fclose(file);

}

Page 173: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 19 장 로봇 메트로놈

소리 만들기

이번에는 파일에 미리 저장된 소리가 아니라 실시간으로 소리를 만들어

내는 방법을 알아보자.

List 소리 만들기 #include "pelican.h"

#define MAX 35767

void mute()

{

int i;

for(i = 0; i < 960; i++)

speaker[i] = 0;

}

void tone(int hz)

{

int i, j, n = 48000/hz;

mute();

for(i = 0; i < 960/n; i++)

for(j = 0; j < n/2; j++)

speaker[i * n + j] = MAX;

}

main()

{

initialize();

tone(2000); // 2000 hz

execute(100);// 2초

tone(1000); // 1000 hz

execute(100);

tone(500); // 500 hz

execute(100);

}

Page 174: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

일정한 주기로 반복되는 파형을 만들어 스피커를 동작시키면 소리가 만들어

진다. tone()함수는 입력 인자로 주파수 값을 받아서 배열 speaker 에 소리 파형을

저장한다. 실제 소리는 +와 –를 반복하지만 여기에서 만든 소리는 0 과

+35767 을 반복한다. 하지만 들리는 소리는 별차이가 없다. mute()함수는 파형을

없애는 동작을 한다. 새로운 파형을 얻기 위해 이전 파형을 깨끗이 지워야 한다.

#DEFINE 지시어

#define MAX 35767

#define 은 #include 와 같은 전처리 지시어 이다. 프로그램상의 명령문은

아니지만, “MAX 라는 문자를 만나면 숫자 35767 를 바꾸시오” 라고 컴퓨터에게

알려주는 역할을 한다. 이러한 전처리 지시어를 사용하면 프로그램을 알아보기

쉽게 해주고 수정 시에도 모든 숫자를 하나씩 바꾸지 않고 한번에 수정할 수

있다.

메트로놈의 원리

기계식 메트로놈

Page 175: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

위 그림과 같은 기계식 메트로놈은 이전부터 음악 연주에서 필수품이었다.

박자를 정확하게 연주하기 위해 거꾸로 된 추가 일정한 시간 간격으로 왕복

운동하면서 소리로 박자를 알려준다. 추의 길이가 짧아 질수록 빠른 박자가

만들어 진다. C 언어로 매우 정확한 디지털 메트로놈을 만들어 실제 연주에

사용해 보자.

메트로놈의 속도는 Tempo 라고 하며 분당 120 회를 기준으로 한다. 이

속도를 120 BPM(Beat Per Minute)라고 하고 악보의 4 분 음표 120 개를 일분에

연주 하라는 의미이다. 즉, 120BPM 은 0.5 초 간격으로 4 분 음표를 연주하고, 60

BPM 은 1 초 간격으로 연주 하라는 뜻이다.

메트로놈의 박자는 Beat 라고 하며, 2 박자, 3 박자, 4 박자 등이 있다. 보통

처음 음은 강하게 연주하고 다음 음은 약하게 연주 한다.

다음 예제는 120 BPM, 3 박자의 메트로놈을 프로그램으로 만들어 본 것이다.

List 로봇 메트로놈

#include "pelican.h"

#define MAX 35767

#define TEMPO 120

#define BEAT 3

void tone(int hz)

{

int i, j, n = 48000/hz;

for(i = 0; i < 960/n; i++)

for(j = 0; j < n/2; j++)

speaker[i * n + j] = MAX;

execute(1); // 20 msec

for(i = 0; i < 960; i++)

speaker[i] = 0;

}

main()

Page 176: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

{

initialize();

int beat;

float tempo = 50 * (60.0 / TEMPO);

while(1)

{

tone(2000); // chime

execute(tempo);

for(beat = 1; beat < BEAT; beat++)

{

tone(500); // drum

execute(tempo);

}

}

}

프로그램을 살펴보면 tone()함수는 이전 예제와 별 차이가 없다. tone(2000)은

2000Hz 의 소리를 발생한다. 이 높은 음은 기계식 메트로놈의 강한 박자를

나타낸다. tone(500)은 500Hz 의 낮은 음을 발생한다. 드럼과 유사한 소리를

발생하여 약한 박자를 나타낸다.

메트로놈의 속도는 정확성이 중요하다. 120BPM 을 만들기 위해 정확히 0.5

초 간격으로 음을 발생 시켜야 한다.

float tempo = 50 * (60.0 / TEMPO);

위 식의 0.5ch 동안 소리를 내기 위한 프레임 수를 계산한다. 120 BPM 인

경우, 25 프레임이 됨을 알 수 있다.

다음은 비트 정보이다. #define BEAT 3 문장은 3 박자의 메트로놈, 즉 강, 약,

약을 박자를 만든다.

Page 177: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

춤추는 로봇 메트로놈

로봇이 몸으로 박자를 표현하면 소리만 발생하는 메트로놈보다 더 인기를

끌 것이다. 다음은 프로그램은 main()함수의 내용을 로봇 동작과 동기화시켜

박자와 템포에 맞추어 춤을 추게 한다.

main()

{

initialize();

int beat;

int tempo = 50 * (60.0 / TEMPO);

int n = 0;

while(1)

{

led[0] = 63;

led[1] = 0;

eye = ++n % 6 + 1;

left_wing = 32;

right_wing = 32;

tone(2000); // chime

led[0] = 0;

left_wing = 0;

right_wing = 0;

execute(tempo);

for(beat = 1; beat < BEAT; beat++)

{

led[0] = 0;

led[1] = 63;

bill = 10;

tone(500); // drum

led[1] = 0;

bill = 0;

execute(tempo);

}

}

}

Page 178: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

심화학습

@TEMPO 와 BEAT 를 다양하게 바꾸어 실행 시켜 본다.

@소프트웨어로 만든 로봇 메트로놈의 박자 정확도는 얼마나 될까 측정해

본다.

@실제 소리를 녹음한 후 이 소리를 적용하여 기계식 메트로놈의 흉내를

내는 프로그램을 만들어 본다.

@춤추는 로봇 메트로놈을 더욱 다양하게 동작을 만들어 본다.

Page 179: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 20 장 노래하고 말하는 매트릭스 로봇

매트릭스 로봇은 펠리컨처럼 부리는 없지만 말하는 흉내를 소프트웨어로

만들 수 있다.

말하는 매트릭스 로봇

입 모양을 흉내 내는 프로그램을 만든다. 소리의 크기에 맞추어 입을 크게

벌리는 프로그램은 “노래하며 춤추는 펠리컨”을 참고로 하면 된다. 입술의

모양을 닫은 상태에서 크게 벌린 8 가지 상태를 준비한다. 입술의 모양은 3 x

8 의 직사각형으로 디자인 한다.

List 말하는 매트릭스 로봇 #include "matrix.h"

#define P 119

int lips[8][3][8] =

{{{0,0,0,0,0,0,0,0},

{0,0,0,P,P,0,0,0},{0,0,0,0,0,0,0,0}},

{{0,0,0,0,0,0,0,0},

{0,0,P,P,P,P,0,0},{0,0,0,0,0,0,0,0}},

{{0,0,0,P,P,0,0,0},

{0,0,P,0,0,P,0,0},{0,0,0,P,P,0,0,0}},

{{0,0,P,P,P,P,0,0},

{0,0,P,0,0,P,0,0},{0,0,P,P,P,P,0,0}},

{{0,0,P,P,P,P,0,0},

{0,P,0,0,0,0,P,0},{0,0,P,P,P,P,0,0}},

{{0,P,P,P,P,P,P,0},

{0,P,0,0,0,0,P,0},{0,P,P,P,P,P,P,0}},

{{0,P,P,P,P,P,P,0},

{P,0,0,0,0,0,0,P},{0,P,P,P,P,P,P,0}},

{{P,P,P,P,P,P,P,P},

{P,0,0,0,0,0,0,P},{P,P,P,P,P,P,P,P}}};

int talk(int n)

{

int i, j;

Page 180: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

for(i = 5; i < 8; i++)

for(j = 0; j < 8; j++)

matrix[8*i+j] = lips[n][i-5][j];

}

int main()

{

initialize();

FILE* file = fopen("matrix.wav", "rb");

int j = 0, f = 0;

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

talk(power/400000);

execute(1);

}

}

lips[0] lips[1] lips[2] lips[3]

lips[4] lips[5] lips[6] lips[7]

Page 181: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

음성 파일 “matrix.wav”의 소리에 맞추어 말하는 느낌이 들도록 talk()함수를

조절 하면 된다.

노래하고 말하는 매트릭스 로봇

표정 없이 입술만 움직이니까 어색하다면 눈과 코를 만들어 준다. 눈과

코는 4 x 8 크기의 직사각형으로 디자인 한다.

List 노래하며 말하는 매트릭스 로봇 #include "matrix.h"

#define P 119

int lips[8][3][8] =

{{{0,0,0,0,0,0,0,0},

{0,0,0,P,P,0,0,0},{0,0,0,0,0,0,0,0}},

{{0,0,0,0,0,0,0,0},

{0,0,P,P,P,P,0,0},{0,0,0,0,0,0,0,0}},

{{0,0,0,P,P,0,0,0},

{0,0,P,0,0,P,0,0},{0,0,0,P,P,0,0,0}},

{{0,0,P,P,P,P,0,0},

{0,0,P,0,0,P,0,0},{0,0,P,P,P,P,0,0}},

{{0,0,P,P,P,P,0,0},

{0,P,0,0,0,0,P,0},{0,0,P,P,P,P,0,0}},

{{0,P,P,P,P,P,P,0},

{0,P,0,0,0,0,P,0},{0,P,P,P,P,P,P,0}},

{{0,P,P,P,P,P,P,0},

{P,0,0,0,0,0,0,P},{0,P,P,P,P,P,P,0}},

{{P,P,P,P,P,P,P,P},

{P,0,0,0,0,0,0,P},{P,P,P,P,P,P,P,P}}};

int faces[8][4][8] =

{{{0,P,0,0,0,0,P,0},{P,P,P,0,0,P,P,P},

{0,P,0,P,0,0,P,0},{0,0,0,P,P,0,0,0}},

{{0,P,P,0,0,P,P,0},{P,0,0,P,P,0,0,P},

{0,0,0,P,0,0,0,0},{0,0,0,P,P,0,0,0}},

{{P,0,0,P,P,0,0,P},{0,P,P,0,0,P,P,0},

{0,0,0,P,0,0,0,0},{0,0,0,P,P,0,0,0}},

Page 182: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

{{0,0,0,0,0,0,0,0},{P,P,P,0,0,P,P,P},

{0,0,0,P,0,0,0,0},{0,0,0,P,P,0,0,0}},

{{P,P,P,0,0,P,P,P},{P,0,P,0,0,P,0,P},

{P,0,P,P,0,P,0,P},{0,0,0,P,P,0,0,0}},

{{P,P,0,0,0,0,P,P},{0,0,P,0,0,P,0,0},

{P,P,0,P,0,0,P,P},{0,0,0,P,P,0,0,0}},

{{P,P,P,0,0,P,P,P},{P,0,P,0,0,P,0,P},

{P,P,P,P,0,P,P,P},{0,0,0,P,P,0,0,0}},

{{0,P,P,0,0,P,P,0},{P,0,0,P,P,0,0,P},

{0,P,P,P,0,P,P,0},{0,0,0,P,P,0,0,0}}};

int talk(int n)

{

int i, j;

for(i = 5; i < 8; i++)

for(j = 0; j < 8; j++)

matrix[8*i+j] = lips[n][i-5][j];

}

int face(int n)

{

int i, j;

for(i = 0; i < 4; i++)

for(j = 0; j < 8; j++)

matrix[8*i+j] = faces[n][i][j];

}

int main()

{

initialize();

FILE* file = fopen("alphabet.wav", "rb");

int j = 0, f = 0;

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

talk(power/400000);

Page 183: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

if(j++ % 69 == 0) face(f++ % 8);

execute(1);

}

}

심화학습

@ 눈 모양과 코, 입술을 개성 있게 디자인 한다.

Page 184: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 21 장 로봇 자명종

예제로 나온 lip_sync()함수와 표준함수 time()을 활용하여 10 초 후 주인을

깨우는 로봇 프로그램을 완성하시오.

스톱워치 만들기

표준 함수 time()을 사용하기 위해서는 time.h 파일을 인클루드 해야 한다.

List 10초 후 동작하는 로봇 자명종 #include <time.h>

#include "pelican.h"

#define MAX 35767

void tone(int hz)

{

int i, j, n = 48000/hz;

for(i = 0; i < 960/n; i++)

for(j = 0; j < n/2; j++)

speaker[i * n + j] = MAX;

}

void lip_sync(char* f)

{

FILE* file = fopen(f, "rb");

while(1)

{

if(fread(speaker, 2, 960, file) == 0) break;

int power = 0, i;

for(i = 0; i < 960; i++)

{

if(speaker[i] > 0) power += speaker[i];

}

bill = power / 150000;

execute(1);

}

Page 185: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

fclose(file);

}

int main()

{

initialize();

eye = 4;

lip_sync("alarm.wav");

int t0 = time(NULL);

while(1)

{

int t = time(NULL);

if((t - t0) > 10) break;

Sleep(100);

}

eye = 5;

tone(1000); // 1 Khz

while(1)

{

bill = 63;

left_wing = 63;

right_wing = 0;

execute(10);

bill = 0;

left_wing = 0;

right_wing = 63;

execute(10);

}

}

Page 186: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

제 22 장 디지털 로봇 시계

이번 과제가 이 책의 수준으로 볼 때 최종 단계에 해당한다. 배운 것을

복습하면서 차근차근 진행해 보자. 이 프로그램은 로봇이 정확한 시간을 알려

주므로 실용성이 높고 알람 기능 등을 추가하면 더욱 완성도 높은 프로그램이

될 것이다.

0-9 숫자를 표시하자

대규모 프로그램을 완성하는 방법은 우선 필요한 기능을 생각하고 하나씩

만든 다음에 최종적으로 조립하는 방법이 보편적이다. 우선 0-9 까지 숫자를

표시하는 프로그램이 필요하므로 다음과 같이 만든다.

List 0-9 숫자를 표시하자

#include <time.h>

#include "matrix.h"

#define P 50

int digits[11][5][3] =

{{{P,P,P},{P,0,P},{P,0,P},{P,0,P},{P,P,P}},

{{0,0,P},{0,0,P},{0,0,P},{0,0,P},{0,0,P}},

{{P,P,P},{0,0,P},{P,P,P},{P,0,0},{P,P,P}},

{{P,P,P},{0,0,P},{P,P,P},{0,0,P},{P,P,P}},

{{P,0,P},{P,0,P},{P,P,P},{0,0,P},{0,0,P}},

{{P,P,P},{P,0,0},{P,P,P},{0,0,P},{P,P,P}},

{{P,P,P},{P,0,0},{P,P,P},{P,0,P},{P,P,P}},

{{P,P,P},{P,0,P},{P,0,P},{0,0,P},{0,0,P}},

{{P,P,P},{P,0,P},{P,P,P},{P,0,P},{P,P,P}},

{{P,P,P},{P,0,P},{P,P,P},{0,0,P},{P,P,P}},

{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}};

int display(int n, int x, int y)

{

int i, j;

for(i = 0; i < 5; i++)

for(j = 0; j < 3; j++)

Page 187: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

matrix[8*(i+y)+(j+x)] = digits[n][i][j];

}

int main()

{

initialize();

while(1)

{

int t = time(NULL) % 60;

if(t/10 != 0) display(t/10, 1, 3);

else display(10, 1,3);

display(t%10, 5, 3);

execute(1);

}

}

이 프로그램은 현재 시각의 초를 표시한다. 3 차원 배열의 11 번째, 마지막

데이터는 공백 문자이다. 함수 display()는 3 개의 인자를 가지고 있는데, 처음

인자는 표시할 숫자이며, 나머지 x, y 는 표시할 장소의 좌표이다.

현지 시갂을 표시하기

현재 시간은 time()함수로 호출하여 알지 못한다. 지구 상의 장소에 따라

현지 시간이 다르므로 절대 시간을 현지 시간으로 변환하는 표준 함수,

Page 188: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

localtime()이 필요하다. 이 함수의 반환 값은 시간에 대한 여러 가지 정보를

가지고 있는 구조체 포인터이다. 구조체 포인터 now 를 정의하고 time()함수의

결과 값을 가진 변수의 주소를 인자로 넘긴다. 구조체 포인터 now 를 이용하여

시간 관련 정보를 알아낸다.

int min, hour;

struct tm* now;

int t = time(NULL);

now = localtime(&t);

min = now->tm_min;

hour = now->tm_hour;

구조체 포인터 now 에는 초, 분, 시외 다음과 같이 여러 정보가 포함되어

있다.

멤버명 내용

tm_sec 초(0-59)

tm_min 분(0-59)

tm_hour 시(0-23)

tm_mday 날짜(1-31)

tm_mon 월(0-11), 1 월을 0 으로 함

tm_year 현재의 년도에서 1900 을 뺀 값

tm_wday 요일(0-6), 일요일을 0 으로 함

tm_yday 연초부터 지나간 일수(0-365), 1 월 1 일을 0 으로 함

Page 189: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

현지 시간을 알고 나면 시간을 표시하는 방법을 생각해 본다. 매트릭스

로봇의 LED 숫자의 한계로, 분과 시를 동시에 표시하지 못하므로 1.5 초 간격을

번갈아 표시하기로 한다.

List 현지 시간 표시하기

#include <time.h>

#include "matrix.h"

#define P 50

int digits[11][5][3] =

{{{P,P,P},{P,0,P},{P,0,P},{P,0,P},{P,P,P}},

{{0,0,P},{0,0,P},{0,0,P},{0,0,P},{0,0,P}},

{{P,P,P},{0,0,P},{P,P,P},{P,0,0},{P,P,P}},

{{P,P,P},{0,0,P},{P,P,P},{0,0,P},{P,P,P}},

{{P,0,P},{P,0,P},{P,P,P},{0,0,P},{0,0,P}},

{{P,P,P},{P,0,0},{P,P,P},{0,0,P},{P,P,P}},

{{P,P,P},{P,0,0},{P,P,P},{P,0,P},{P,P,P}},

{{P,P,P},{P,0,P},{P,0,P},{0,0,P},{0,0,P}},

{{P,P,P},{P,0,P},{P,P,P},{P,0,P},{P,P,P}},

{{P,P,P},{P,0,P},{P,P,P},{0,0,P},{P,P,P}},

{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}};

int display(int n, int x, int y)

{

int i, j;

for(i = 0; i < 5; i++)

for(j = 0; j < 3; j++)

matrix[8*(i+y)+(j+x)] = digits[n][i][j];

}

int main()

{

int min, hour, i;

struct tm* now;

initialize();

while(1)

{

int t = time(NULL);

now = localtime(&t);

Page 190: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

min = now->tm_min;

hour = now->tm_hour;

if(min/10 != 0) display(min/10, 1, 3);

else display(10, 1,3);

display(min%10, 5, 3);

execute(75);

for(i = 0; i < 64; i++)

matrix[i] = 0;

if(hour/10 != 0) display(hour/10, 0, 0);

else display(10, 0, 0);

display(hour%10, 4, 0);

execute(75);

for(i = 0; i < 64; i++)

matrix[i] = 0;

}

}

시와 분을 표시하기 전에 전체 화면을 지우는 for 반복문이 필요하다.

심화학습

@ 시간을 오전과 오후로 나누어 표시하고 오후인 경우에는 아래 그림과

같이 오른쪽 상단에 점을 찍는다.

프로그램 힌트:

Page 191: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

void execute_clear(int frame)

{

execute(frame);

int i;

for(i = 0; i < 64; i++)

matrix[i] = 0;

}

int main()

{

int min, hour, i;

struct tm* now;

initialize();

while(1)

{

int t = time(NULL);

now = localtime(&t);

min = now->tm_min;

hour = now->tm_hour;

if(min/10 != 0) display(min/10, 1, 3);

else display(10, 1,3);

display(min%10, 5, 3);

execute_clear(75);

if(hour > 12)

{

matrix[7] = P;

hour -= 12;

}

else matrix[7] = 0;

if(hour == 0) hour = 12;

if(hour >= 10)

for(i = 0; i < 40; i += 8)

matrix[i] = P;

display(hour%10, 2, 0);

execute_clear(75);

}

}

Page 192: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

@ 상단의 스위치를 누르면 월과 날짜를 표시하는 프로그램을 같은

방식으로 완성하라. 월은 0 부터 시작하므로 1 을 더하여 표시하라.

int main()

{

int day, mon, i;

struct tm* now;

initialize();

while(1)

{

int t = time(NULL);

now = localtime(&t);

day = now->tm_mday;

mon = now->tm_mon + 1;

if(day/10 != 0) display(day/10, 1, 3);

else display(10, 1,3);

display(day%10, 5, 3);

execute_clear(75);

if(mon >= 10)

for(i = 0; i < 40; i += 8)

matrix[i] = P;

display(mon%10, 2, 0);

execute_clear(75);

}

}

Page 193: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

PART 5. Appendix

Page 194: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 195: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

부록

1. 새로운 작업 공갂 만들기

샘플 작업공간과 별도로 나만의 작업공간을 만들어 보자. 우선 File

메뉴에서 Switch Workspace 선택 후, 서브 메뉴에서 Other...를 선택하면 다음과

같은 윈도우가 나타난다. Copy Settings 를 열고 를

선택한다.

작업공간의 이름을 “workspace_matrix”로 입력하고 OK 버튼을 클릭한다.

확인해 보면 실제로 같은 이름의 폴더가 생긴다. 자동으로 프로그램이

종료되었다가 다시 시작하면서 다음과 같은 시작 화면이 나타난다.

Page 196: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

X 로 표시된 부분을 클릭하여 Welcome 화면을 닫는다. 이제 아래와 같은

작업화면이 나타난다. 이 작업화면은 3 부분으로 나누어져 있다.

1. Project Explorer: 왼쪽영역에 위치한 화면. 작업 공간내의 소스와 기타 파일을

표시한다.

2. Editor: 오른쪽 상단의 영역. C 소스 파일을 편집하는 영역

3. Console: 오른쪽 하단. 프로그램이 실행 시 입출력을 담당하는 영역.

Page 197: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

도움말 기능 알아보기

C 언어 외의 여러 가지 기능을 알고 싶다면 도움말을 열고 공부한다. 영어로

되어 있지만 작업공간이나 메뉴의 기능을 자세히 알고 싶다면 도움이 될 것이다.

다음과 같은 도움말 화면을 열기 위해 메뉴 “Help”에서 을

선택한다.

Page 198: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

새로운 프로젝트를 만들자

하나의 프로젝트에는 하나의 메인 프로그램만이 허용된다. 따라서 새로운

작품을 만들기 위해서 새 프로젝트를 생성하고 소스를 관리한다

프로젝트를 복사하여 새 프로젝트를 만들기

하지만 로봇마다 필요한 별도 프로그램과 설정이 다르므로 이미 만들어져

있는 프로젝트를 다음 과정으로 복사하여 사용하는 편이 간편하다.

1. C/C++ 프로젝트 창에서 원하는 복사할 프로젝트를 선택 한 후 콘트롤

키를 누른 상태에서 C 와 V 를 순차적으로 누른다. 이 과정은 Edit 메뉴

Page 199: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

또는 오른편 키를 눌러서 Copy 명령과 Paste 명령을 순차적으로

실행하는 것과 동일하다.

2. 이제 복사할 프로젝트 이름을 기입하고 OK 버튼을 클릭한다.

3. “pelican_new” 프로젝트가 생성되면 폴더 내의 필요 없는 파일을 지우고

새로운 소스 파일을 만드는 작업을 시작한다.

4.

빈 프로젝트 만들기(NEW EMPTY PROJECT)

로봇과 관련 없는 순수한 C 프로그램을 공부하는 프로젝트를 만들거나

기존에 없는 새로운 로봇을 입수한 경우, 처음부터 빈 프로젝트를 만드는

방법을 알아본다.

Page 200: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

새 프로젝트는 File 메뉴에서 New 를 선택하거나 메뉴 바에서 그림과 같이

아이콘을 선택하여 만들 수 있다.

다음의 프로젝트 생성 창에서 필요한 정보를 입력한다. 우선 프로젝트의

이름은 입력하고, Project type 은 Empty Project 를

선택한다.

Page 201: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

Finish 버튼을 누르면 Project Explorer 창에 다음과 같은 기본 폴더가 만들어

진다.

Includes 폴더는 C 언어의 표준 함수가 들어있다. 이 표준 함수를

인클루드하는 경우에는 < >를 사용한다.

소스 파일 만들기

툴 바에서 New C/C++ Source Files 아이콘을 선택하면 다음과 같이 나타난다.

(이전에 일단 프로젝트가 청색으로 선택된 상태임을 확인한다)

을 클릭하면 다음과 같은 소스파일 생성 화면이 나타난다.

Page 202: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

을 입력한다. 소스 파일 “my_prog.c”가 추가 된다.

동시에 편집화면에는 내용이 표시된다.

이제 원하는 C 프로그램을 입력한다.

Page 203: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

소스 폴더 만들기

대부분의 C 프로그램은 하나의 큰 단독 파일로 구성되지 않고 여러 개의

기능을 달리하는 작은 파일로 나누어 개발된다. 이렇게 하는 편이 소스를

관리하기 편하고 수정과 재사용이 용이하기 때문이다. 소스를 모아서 관리하기

위해 소스 폴더를 만드는 방법을 알아본다.

를 선택하면 다음과 같은 소스폴더 생성 창이 나타난다.

을 입력하고 Project 탐색창에 새로운 소스폴더가

추가됨을 확인 한다. 처음 만들어진 소스 파일을 클릭한 후 버튼을 떼지 말고

폴더 위로 이동한다. 이 과정을 드래그앤드롭(drag and drop) 이라고 한다.

Page 204: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

이제 소스 파일이 소스 폴더 내에 위치함을 확인한다.

소스 파일 편집하기

다음과 같은 간단한 프로그램을 입력한다.

프로그램을 실행하기 위해 메뉴 바에서 실행 버튼을 클릭합니다.

어떤 일이 일어 날까요? 실망스럽게도 다음과 같은 경고 창이 뜬다.

Page 205: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

아직 실행할 준비가 안된 상태이다. C 프로그램은 일단 컴퓨터가 알아볼 수

있는 형태로 변화되지 않으면 실행이 되지 않는다. 이 과정을 컴파일이라고

하는데 꼭 알아야 하는 지식이다.

방금 입력한 내용을 파일에 저장하기 위해 Save 메뉴를 클릭한다. 파일이름

앞에 붙어 있는 *가 사라짐을 확인한다.

이제 컴퓨터가 이해하는 이진 파일을 만들기 위해 Build All 메뉴를

클릭한다.

프로젝트 내에 Binaries 와 Debug 폴더가 자동으로 만들어 진다. Binaries 내의

my_program.exe 는 컴파일이 완료된 실행 파일이다.

이제 다시 실행 버튼을 클릭한다. 콘솔 창에 “Hello”가 나타남을 확인한다.

Page 206: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

자동 컴파일 기능

소스를 수정하면 또 컴파일을 수행해야 한다. 만약 소스를 수정하면

자동으로 알아서 컴파일을 하도록 설정하려면 다음과 같이 Project 메뉴에서

을 첵크한다. 첵크하지 않으면 매번 수동으로

을 수행해야 한다.

로봇 프로젝트를 만들자

C 언어로 로봇을 제어하기 위해서는 C 의 표준 함수만으로는 충분하지 않다.

RoboidC 는 C 의 표준함수와 자동 컴파일기능을 기본으로 모든 로봇을 제어할

수 있는 라이브러리를 제공하고 있다.

프로젝트를 컴파일 하기 전에 필요한 라이브러리의 위치를 다음과 같이

미리 설정해 주어야 한다. 로봇 프로젝트를 컴파일 시 필요한 라이브러리는

wsock32 와 대상 로봇 제어 헤더 파일이다.

Page 207: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

마우스로 로봇 프로젝트를 선택한 후 메뉴에서 Project -> Property 를

선택한다.

프로퍼티 창이 나타나면 Settings -> Directories 를 선택하고 Include

paths 창에서 을 클릭하여 폴더를 추가한다. 이때 특정 로봇에 필요한 파일

폴더를 File System 또는 작업공간에서 찾아서 추가한다. 다음은 펠리컨 로봇을

개발하기 위한 프로젝트를 표시한다. File System 을 선택하고 pelican_c 폴더

내에서 Roboid 폴더를 선택한다. 다름 로봇도 같은 형식으로 구성되어 있다.

Page 208: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

OK 버튼을 눌러 실행을 끝내면 다음과 같이 Includes 에 폴더가 추가 됨을

볼 수 있다.

이제 #include "pelican.h" 명령이 제대로 동작한다.

같은 방법으로 필요한 라이브러리 wsock32 를 추가한다. wsock32 는 표준

라이브러리로 로보이드 통신에 필요한 TCP/IP 를 지원한다. MinGW C Linker 에서

Libraries 를 선택하고 을 클릭하여 wsock32 라이브러리를 추가한다.

MinGW 는 Windows 에서 표준 C 컴파일 환경을 제공해주는 공개

소프트웨어이다.

이상과 같은 과정을 따라서 한다면 여러분이 제작한 독자적인 로봇도

RoboidC 를 이용해서 프로그램을 개발하거나 일반에게 공개할 수 있다.

Page 209: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 210: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

2. 독립된 실행 파일 만들기

RoboidC 를 사용하는 동안에는 좋은 환경 덕분에 실행 파일을 직접 더블

클릭하여 실행할 필요가 없었다. 하지만 개발이 끝난 작품(로봇 프로그램)을

제출하거나 RoboidC 가 없는 환경에서는 독립된 실행 파일(*.exe)을 만들어

배포해야 한다.

다음 순서를 따라 하면 간단히 실행 파일이 만들어 진다.

1. 우선 C/C++ project 창에서 아래와 같이 두 파일을 선택한다. 복수의

파일을 선택 할 경우에는 두 번째부터는 콘트롤 키를 누른 상태에서

클릭한다.

2. File 메뉴를 열거나 또는 오른쪽 버튼을 클릭하여 Export… 메뉴를

선택한다.

3. Export 창에서 File System 을 선택하고 Next 버튼을 클릭.

Page 211: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

4. 출력할 폴더 이름을 기입하고 Finish 를 클릭한다. “C:\Robot”폴더에

옮겨진 실행 파일 “roboid.exe”를 더블 클릭하여 실행한다. 일단 실행

파일이 된 후는 일반적인 PC 프로그램과 동일하게 취급하면 된다.

이름은 소스 파일과 무관하게 항상 “roboid.exe”로 되어 있으나 원하는

이름으로 변경해도 된다. 주의할 점은 같은 폴더 내에 Roboid 폴더가

같이 있어야 정상적으로 실행된다.

Page 212: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야
Page 213: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

3. 기타 로봇의 사양과 사용법

하나의 프로젝트에는 하나의 메인 프로그램만이 허용된다. 따라서 새로운

작품을 만들기 위해서 새 프로젝트를 생성하고 소스를 관리한다. 새 프로젝트는

File 메뉴에서 New 를 선택하거나 메뉴 바에서 그림과 같이 아이콘을 선택하여

만들 수 있다.

4. 오디오 포맷 변홖

Page 214: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

아스키 코드 표

DEC HEX OCT Char

DEC HEX OCT Char

DEC HEX OCT Char

0 00 000 Ctrl-@ NUL 43 2B 053 + 86 56 126 V

1 01 001 Ctrl-A SOH 44 2C 054 , 87 57 127 W

2 02 002 Ctrl-B STX 45 2D 055 - 88 58 130 X

3 03 003 Ctrl-C ETX 46 2E 056 . 89 59 131 Y

4 04 004 Ctrl-D EOT 47 2F 057 / 90 5A 132 Z

5 05 005 Ctrl-E ENQ 48 30 060 0 91 5B 133 [

6 06 006 Ctrl-F ACK 49 31 061 1 92 5C 134 \

7 07 007 Ctrl-G BEL 50 32 062 2 93 5D 135 ]

8 08 010 Ctrl-H BS 51 33 063 3 94 5E 136 ^

9 09 011 Ctrl-I HT 52 34 064 4 95 5F 137 _

10 0A 012 Ctrl-J LF 53 35 065 5 96 60 140 `

11 0B 013 Ctrl-K VT 54 36 066 6 97 61 141 a

12 0C 014 Ctrl-L FF 55 37 067 7 98 62 142 b

13 0D 015 Ctrl-M CR 56 38 070 8 99 63 143 c

14 0E 016 Ctrl-N SO 57 39 071 9 100 64 144 d

15 0F 017 Ctrl-O SI 58 3A 072 : 101 65 145 e

16 10 020 Ctrl-P DLE 59 3B 073 ; 102 66 146 f

17 11 021 Ctrl-Q DCI 60 3C 074 < 103 67 147 g

18 12 022 Ctrl-R DC2 61 3D 075 = 104 68 150 h

19 13 023 Ctrl-S DC3 62 3E 076 > 105 69 151 i

20 14 024 Ctrl-T DC4 63 3F 077 ? 106 6A 152 j

21 15 025 Ctrl-U NAK 64 40 100 @ 107 6B 153 k

22 16 026 Ctrl-V SYN 65 41 101 A 108 6C 154 l

23 17 027 Ctrl-W ETB 66 42 102 B 109 6D 155 m

Page 215: 로봇으로 배우는 C - Roboid Studioroboidstudio.org/roboidc/download.php?fn=BeginningCwith...제 1 장 C 는 어떤 얶어인가? C얶어는 어떤 얶어이며 왜 공부해야

24 18 030 Ctrl-X CAN 67 43 103 C 110 6E 156 n

25 19 031 Ctrl-Y EM 68 44 104 D 111 6F 157 o

26 1A 032 Ctrl-Z SUB 69 45 105 E 112 70 160 p

27 1B 033 Ctrl-[ ESC 70 46 106 F 113 71 161 q

28 1C 034 Ctrl-\ FS 71 47 107 G 114 72 162 r

29 1D 035 Ctrl-] GS 72 48 110 H 115 73 163 s

30 1E 036 Ctrl-^ RS 73 49 111 I 116 74 164 t

31 1F 037 Ctrl_ US 74 4A 112 J 117 75 165 u

32 20 040 Space 75 4B 113 K 118 76 166 v

33 21 041 ! 76 4C 114 L 119 77 167 w

34 22 042 " 77 4D 115 M 120 78 170 x

35 23 043 # 78 4E 116 N 121 79 171 y

36 24 044 $ 79 4F 117 O 122 7A 172 z

37 25 045 % 80 50 120 P 123 7B 173 {

38 26 046 & 81 51 121 Q 124 7C 174 |

39 27 047 ' 82 52 122 R 125 7D 175 }

40 28 050 ( 83 53 123 S 126 7E 176 ~

41 29 051 ) 84 54 124 T 127 7F 177 DEL