[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>()); //내림차순 정렬

윈도우 소켓 프로그래밍(TCP)

카테고리 없음 2014. 2. 5. 07:35

소켓을 생성할때는 라이브러리에서 제공하는 소켓생성 구조체를 사용합니다. SOCKET 구조체는 주소,

소켓타입 프로토콜 등을 사용자가 직접 지정해 주어야 합니다.

 

생성후 사용자가 요청한 프로토콜을 이용하여 통신할수 있도록 내부적으로 리소스를 할당해, 접근시 핸들값

(SOCKET 타입, 32비트 정수)의 디스크립터를 리턴합니다. 프로토콜시 자주 이용하는 것은 TCP, UDP입니다.(AF_INET)

 

소켓통신이 끝나면 리소스를 반환해야 합니다. 쉽게 말하면 메모리를 할당한뒤 free하는것가 같습니다.

소켓 리소스 제거는 closesocket() 를 사용해 소켓 리소스를 제거합니다.


TCP서버, 클라이언트는 다음과 같은 순서로 소켓 함수를 호출합니다.

클라이언트는 서버와 달리 bind()함수를 호출하지 않습니다. Bind()함수 없이 connect()함수를 호출하면

OS는 자동적으로 지역 IP주소와 포트번호를 설정합니다.

 

- Socket : 소켓생성

- Connect() : 서버에 접속 요청

- Send(), recv() : 데이터 전송, 수신 함수로 서버/클라이언트 와 통신을 수행합니다.

- Closesocket() : 소켓을 종료합니다.

 

Connect()함수는 서버에게 접속하여 TCP 프로토콜 수준의 연결을 설정합니다.

s: 서버와 통신하기 위해 만든 소켓, name : 서버 주소를 초기화 한 소켓 구조체 변수의 주소값

 namelen : 소켓 구조체 변수의 길이



SOCKADDR_IN serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("128, 0, 0, 1");
int retval = connect(sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
if(retval == SOCKET_ERROR)
err_quit("connect()");

데이터 전송은 Send()함수를 이용합니다.

데이터를 송신 버퍼에 복사함으로 프로토콜에 의해 데이터가 전송 되도록 합니다.

 s : 통신할 대상과 연결된 소켓, buf : 보낼 데이터를 담고 있는 어플리케이션 버퍼의 주소

 len : 보낼 데이터 크기, Flags : send() 함수의 동작을 바꾸는 옵션(대부분 0을 사용)

 

데이터 수신 함수는 recv()함수를 사용합니다.

수신 버퍼에 도착한 데이터를 어플리케이션의 버퍼로 복사합니다.

s : 통신할 대상과 연결된 소켓, buf : 받은 데이터를 저장할 어플리케이션 버퍼의 주소, len : 수신 버퍼로 부터 복사할 최대 크기

 flags : recv()함수의 동작을 바꾸는 옵션(대부분 0을 사용)

recv()함수 사용시 주의점은 TCP메시지 경계를 구분하지 않기 때문에, 세번째 인자인 len으로 지정한 크기보다

작은 데이터가 어플리케이션 버퍼로 복사될수 있습니다. 따라서 자신이 받을 데이터의 크기를 알고 있다면,

해당 크기만큼 받을때 recv() 함수를 여러번 호출해야 합니다.

 

어플리케이션 프로토콜과의 메세지 설계를 할때 경계 구분 세가지 방법을 소개합니다.

송신자 입장에서는

1. 항상 고정길이 데이터를 보냄

2. 경계 구분을 위해 특별한 표시(eor : End of Record)

3. 보낼 데이터 길이를 고정 길이 데이터로 보낸후, 가변 길이 데이터를 이어서 송신(헤더 추가)

 

수신자 입장에서는

1. 항상 고정 길이 데이터를 수신

2. EOR이 나올때 까지 데이터를 읽은 후 처리

3. 고정 길이 데이터를 읽어 뒤 따라올 데이터의 길이를 알아냄, 이 길이만큼 데이터를 읽어 처리(헤더를 읽고 처리)

가장 많이 사용되는 방법은 3번 입니다.

 

 

소켓 프로그래밍

카테고리 없음 2014. 2. 5. 07:12

소켓은 네트워크를 통한 입/출력을 하기 위해 사용자에게 필요수단을 제공하는 응용 프로토콜 인터페이스를 말합니다.

네트워크 입출력을 하기 위해서는 프로토콜, 소스 IP주소, 소스 포트 번호, 목적지 IP주소, 목적지 포트번호 총 5가지의

요소가 필요합니다.

 

C/C++에서 파일 입출력을 통해 파일을 open, read, write하는것과 동일한 방식으로 socket을 생성해 recv(받기),

send(보내기)등의 작업을 할수 있습니다.

 

소켓은 네트워크 인터페이스 층면에서 어플리케이션 층과 TCP/UDP층 사이에 소켓 인터페이스 계층이 존재하여

두 계층을 서로 연결해주는 다리 역활을 합니다.

윈도우 상에서의 소켓 프로그래밍은 윈도우에서 지원하는 Winsock을 사용하여 소켓프로그래밍을 작성합니다.

상당부분 BSD계열 유닉스 소켓을 참고로 설계되었기 때문에 많은 부분이 리눅스 기반 소켓과 유사합니다.

윈도우 소켓을 사용하려면

1. Winsock2.h 헤더파일을 포함합니다.

2. Ws2_32.lib 라이브러리를 링크합니다.

3. 윈도우 소켓 사용을 위한 라이브러리를 참조해 소켓생성, 전송, 수신 등을 사용해 소켓 통신을 합니다.

 

 

Ws2_32.lib 라이브러리를 링크할시,

와 같이 파일에 직접 추가하거나

프로젝트 속성 -> 구성 속성 -> 링커 -> 입력 -> 추가종속성 란에 아래 그림과 같이 입력해 주면 됩니다.

 

 

네트워크 프로그래밍에서는 여러 원인으로 인해 오류가 발생하고, 오류 발생 확률이 높기 때문에 오류처리코드를

작성해 각 오류에 대해 대응(예외)하는 부분이 필요합니다. 각각의 함수 리턴값을 이용하여 오류 목록을 확인하고

그에 대해 적절히 처리될수 있도록 작성되어야 합니다. 예)WSAStartup()

사용 예는 아래 사진과 같습니다.

 

 

네트워크 개요

카테고리 없음 2014. 2. 3. 16:56

네트워크란 각 호스트(End System)들을 연결하는 하나의 단일 시스템을 의미합니다.

네트워크는 원거리에 있는 사용자 간의 원활하고 빠른 의사소통을 위해 활용됩니다.

 

각각의 네트워크는 프로토콜(서로다른 두개의 시스템이 통신하기 위한 약속, 규약)로 상호작용(의사소통)합니다.

인터넷 상에서 여러개의 네트워크가 존재하며, 각각의 네트워크를 연결하기 위한 장치가 필요할 것입니다.

또한 각각의 네트워크가 정해진 규율 없이 따로 공존하면 여러개의 네트워크를 연결할 방법이 없을것입니다.

따라서 OSI 표준 7개 층을 기반(이러한 형태로 네트워크 장비를 설치, 구성하자는 약속)으로 구성되어 있습니다.

아래의 그림은 OSI 7계층을 나타낸 그림입니다.

 

 

이와 별개로 인터넷의 핵심 프로토콜인 TCP와 IP가 존재합니다. 각각의 애플리케이션은(종단시스템)은 TCP/IP프로토콜을 이용해 서로 상호작용 합니다.

TCP/IP프로토콜은 위 그림의 OSI 7계층에 비해 조금 간소화된 4계층으로 구성되어 있습니다.

네트워크 액세스 계층에서는 물리적 네트워크를 통한 실제적인 데이터를 전송하는 역활을 담당합니다. 디바이스 드라이버와 네트워크 하드웨어으 결합으로 물리주소(physical address)를 표현합니다. 인터넷 계층에서는 전송계층이 내려보낸 데이터를 IP주로와 라우팅(경로설정)을 이용하여 종단 시스템까지 전달하는 역할을 하며, 전송계층에서는 최종적인 통신 목적지(프로세스)를 지정하고, 오류를 검사해 수정해 전송하는 역활을 하고 있습니다. 마지막으로 어플리케이션 계층에서는 다양한 어플리케이션 서비스를 제공하는 역활을 합니다.

 

각각의 프로토콜은 제어정보(IP주소, 포트번호, 오류체크 코드등)을 데이터에 추가하여 전송합니다. 각각의 계층에 대한 정보를 데이터에 헤더부분을 추가해 각각의 계층별 정보를 담습니다. 송신측에서는 헤더를 추가하고, 수신측에서는 헤더를 해독해 데이터의 용도 및 형태등을 파악합니다.

 

 

클라이언트와 서버는 서로상호작용하며 클라이언트가 서버에 접속해 정보를 요청하면 서버가 요청 정보를 처리하는 방식으로 구성되어 있습니다.

 각각의 서버는 클라이언트들에게 정보(서비스)를 제공합니다. 하나의 서버와 클라이언트가 1:1(peer to peer)로 연결될수도 있고, 1:n방식으로 하나의

서버에 다수의 클라이언트가 접속할수 있는 방식도 있습니다.

 

안드로이드 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