레이블이 자료형인 게시물을 표시합니다. 모든 게시물 표시
레이블이 자료형인 게시물을 표시합니다. 모든 게시물 표시

2015년 7월 1일 수요일

자바(JAVA)의 기본 자료형 (primitive types)

 자바의 자료형은 크게 기본형(primitive type)과 참조형(referene type)으로 나뉜다. 그리고 기본형은 다시 정수형, 실수형, 문자형, 논리형 네 가지로 분류할 수 있다. 이것들을 다음 표에 정리하였다.

[표 1] 자바의 기본 자료형(primitive type)의 종류
분류
이름
바이트 수
비고
정수형
byte
1
-127 ~ +128
short
2
-32,768 ~ + 32,767
int
4
-2,147,483,648 ~ +2,147,483,647
long
8
-9,223,372,036,854,775,808~
+9,223,372,036,854,775,807
실수형
float
4
단정도 실수형 (유효 자리는 7 정도임)
double
8
배정도 실수형 (유효 자리는 15정도)
문자형
char
2
유니코드 문자열
논리형
boolean
1
true, false

 정수형은 정수를 저장하는 자료형으로서 byte, short, int, long 네 가지가 있으며 각각에 저장할 수 있는 정수의 범위가 다르다 ([표 1] 참조) 한 가지 알아둘 것은 C/C++ 과 다르게 자바의 정수형에는 unsigned 형이 없고 부호 있는 정수형만 있다는 것이다. (자료 구조의 단순함을 유지하기 위해서 이렇게 설계했다고 한다.) 그리고 C/C++의 long long int 가 자바의 long형에 해당된다. 숫자 상수끝에 L/l 접미어가 붙으면 long형으로 저장된다.

 실수형은 실수(소숫점이나 e/E를 포함하는 수)를 저장하는 자료형으로서 float와 double 형이 있다. (이것은 C/C++과 동일하다.) 숫자 상수 끝에 f/F 접미어가 붙으면 float형으로 저장된다.

 컴퓨터에서는 모든 문자에 번호를 할당하고 문자를 정수로 바꿔서 저장한다. 어떤 문자에 어떤 번호를 할당하는 가는 여러 방법이 있으며 자바는 유니코드(unicode)라는 세계 표준 규격을 따른다. 유니코드는 국제적으로 사용되는 모든 문자를 0~65,535 범위(2 바이트)의 정수에 할당한 것이라고 이해하면 된다. 자바의 char형은 유니코드 한 문자를 표현할 수 있는 자료형으로서 2 byte 크기이다. 문자상수는 작은 따옴표를 사용하여 표시한다. 예를 들면 ‘a’, ‘가’, ‘3’ 등이다. (C/C++에서는 char형이 1byte이다. 혼동하면 안된다.)

 논리형은 true(참)과 false(거짓) 단 두 개의 값만을 가지는 자료형이다. 조건 검사에서 사용되는 논리식의 결과값을 저장하는 용도로 사용된다.

2015년 6월 15일 월요일

 이제 AVR을 구동시키기 위해서는 AVR이 이해할 수 있는 명령어들(어셈블리 명령어)로 이루어진 화일을 내부 플래시 메모리에 다운로드시켜야 한다. 따라서 사용자가 작성한 C/C++ 프로그램을 AVR이 실행할 수 있는 이진 파일로 번역(컴파일)해 주는 컴파일러가 필요하다. 사용자가 작성한 C/C++프로그램은 그 표준이 정해져 있기 때문에 PC용이든 uC용이든 그 외관은 비슷해 보이지만 컴파일러에 따라서 같은 프로그램을 PC에서, uC에서, 혹은 DSP에서와 같이 다양한 플랫폼에서 구동시킬 수 있다.

 이러한 AVR컴파일러는 상업용(예:CodevisionAVR) 과 무료 컴파일러로 크게 구분할 수 있다. avr-gcc/avr-g++ 은 대표적인 오픈소스 기반의 무료 AVR 컴파일러로서 그 성능이 상용 컴파일러에 못지 않고 또 Atmel Studio라는 개발 IDE에 통합되어 편리하게 사용할 수 있기 때문에 널리 사용되고 있다. Atmel studio 6.x버전은 컴파일러를 포한한 여러 도구를 모아 놓은 avr 툴체인(toolchain)이 설치 화일에 포함되어서 Atmel studio를 설치할 때 이것들도 자동으로 설치되며 따라서 WinAVR을 별도로 설치할 필요가 없다.

지원하는 변수형

 avr툴체인은 <표 4.1.1>에 수록된 데이터 형을 지원한다. 표준 C/C++에서 지원하는 거의 모든 데이터형을 지원한다. 또한 C/C++ 에서 상수는 10진수, 8진수, 16진수 세 가지 표현만 지원했으나 gcc/g++는 2진수 표현도 지원하며 0b로 시작한다. PC환경에서는 2진수를 취급하는 것이 그다지 중요하지 않지만 uC 프로그래밍에서는 2진수를 다루는 것은 매우 빈번히 일어나며 중요하다. 예를 들어서 다음 네 가지 변수는 모두 같은 숫자값을 가진다.

byA = 17;
byB = 019;
byC = 0x11;
byD = 0b00010001; //2진수 표현

즉, AVR 프로그램에서 2진수를 취급하는 경우가 상대적으로 많기 때문에 지원하는 기능이며 편리하게 사용할 수 있다.

[표 1] avr툴체인이 지원하는 자료형
종류
데이터형
축약된 표현
바이트 수
비고
signed char
int8_t
1
unsigned char
uint8_t
1
signed short
int16_t
2
unsigned short
uint16_t
2
signed int
int16_t
2
signed short 와 같다
unsigned int
uint16_t
2
un signed short 와 같다
signed long
int32_t
4
unsigned long
uint32_t
4
signed long long
int64_t
8
unsigned long long
uint64_t
8
실수형
float
4
double
4
float형과 같다.
논리형
boolean

1
avr-g++ 에서만 지원

여기서 주의할 것은  avr툴체인의 int형은 short형과 마찬가지로 2byte이고, double형은 float형과 마찬가지로 4byte라는 것이다.

IOCR에의 접근

 IOCR이 무엇인지는 이전 포스트에서 설명한 바가 있다. AVR프로그래밍에서 IOCR을 조작하는 것은 거의 필수적으로 행해지는 일이다. avr-gccs는 IOCR에 접근하는 편리한 방법을 제공하는데 예를 들어 PORTD와 관련된 레지스터(PORTD, DDRD, PIND)값을 읽거나 쓰려면 다음과 같이 하면 된다.

unsigned char byA = 0;
PORTD = byA;
DDRD = 0xFF;
byA = PIND;

이런 식으로 변수를 다루듯이 IOCR의 이름을 사용할 수 있는데 이러한 명령이 내려지면 컴파일러는 해당하는 IOCR의 주소를 참조하여 거기에 접근하는 일련의 명령어들을 자동으로 생성하게 된다.

 <io.h>를 인클루드할 때 자동으로 포함되는 <sfr_defs.h>에는 비트를 조작하는 매크로가 다음과 같이 정의되어 있다.
#define _BV(bit) (1 << (bit))
이 매크로를 이용하면 IOCR의 특정한 비트를 세트(1) 또는 리셋(0)시키는데 다음과 같이 사용할 수 있다.

PORTD |= _BV(0); //0번비트 세트
PORTD &= ~_BV(7); //7번비트 리셋

그리고 같은 헤더파일에 IOCR의 특정 비트가 세트(리셋)되어 있는지 조사하는 매크로가 다음과 같이 정의되어 있어서 조건문과 조합하여 사용할 수 있다.

#define bit_is_set(sfr,bit) (_SFR_BYTE(sfr)&_BV(bit))
#define bit_is_clear(sfr,bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

또한, IOCR의 특정 비트가 세트(리셋)될 때까지 기다리는 매크로도 다음과 같이 정의되어 있다.
#define loop_until_bit_is_set(sfr, bit)
                  do {} while (bit_is_clear(sfr, bit))
#define loop_until_bit_is_clear(sfr, bit)
                  do {} while (bit_is_set(sfr, bit))

이러한 매크로 함수를 이용하면 어떤 특정한 비트가 세트(리셋)될 때까지 대기해야 되는 경우에 편리하게 사용할 수 있다.


2015년 5월 30일 토요일

파이썬 내장 함수 (4) 연산을 수행하는 내장 함수들

 다음 표는 산술/논리 연산에 관련된 내장 함수들이다.

[표 1] 산술/논리 연산에 관련된 내장 함수들
hex(n)
oct(n)
bin(n)
정수 n의 16진수 값을 구해서 ‘문자열’로 반환한다.
정수 n의 8진수 값을 구해서 ‘문자열’로 반환한다.
정수 n의 2진수 값을 구해서 ‘문자열’로 반환한다.
abs(n)
절대값을 구한다. 복소수의 경우 크기를 구한다.
pow(x,y[,z])
거듭제곱을 구한다. pow(x,y)은 x**y 와 같다.
divmod(a,b)
a를 b로 나눈 (몫, 나머지)를 구한다. 튜플 반환.
all(iterable)
any(iterable)
iterable 의 모든 요소가 True 일 경우 True를 반환.
iterable 의 하나 이상의  요소가 True 일 경우 True를 반환.
max(iterable)
max(arg1, arg2, …)
최대값을 구한다.
min(iterable)
min(arg1, arg2, …)
최소값을 구한다.
round()
반올림을 한다.

hex(), oct(), bin() 함수는 각각 ‘0x’, ‘0o’, ‘0b’ 로 시작하는 ‘문자열’로 결과를 반한한다. 이 문자열을 파이썬 값으로 변환하려면 eval()함수를 이용하면 된다.


파이썬 내장 함수 (3) 열거형의 정보를 얻는 내장 함수들

 다음은 열거형(sequence)의 정보를 얻는 내장 함수들이다.

[표 1] 열거형의 정보를 얻는 내장 함수들
함수명
기능
len(seq)
시퀀스형을 받아서 그 길이를 반환한다.
iter(obj [,sentinel] )
next(iterator)
객체의 이터레이터(iterator)를 반환한다.
이터레이터의 현재 요소를 반환하고 포인터를 하나 넘긴다.
enumerate(iterable, start=0)
이터러블에서 enumerate 형을 반환한다.
sorted(iterable[,key][,reverse])
정렬된 *리스트*를 반환
reversed(seq)
역순으로 된 *iterator*를 반환한다.
filter(func, iterable)
iterable의 각 요소 중 func()의 반환값이 참인 것만을 묶어서 이터레이터로 반환.
map(func, iterable)
iterable의 각 요소를 func()의 반환값으로 매핑해서  이터레이터로 반환.

iter()은 seq형으로부터 이터레이터를 반환하는 함수이다. next()는 이터레이터의 현재 요소를 반환하고 이터레이터의 포인터를 그 다음 요소로 넘기는 함수이다.

enumerate()은 시퀀스로부터 enumarate형을 반환한다. 이것은 인덱스와 해당 값의 튜플을 반환하는 이터레이터를 가진다.

>>> seasons = ['spring','summer','fall','winter']
>>> list(enumerate(seasons))
[(0, 'spring'), (1, 'summer'), (2, 'fall'), (3, 'winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'spring'), (2, 'summer'), (3, 'fall'), (4, 'winter')]

보통은 for 문과 같이 사용되어서 반복문 안에서 이터러블의 요소값 뿐만 아니라 그 인덱스 정보도 필요할 경우 편리하게 사용할 수 있다.

>>> seasons=['spring','summer','fall','winter']
>>> for i,v in enumerate(seasons):
 …:    print("%s:%s"%(i,v))
  
0:spring
1:summer
2:fall
3:winter

filter(func, iterable)는 함수와 이터러블을 입력으로 받아서 이터러블의 요소가 하나씩 함수에 인수로 전달될 때, 참을 반환시키는 것만을 따로 모아서 이터레이터로 반환하는 함수이다.

 다음 예를 살펴보자.

def positive(l):
   result = []
   for i in l:
       if i > 0:
     result.append(i)
   return result
>>> print(positive([1,-3,2,0,-5,6]))
[1, 2, 6]

위의 positive함수는 리스트를 입력값으로 받아서 각각의 요소를 판별해 양수값만 따로 리스트에 모아 그 결과값을 돌려주는 함수이다.

 filter()함수를 이용하면 아래와 같이 똑같은 일을 동일하게 구현할 수 있다.

>>> def positive(x):
…      return x > 0
>>> print(list(filter(positive, [1,-3,2,0,-5,6])))
[1, 2, 6]

filter() 함수는 첫 번째 인수로 함수명을, 두 번째 인수로는 그 함수에 차례로 들어갈 이터러블(리스트, 터플, 문자열 등)을 받는다. filter 함수는 두 번째 인수인 이터러블의 각 요소들이 함수에 들어갔을 때 리턴값이 참인 것만을 이터레이터로 묶어서 돌려준다. 위의 예에서는 1, 2, 6 만이 양수로 x > 0 이라는 문장이 참이 되므로 [1, 2, 6]이라는 결과 값을 돌려주게 된다.

익명함수(lambda)를 쓰면 더욱 간편하게 쓸 수 있다.

>>> list(filter(lambda x: x > 0, [1,-3,2,0,-5,6]))
[1, 2, 6]

 filter()와 유사한 map() 함수가 있다. 이것은 함수와 이터러블을 입력으로 받아서 각각의 요소가 함수의 입력으로 들어간 다음 나오는 출력값을 묶어서 이터레이터로 돌려주는 함수이다. 만약 어떠 리스트의 모든 요소의 제곱값을 갖는 새로운 리스트를 만들고 싶다면 다음과 같이 하면 된다.

>>> a = [2, 3, 4, 7, 8, 10]
>>> a2 = list(map(lambda x:x**2, a))
[4,9,16,49,64,100]

파이썬 2.7은 filter()와 map()의 결과가 리스트이므로 위 예에서 list함수를 이용하여 리스트로 변환하지 않아도 된다. 파이썬 3.x에서는 이들 함수의 반환값이 리스트가 아닌 반복형(iterable)이므로 이것을 리스트로 만들기 위해서는 list()함수를 명시적으로 사용해야 한다.