비트 연산자

프로그래밍/C/C++ 2014. 2. 12. 14:17

비트 연산자의 필요성

8개의 LED조명을 제어하기 위한 프로그램을 생성한다고 할때

  enum {LED0 = 0, LED1, LED2, LED3, LED4, LED5, LED6, LED7};

  enum {LED_OFF = 0, LED_ON = 1};

  char mmio[8] = {0, }; // 8개의 배열을 만든뒤

  mmio[LED1] = LED_ON; //LED1의 조명 ON

  mmio[LED3] = LED_OFF; //LED3의 조명 OFF 

로 조명을 제어 할수 있습니다.

하지만 이 부분에서의 문제점은 총 8개의 비트(0, 1)만으로 충분하지만, 사용 메모리 크기는 8비트 * 8개(64비트)

공간을 할당하여 사용하고 있다는 것입니다. 각 char형의 1비트 밖에 사용하지 않고 7비트트 * 8개(56비트)의

공간이 낭비되고있는 문제점입니다.

 

이 문제를 해결하기 위해서는 8비트를 사용하여 8개의 LED를 제어하는 방법을 사용하여야합니다.

char 형의 문자형을 하나 사용하여 8비트(1바이트) 공간을 사용하는 방법을 소개합니다.

이 문제를 해결하기 위해서는 비트연산자를 활용해 각 비트의 연산이 필요합니다.

 

1. AND연산

 

 

AND연산은 위 그림과 같이 1과 1이 입력될때만 1이 출력되고 그 외의 연산은 0이 출력되는 게이트를 말합니다.

 

2. OR연산

 

 

 

OR연산은 위 그림과 같이 0과 0이 입력될때만 0이 출력되고 그 외의 연산은 1이 출력되는 게이트를 말합니다.

(입력 게이트로 하나라도 1이 포함되면 1이 출력)

 

3. NOT연산

NOT연산은 위 그림과 같이 0을 NOT연산자를 취하면 1이 출력되고, 1을 NOT연산자를 취하면 0이 출력됩니다.(반대로 출력)

 

4. SHIFT 연산

  데이터 << 이동할 비트 수

 데이터 >> 이동할 비트 수

 

SHIFT연산은 메모리 상을 비트 단위로 이동하는 것을 말합니다. 데이터를 비트 단위로 좌, 우로 이동하는

기능을 합니다.

규칙1. 특정 비트를 설정하려면 OR연산자를 사용합니다.

 char mmio = 0; // 0000 0000

규칙2. 특정 비트를 검색하려면 AND연산자를 활용합니다.

규칙3. 특정 비트를 초기화하려면 &연산자와 비트 반전 연산자(~, NOT)을 사용합니다.

 

 

 

 

'프로그래밍 > C/C++' 카테고리의 다른 글

C++ 파일 입출력  (0) 2014.02.24
함수 주요 형태(_stdcall, _cdecl, _fastcall)  (0) 2014.02.24
함수 포인터  (0) 2014.02.12
[STL]컨테이너 선택  (0) 2014.02.09
[STL] 제네릭 알고리즘 Generic Algorithm  (0) 2014.02.09

함수 포인터

프로그래밍/C/C++ 2014. 2. 12. 04:22

우리가 알고있는 일반적인

함수의 선언은 리턴타입 (함수명 ([파라미, ...])) 형식을 갖습니다.

함수의 포인터 선언 방법은 함수의 심볼은 반드시 리턴 타입과 매개변수 사이에 위치해야 합니다.

함수의 포인터 선언은 리턴타입 (*포인터명) ([파라미터, ...]) 형식을 갖습니다.(괄호 필수,

미괄호시 파라미터 부터 해석해서 리턴타입을 리턴타입을 포인터로 리턴하는 함수로 인식합니다.)

함수호출, 함수의 포인터 호출 방법은 아래와 같습니다.

 


하지만 이러한 방법은 매우 복잡합니다. 함수의 포인터 호출 방법을 아무도 사용하지 않을 것입니다.

하지만 전처리기 #define문을 사용해 함수의 포인터를 간단히 치환할수 있습니다.

 

출력 결과

 called foo(10);

 called foo(10);

 called foo(10);

 called foo(10);

 

위의 주석으로 처리된 함수 포인터는 #define선언된 함수의 포인터 타입으로 변경되어 간단히 사용할수 있습니다.

[STL]컨테이너 선택

프로그래밍/C/C++ 2014. 2. 9. 14:12

컬렉션 내의 값들을 어떤 방식으로 접근하는가에 따라 컨테이너 선택이 달라져야 합니다.

 

▶ 컬렉션 내에 임의 접근이 자주 필요할시

    vector와 deque를 사용하고, 순차접근만으로 충분하다면 다른 컨테이너를 써도 무방합니다.

 

▶ 컬렉션 내의 값들을 순서 매길 필요가 있을시

    Set을 사용하는게 좋습니다. 매순간 순서가 필요없고 특정 순간에 필요하다면 list혹은 vector에 값을 대입하고 필요시

    정렬하는 방법을 사용하는 것이 좋습니다.

 

▶ 데이터 구조 내에서 유지되는 값들의 순서가 필요할시

     stack이나 list를 선택하는것이 좋습니다.

 

▶ 실행중에 데이터 구조가 광범위 하게 변활시

    list와 set을 선택하는 것이 좋습니다.  vector, deque는 컬렉션으로 부터 원소들을 제거한 뒤에 데이터 이동이

    이루어지기 때문에 부하의 원인이 됩니다.

 

▶ 어떤 값이 컬렉션 내에 포함되어 있는지 확인하는 빈도가 높으시

    set이나 map을 선택하는 것이 좋습니다.

 

▶ 컬렉션에 대해 인덱싱이 필요할시

    vector, deque를 사용하고, 키 값이 어떤 순서가 있는 데이터 형이라면(문자, 문자열, 사용자 정의 데이터 타입)

    map을 사용합니다.

 

▶ 두개 이상의 수열을 하나로 합치는 일이 자주 발생할 경우

    set이나 list가 유용합니다. 어떤 것을 선택할지는 순서가 유지되는가의 여부에 따라 결정하는 것이 좋습니다.

 

▶ 컬렉션 중간에서 데이터 삽입, 삭제가 자주 이루어질시

    list가 최선의 선택이며, 앞쪽에서 삽입된다면, deque , list 끝에서 삽입과 삭제가 이루어진다면 stack, deque를 사용하는 것이 좋습니다.

'프로그래밍 > C/C++' 카테고리의 다른 글

비트 연산자  (0) 2014.02.12
함수 포인터  (0) 2014.02.12
[STL] 제네릭 알고리즘 Generic Algorithm  (0) 2014.02.09
[STL] 정렬 컨테이너1 (set, multiset, map, multimap)  (0) 2014.02.09
[STL] 제네릭(generic) 기초 정리  (0) 2014.02.09

[STL] 제네릭 알고리즘 Generic Algorithm

프로그래밍/C/C++ 2014. 2. 9. 04:29

Generic Algorithm이란 컨테이너에 대해서 적용할 수 있는 기능들을 체계적으로 정리해놓은 함수를 말합니다. 일반적이

기 때문에, 특정 컨테이너에 종속된 것이 아니라 모든 컨테이너에서 사용할수 있습니다. 알고리즘 함수들은 특정 컨테이

너의 멤버 함수가 아닌 일반 전역 함수로 작성되어 있습니다.

 

  ☞ find 예제

 

  ☞ copy 예제

 

  ☞ sort 예제

  ☞ reverse 예제

 reverse_copy를 사용하면, reverse대상은 그대로 두고 복사시킬수 있습니다.

 → reverse_copy(vec1.begin(), vec1.end(), 참조 객체 );

 

 

[STL] 정렬 컨테이너1 (set, multiset, map, multimap)

프로그래밍/C/C++ 2014. 2. 9. 04:01

▶ STL-Set, Multiset

 Set은 key만을 저장하는 자료구조 입니다.

 Set은 중복되지 않은 key를 저장합니다.(multiset은 중복되지 않은 key를 저장-중복 허용)

 Set에 값을 한번 넣어보는것 만으로 중복된 값이 있는지 찾을수 있습니다.

 

  ☞ Set함수의 생성

    Set<int> a; //오름 차순 정렬

    Set<int, greater<int>> a; //내림차순으로 정렬

    Set<int> a(List.begin(), List.end()); //List를 미리 넣음

    Set<int, greater<int>> a(List.begin(), List.end());

 insert문을 통해 해당 타입에 맞는 값을 넣을수 있습니다.

 find문을 통해 특정 값을 인자로 취해서 set내에 값이 존재하면 그 값의 위치를 반복자를 리턴합니다.

 (없을시 end of set을 리턴)

 

▶ STL-Map, Multimap

 Map은 key와 value 정보를 가지고 있는 자료구조 입니다.

 Multimap은 같은 key로 인덱싱 되는 여러개의 다른 원소를 허용합니다.

 

 Map은 vector나 deque와 같이 인덱싱이 가능합니다.

    map<int, int> myMap;

    myMap.insert(map<int, int>::value_type(5, 7);

    myMap[5] = 7;

    cout << myMap[5];  // -> 7

 Map과 deque, vector 의 차이는 key값이 꼭 숫자일 필요가 없다는 것입니다.

 또한 Map은 정렬된 데이터의 구조를 가지고 있습니다(Tree, hash)

 set과 마찬가지로 insert를 통해 해당 타입에 맞는 값을 넣을수 있습니다.(인덱싱)

 find문을 통해 특정 값을 인자로 취해서 map내에 값이 존재한다면 그 위치를 나타내는 반복자를 리턴합니다.

 (없을시에는 end에 해당하는 반복자를 리턴)

 

 

[STL] 제네릭(generic) 기초 정리

프로그래밍/C/C++ 2014. 2. 9. 03:24

 제네릭이란 무엇인가?

 네이버에서 Generic 이라는 단어를 검색하면

 [문법] 총칭적인

 the generic singular 총칭 단수 <보기 : The cow is an animal>

이라고 검색됩니다. 해석하면 "암소는 동물이다"  소는 분명히 고양이나 개와는 다르지만, "동물"이라는 것으로

총칭할수 있습니다. 그렇다면 왜 총칭하는 것일까요? 어떤 프로그램을 만든다고 할때 어떤 기능이 되야 하는지 고민한뒤

클래스, 맴버함수, 맴버변수등을 작성합니다. 여기서 사용하는 변수의 타입을 총칭화 하면 장점이 있습니다.

1. 템플릿을 이용하면 총칭화된 타입을 사용하는 클래스와 함수를 만들수 있다.

2. 템플릿을 사용하면 타입에 제약을 받지 않은 로직을 기술할수 있다.

그리고 제네릭 프로그래밍을 하기 위해서는 템플릿이 꼭 필요합니다. 그런데 STL은 무엇으로 만들어 졌을까요?

템플릿으로 만들어 졌습니다. STL은 제네릭 프로그램으로 만들어진 가장 대표적인 예중 하나입니다.

두개의 function함수가 있지만, 타입에 따라 다른 함수가 호출됨을 확인할수 있습니다.

첫번째 function함수는 호출1을 출력하고, 두번째 function함수는 호출2를 출력합니다. 

   

         

 

▶ 제네릭을 사용해 펙토리얼 연산

        

 

▶ 제네릭을 사용한 이진수 십진수 변환

     

[STL]기초, 컨테이너(vector, deque, list)

프로그래밍/C/C++ 2014. 2. 9. 03:06

STL이란 무엇인가?

STL이란 C++언어의 "표준 템플릿 라이브러리" Standard Template Library 약자입니다. STL을 간단하
게 말하자면 일반적으로 많이 사용되는 자료구조와 알고리즘을 모은 라이브러리입니다.

 

 

STL은 대부분 알고있는 자료구조와 알고리즘을 제공합니다.

 

컨테이너(Container) 에서는 시퀀스 컨테이너(sequence container)와 정렬 연관 컨테이너가 있습니다.

시퀀스 컨테이너는 Vector, List, Deque 가 있고, 정렬 연관 컨테이너는 Set, Multiset, Map, Multimap이 있습니다.

시퀀스 컨테이너는 index들의 동일한 형식의 객체들이 선형적으로 연결되어 있습니다.

 

 

▶ 시퀀스 컨테이너의 멤버함수

assign

특정 원소로 채운다

clear

모든 원소를 지운다 

swap

두개의 컨테이너 원소를  바꾼다

empth

아무것도 없으면 true 반환 

begin

첫번째 원소의 반복자 반환 

front 

첫 번째 원소의 참조를 반환 

end

마지막 원소의 반복자 반환 

 back

마지막 원소의 참조를 반환 

 rbegin

역방향의 첫번째 원소 반복자 반환 

 rend

역방향의 마지막 원소 다음의 반복자를 반환 

 size

원소의 개수를 반환 

 reserve

지정된 크기만큼의 공간을 확보 

 resize

컨테이너가 담을수 있는 개수를 지정 

push_back 

마지막에 원소를 추가 

 pop_back

마지막 원소를 삭제 

 insert

특정 위치에 원소를 삽입 

 erase

특정 위치의 원소나 지정범위 삭제 

 

▶ 시퀀스 컨테이너의 선언과 초기화

디폴트 생성자 : deque<int>myD;

원소의 개수를 지정 : deque<int>myD(10);

원소의 개수와 값을 초기화 : deque<int>myD(10, 3);

 

▶ STL-Vector

 선형 구조의 가변 배열 방식입니다.

 동일한 형식의 객체를 계속 넣을수 있습니다.

 요소의 개수에 따라 자동으로 메모리 관리를 합니다.

 

☞ vector 예제

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

▶ STL-Deque

 deque는 double ended queue의 줄임말입니다.

 두개의 key를 두어 앞과 뒤를 관리하여, FIFO와 LIFO를 모두 사용할수 있습니다.

 

Vector와 Deque의 단점은 중간의 삽입과 삭제를 수행시 데이터 이동이 있다는 것입니다.(일종의 행렬)

    삽입과 제거가 빈번한 알고리즘에서는 벡터보다는 리스트를 쓰는것이 좋습니다.

 

▶ STL-List

 각 노드는 링크(포인터)로 연결되어 있습니다.

 iterator(반복자)를 사용해 탐색이 가능합니다.

 ☞ List의 단점은 중간에 원소에 접근이 불가능하고, 탐색시 처음부터 검색해야 한다는 점입니다. 

     탐색이 많은 경우 List보다는 Vector혹은 Deque를 쓰는것이 좋습니다.

 

   <List의 탐색>

     List<int>::iterator itr;

     for(itr = myList.begin(); itr != myList.end(); itr++)

     cout << *itr;

 

 List는 sort(정렬)을 지원합니다. [qsort사용불가]

     List.sort(); //오름차순 정렬

     List.sort(greater<T>()); //내림차순 정렬

안드로이드 NDK 로그 출력하기

안드로이드 개발을 하다보면 답답한 경우가 많습니다.(망할 디버깅....)

NDK환경에서 log.d와 동일하게 로그 출력할수 있는 방법을 소개합니다.

 

이클립스 패키지 폴더에서 jni폴더에 Android.mk파일을 보면

위와 같이 LOCAL_LDLIBS += -llog 를 추가합니다.

 

그다음 log 출력메세지를 작성할 cpp파일에

#include <android/log.h> 를 추가합니다.

 

마지막으로 로그 출력을 위해

__android_log_print(ANDROID_LOG_DEBUG, "태그 이름", "출력 메세지");

를 작성하면 아래와 같이 이클립스의 LogCat화면에 메세지가 출력됩니다.

 

※__android_log_print()의 첫번째 변수값인 옵션에는

    ANDROID_LOG_DEFAULT

    ANDROID_LOG_UNKNOWN

    ANDROID_LOG_VERBOSE

    ANDROID_LOG_DEBUG

    ANDROID_LOG_INFO

    ANDROID_LOG_WARN

    ANDROID_LOG_ERROR

등을 사용하면 됩니다.

 

'프로그래밍 > 안드로이드' 카테고리의 다른 글

Android - DB 연동 기술 정리  (0) 2014.02.25
안드로이드 NDK 등 링크 정리  (0) 2014.02.24

pthread 함수정리

프로그래밍/C/C++ 2014. 1. 31. 19:39

안드로이드 NDK(리눅스 커널)에서 pthread를 지원한다고 한다.

단일 프로세스에서 동시에 여러작업을 하는것처럼 보여지기위해 스레드를 사용한다.

pthread API 함수를 쓰기 위해서 #include <pthread.h>를 해야한다.

또한 컴파일시 -lpthread 옵션 추가를 해주어야 한다.(미추가시 컴파일 오류 혹은 스레드가 정상으로 작동하지 않음)

 

pthread_t  :  pthread의 자료형을 나타낸다.

 

1. pthread 생성 

int pthread_create(pthread_t *th_id, const pthread_attr_t *attr, void *함수명, void *arg)

 첫번째 인자 : pthread 식별자(thread가 생성되면 thread식별자 값이 주어진다.)

 두번째 인자 : pthread 속성(옵션), 기본적인 thread를 사용할경우 NULL로 설정

 세번째 인자 : pthread 분기함수, 반환값이 void* 타입이고 매개변수도 void* 으로 선언된 함수만 사용할수있다.

                     예) void *threadFunc(void *arg)

 네번째 인자 : 분기할 함수로 넘겨줄 인자값. 어떤 자료형을 넘겨줄 지 모르기 때문에 void 형으로 넘겨주고, 상황에 맞게

                     분기하는 함수 내에서 원래의 자료형으로 캐스팅해서 사용하면 된다.

 ▶ 성공적으로 pthread가 생성된 경우 0을 리턴

 

2. pthread 옵션

int pthread_join(pthread_t th_id, void **thread_return)

 - 특정 pthread가 종료될 때까지 기다리다가 pthread가 종료시 자원 해제

 첫번째 인자 : pthread를 기다릴 id

 두번째 인자 : pthread의 return값(포인터로 받아와야함)

 

int pthread_detach(pthread_t th_id)

 - th_id 식별자를 가지는 pthread가 부모 pthread로 부터 독립한다.

   (pthread_join(..)이 없어도 종료시 자동으로 리소스가  해제됨)

 

void pthread_exit(void *ret_value)

 - 현재 실행중인 thread를 종료시킨다. pthread_exit가 호출되면 cleanup handler가 호출되며 리소스 해제하는 일을 수행

 

void pthread_cleanup_push(void *함수명, void *arg)

 - pthread(exit)가 호출될때 호출된 handler를 정하는 함수(자원 해제용이나 mutex lock해제를 위한 용도로 사용)

 

void pthread_cleanup_pop(int exec)

 - 설정된 cleanup handler를 제거하기 위해서 사용하는 함수(exec 값이 0일 경우 바로 cleanup handler 제거하고 그 외

    의 값을 가질 경우 cleanup handler를 한번 실행한 후 제거한다)

 

pthread_t pthread_self()

 - 현재 동작중인 pthread의 식별자를 리턴.

윈도우 스레드(win thread) - 세마포어예제

프로그래밍/C/C++ 2014. 1. 29. 20:25