반응형

cpp numerics library

수치 라이브러리


일반 수학 함수들은 <cmath> 헤더에 선언되어 있고 std::sin, std::sqrt 등으로 사용할 수 있다. 네임스페이스는 std를 사용.

복소수는 <complex> 헤더, 알고리즘은 <numeric> 헤더를 사용한다.


++Common mathematical functions

+abs(value)    ; 절대값. 데이터 타입은 int, long, long long, float을 지원한다.

타입을 명시한 함수도 있다. fabs(float), labs(long) , llabs(long long) (C++11)


+div(x, y)    ; 몫과 나머지를 구한다.

std::div_t div(int x, int y) ; 데이터 타입은 long, long long도 지원. ldiv(), lldiv() 사용.

struct div_t { int quot; int rem; }    ; 리턴값인 div_t 타입은 몫과 나머지 필드가 있다.

itoa 함수 구현 예제

std::string itoa(int n, int base) {

   std::string buf ;

   std::div_t dv{} ; 

   dv.quot = n ;

   do {

      dv = std::div(dv.quot, base) ;

      buf += "0123456789abcdef"[std::abs(dv.rem)] ;

   } while (dv.quot) ;

   if (n<0) buf +='-' ;

   return { buf.rbegin(), buf.rend() } ;

}


+큰값, 작은값

max(a,b), fmax(a,b) 등. max는 int, long, long long, fmax는 float, double, long double

min(a,b), fmin(a,b) 등


+오차

fdim(a,b) ; a-b 값이 0보다 크면 a-b값을 리턴. 그렇지 않으면 0리턴. (dim 은 없다. fdim 사용 )


+지수, 로그

exp(arg)    ; 자연상수 e의 arg승수 값. e^arg.  타입은 float, double, long double

exp2(arg)    ; 2^arg  (C++11)

log (arg)   ;   ln(arg) 자연로그

log10(arg)  ; 밑이 10인 로그

pow(x, y)    ; x^y 

sqrt(x)    ; root(x)


+삼각함수

sin, cos, tan, asin, acos, atan

const double pi = std::acos(-1) ;

std::sin( pi/6 )    --> 0.5

std::sin( pi/2 )    --> 1

2 * std::atan( INFINITY )    --> 3.14159 (pi)


atan2(y, x)    ; atan ( y/x ),  -pi~pi 범위의 리턴값


hyperbolic 삼각함수 ; sinh, cosh, tanh, asinh, acosh, atanh 

sinh(arg) ;   ( e^arg - e^-arg ) / 2

cosh(arg) ;  ( e^arg + e^-arg ) / 2

tanh(arg) ;  sinh / cosh


+ 가까운 정수

ceil ; 올림

floor ; 내림

round ; 반올림 (C++11)

float round(float arg) ; double round (double arg) ; ... long double 등.











'Develop > C&CPP' 카테고리의 다른 글

libcurl HTTP POST send 모듈/curl 커맨드 방식도 지원  (0) 2018.07.13
if or 비교시 어떤 식의 성공으로 진입했는지 구분  (0) 2018.07.13
Preprocessor  (0) 2018.06.20
deque  (0) 2018.06.13
stack / queue  (0) 2018.06.12
반응형

cpp preprocessor (전처리기)


전처리기는 소스코드를 컴파일 전단계 (translation phase)에서 처리된다. (런타임이 아니다.) 전처리가 된 후 컴파일러로 전달된다.


+지시어

#으로 시작한다.

키워드로는 define, undef, include, if, ifdef, ifndef, else, elif, endif, line, error, pragma 가 있다.

null 지시어로 #만 쓰는 것도 가능하다. (아무일도 안 함.)


+기능

전처리기는 소스 파일의 번역을 한다.

소스의 일부를 조건에 따라 컴파일할 수 있다. (#if, #ifdef, #ifndef, #else, #elif, #endif)

텍스트를 변경하는 매크로 기능을 한다. (텍스트를 붙이거나 식별자를 스트링으로 사용하는 등) (#define, #undef,  오퍼레이터로써 # , ## )

다른 파일들을 포함시킬 수 있다. (#include)

에러를 발생시킬 수 있다. (#error)

파일명과 라인 번호 정보를 알 수 있다. ( #line )

지정된 방식으로 작업을 한다. (#pragma)


+조건적 포함

#if [expression]

#ifdef [identifier]

#ifndef [identifier]

#elif [expression]

#else

#endif

조건에 따라 코드 블록이 수행된다.


#if, #elif 뒤에 나오는 expression은 상수적 표현을 의미한다. unary 연산자를 포함할 수 있고,  defined identifier 나  defined (identifier) 를 사용할 수 있다. 

expression의 값이 non-zero이면 해당 블록이 처리되고, 0이면 스킵된다.


#ifdef, #ifndef는 다음과 같다. (identifer가 매크로명으로 정의되었는지 검사한다.)

#if defined identifier

#if !defined identifier


#define ABCD 2

#include <iostream>

int main()

{

#ifdef ABCD

std::cout << "1: yes\n" ;

#else

std::cout << "1:no\n" ;

#endif


#ifndef ABCD

std::cout << "2:no1\n" ;

#elif ABCD==2

std::cout << "2.yes\n" ;

#else

std::cout << "2.no2\n" ;

#endif


#if !defined(DCCA) && (ABCD < 2*4-3)

std::cout << "3. yes\n" ;

#endif

}

모두 yes가 출력됨.



+텍스트 변경 매크로

#define identifier    replacement-list

#define identifier(parameters)    replacement-list

#define identifier(parameters, ...)    replacement-list    (C++11)

#define identifier(...)    replacement-list (C++11)

#undef identifier


#define은 지정한 식별자를 replacement-list로 변경해 준다.

객체같은 매크로 ; identifier를 replacement-list로 교체한다.

함수같은 매크로 ; 위와 같지만 추가적으로 파라미터를 사용한다.

variable arguments의 경우 __VA_ARGS__ identifier를 사용한다. 

__VA_OPT__(content)는 __VA_ARGS__가 비어 있지 않을 경우 확장된다.

#define F(...)  f(0 __VA_OPT__(,) __VA_ARGS__)

F(1,2,3) --> f(0, 1,2,3)

F()    --> f(0)


#define G(X, ...)    f(0, X __VA_OPT__(,) __VA_ARGS__ )

G(a,b,c) --> f(0, a,b,c)

G(a,) --> f(0, a)

G(a) --> f(0, a)


#define SDEF(sname, ...)    S sname __VA_OPT__(= {__VA_ARGS__} )

SDEF(foo);    --> S foo;

SDEF(x, 1,2,3);    -->  S x = {1,2,3};



오퍼레이터 #, ##

함수같은 매크로에서 replacement-list 내부에서 식별자 앞에 # 오퍼레이터를 붙이면 결과를 ""로 묶게 된다. 내부에 "가 있으면 \도 자동으로 추가된다.

 

#define showlist(...)    puts(#__VA_ARGS__)

showlist() ;     -->  puts("") ;

showlist(1,"x", int);     --> puts("1, \"x\", int") ;


repplacement-list 내부에 연속된 두 개의 식별자 사이에 ## 오펴레이터가 추가되면 파라미터들을 두 식별자로 바꾸게 된다. 이 작업은 스트링을 붙여서 인식하게 된다.

#define Func(x) Func ##x

Func(1)    --> Func1 

Func(2)    --> Func2



#include <iostream>


#define FUNC(name, val) int FUNC_##name() {  return val ; }

FUNC(aaa, 10)

FUNC(bbb, 20)

FUNC(ccc, 30)

int main() {

    std::cout << FUNC_aaa()  << std::endl ;

    std::cout << FUNC_bbb()  << std::endl ;

    std::cout << FUNC_ccc()  << std::endl ;

return 0 ;

}

10, 20, 30이 출력된다.

FUNC(aaa, 10)   -->   int FUNC_aaa() { return 10 ; } 

위와 같이 풀린다.


+ Predefined macro

__FILE__    ; 현재 소스 파일명으로 확장 (string)

__LINE__    ; 현재 라인 번호 (int)

__DATE__    ; 컴파일 날짜(translation date)  "Mmm dd yyyy"

__TIME__    ; 컴파일 시간 "hh:mm:ss"


  • 소스 파일 포함 ; include

#include <filename>

#include "filename"

해당 파일을 그 위치에 포함시킨다.

C, C++ 라이브러리는 표준 include디렉터리에서 불러들인다. (include 디렉터리는 컴파일 옵션으로 설정할 수 있다.) 

""로 지정하면 소스파일의 디렉터리에서 검색한다. 못찾으면 표준 include 디렉터리에서 찾는다.

nested된 include에 의해 반복될 경우를 막기위해 다음과 같이 한 번한 include되게 한다.

#ifndef _FOO_H_

#define _FOO_H_

// to do..

#endif

pragma를 지원하는 컴파일러에서 아래와 같이 사용하면 위 효과를 동일하게 할 수 있다.

#pragma once


  • 에러 지시

#error error_message

위 지시자를 만나면 에러 메시지를 출력한다.  컴파일 시점에서 발생한다.

#if !WINDOWS_XP && !WINDOWS_7

#error Please check your OS

#endif


  • 파일명과 줄번호 정보

#line lineno

#line lineno "filename"

다음 줄 라인 번호를 lineno로 변경한다. 매크로 __LINE__ 값이 바뀐다.

뒤에 파일명을 주면 __FILE__ 매크로인 파일명이 바뀐다.


#line 777 "test.cc"

assert(2+2==5) ;

위 소스를 컴파일 할 경우, test.cc:777 에서 assertion 에러가 발생한다.



'Develop > C&CPP' 카테고리의 다른 글

if or 비교시 어떤 식의 성공으로 진입했는지 구분  (0) 2018.07.13
Numerics library  (0) 2018.06.21
deque  (0) 2018.06.13
stack / queue  (0) 2018.06.12
cstring  (0) 2018.06.11
반응형

cpp deque

include <deque>

double ended queue . 입출구가 양쪽 끝에 달린 형태.


++Iterators

begin, end, rbegin, rend, cbegin, cend, crbegin, crend


++capacity

size, max_size, resize, empty, shrink_to_fit


++elements access

[], at, front, back


++modifiers

assign, push_back, push_front, pop_back, pop_front

insert, erase, swap, clear, emplace, emplace_front, emplace_back


ex)

std::deque<int> myq (2, 100) ;    // 100을 값으로 2개 노드 생성..  100,100

myq.push_front(200) ;    // 200,100,100

myq.push_front(300) ;    // 300,200,100,100

myq.push_back(99) ;    // 300, 200,100,100, 99

std::cout << myq.front() << '\n' ;    // 300

std::cout << myq.back() << '\n' ;  // 99

myq.pop_front() ;     // 200,100,100,99

myq.pop_back() ;    // 200,100,100

// 출력

for (std::deque<int>::iterator it=myq.begin(); it!=myq.end(); ++it) {

  std::cout<<' ' << *it ;

}


+insert

iterator insert(const_iterator pos, const value_type& val) ;    // 지정된 위치에 삽입.

iterator insert( ", size_type n, const vlaue_type &val) ;    // 지정된 위치에 해당 값을 n개 삽입. (fill)

iterator insert(", InputIterator first, last) ;    // 지정한 위치에 범위를 삽입.

iterator insert(", initializer_list<value_type> il) ;

리턴값은 새로 추가된 첫번째 엘리먼트의 위치


std::deque<int> myq ;

for (int i=1; i<6; i++) myq.push_back(i);    // 1 2 3 4 5

std::deque<int>::iterator it = myq.begin() ; // it point 1

++it ;    // next position ; it point 2

it = myq.insert(it, 10) ;        // 1 10 2 3 4 5

myq.insert(it, 2, 20);    // 1 20 20 10 2 3 4 5

+erase

지정된 위치 또는 범위를 삭제.

리턴값은 삭제된 범위에 처음 오게 될 요소의 위치.

myq.erase( myq.begin()+3) ;

myq.erase( myq.begin(), myq.begin()+3) ;




'Develop > C&CPP' 카테고리의 다른 글

Numerics library  (0) 2018.06.21
Preprocessor  (0) 2018.06.20
stack / queue  (0) 2018.06.12
cstring  (0) 2018.06.11
thread mutex  (0) 2018.06.10
반응형

cpp stack

include <stack>


LIFO로 디자인된 자료구조. push/pop


+ member functions

empty    ; 비었는지 테스트

size    ; 스택 엘리먼트 개수

top    ; 가장 위의 엘리먼트 접근

push    ; 삽입. (가장 위에 추가)

emplace(c++11) ; construct & push

pop    ; top(가장 위) 엘리먼트를 제거

swap(c++11) ; 다른 스택과 바꿈. 


+ex)

std::stack<int> st1 ;

st1.push(1) ;

st1.push(2) ;

st1.push(3) ;

st1.size()    // => size=3

st1.top()    // => 3

st1.pop()    // => size=2

st1.top()    // => 2

st1.empty()    // => false

while(  !st1.empty() ) {    // 일반적인 스택 데이터를 전부 하나씩 추출하는 방법.

std::cout << '  ' << st1.top() ;    // 최상위 노드 접근.

st1.pop() ;    // 최상위 노드 삭제.

}


+ swap ex)

std::stack<int> foo, bar ;

foo.push(10); foo.push(20); foo.push(30) ;

bar.push(11) ; bar.push(22) ;

foo.swap(bar) ;     // foo와 bar가 바뀜.

foo.size() ;    // 2

bar.size() ;    // 3




++ queue

FIFO 방식의 자료구조

include <queue>


+members

empty

size

front    ; 가장 앞 노드의 값

back    ; 가장 뒤 노드의 값

push ; 노드를 가장 뒤에 추가

emplace (c++11)

pop ; 가장 앞의 노드를 제거

swap (c++11)


ex)

std::queue<int> q1 ;

q1.push(1) ;

q1.push(2) ;

q1.push(3) ;

while( !q1.empty() ) {

std::cout << ' ' << q1.front() ;     // 가장 앞 노드값 출력

q1.pop()    ;    // 가장 앞 노드 제거.

}




'Develop > C&CPP' 카테고리의 다른 글

Preprocessor  (0) 2018.06.20
deque  (0) 2018.06.13
cstring  (0) 2018.06.11
thread mutex  (0) 2018.06.10
thread  (0) 2018.06.09
반응형

cpp cstring

c string and array


include <cstring>


+함수들

void * memcpy (void *dest, const void *src, size_t num) ; dest return.

void * memmove(void *dest, const void *src, size_t num)  ; memcpy와 유사하나 차이점은 dest와 src가 overlap이 되어도 된다. 따라서 성능상은 memcpy가 더 좋음. 그러나 overlap이 필요하면 memmove를 사용한다. 

char* strcpy(char *dest, const char *src) ; dest return. null 문자까지 복사.

char* strncpy(char *dest, const char *src, size_t num) ; num크기까지 복사한다. num전에 null문자가 있으면 null전까지 복사하고 나머지는 null로 패딩한다.  

char* strcat (char *dest, const char *src) ; src문자를 dest뒤에 붙인다. dest return.

char* strncat (char *dest, const char *src, size_t num) ; src의 num 크기만큼만 dest 뒤에 붙인다. 마지막에 null문자 추가. 

int memcmp (const void *ptr1, const void *ptr2, size_t num) ; 두 메모리 블록을 비교한다. strcmp와 다르게 null문자가 있어도 중간에 멈추지 않고 지정된 크기만큼  비교한다.  return ;  ptr1<ptr2 이면 <0,  ptr1>ptr2이면 >0 , ptr1=ptr2 이면 0.

int strcmp (const char *str1, const char *str2) ; 두 스트링을 비교한다. return ; <0, >0, 0

int strncmp(", ", size_t num) 

char * strchr( char *str, int ch) ; 스트링에서 지정한 문자를 찾아 위치를 리턴. 

char* strrchr (char *str, int ch) ; 스트링에서 지정한 문자를 뒤에서 부터 찾아 위치를 리턴.

char* strstr (char *str1, const char *str2) ; str1 스트링에서 str2 스트링을 찾아 위치를 리턴.

char* strtok (char *str, const char *delimeters) ; 스트링을 토크닝함. 딜리미터로 지정된 문자열 가운데 아무 문자나 맞으면 자른다. 다음 토큰 검색시에는 str을 NULL로 준다. 주의! thread-unsafe! . thread에서는 strtok_r() 사용.

void* memset (void *ptr, int val, size_num) ; 메모리 블록을 특정 값으로 초기화. ptr is returned.

size_t strlen(const char *str) ; 스트링 길이를 리턴.


+잘 안쓰는 함수

void * memchr(void *ptr, int val, size_num) ; 메모리 블록에서 지정된 값을 찾는다. return ; 처음 val이 발견된 주소. 없으면 null

size_t strcspn (const char *str1, const char *str2) ; str1에서 str2의 임의의 문자가 가장 먼저 나오는 곳 이전까지의 길이.  str2를 any delimeter로 보고 첫 번째 토큰의 길이.

char * strpbrk (char *str1, const char *str2) ; str2를 any delimeter로 보고 처음 나오는 delimeter의 위치 포인터 리턴.

char* strerror(int errnum) ; 에러코드를 에러스트링으로 변환.







'Develop > C&CPP' 카테고리의 다른 글

deque  (0) 2018.06.13
stack / queue  (0) 2018.06.12
thread mutex  (0) 2018.06.10
thread  (0) 2018.06.09
utility  (0) 2018.06.08
반응형

cpp mutex

include <mutex>


+ mutex 사용하기

std::mutex mtx ;


void func(int id, int &v) {

   for (int i=0; i<10; i++) {

     mtx.lock() ;

    ++v ;

    mtx.unlock() ;

   }

}

int v=0 ;

std::thread t1 (func, 0, std::ref(v) ) ;

std:;thread t2(func, 1, std::ref(v) ) ;

t1.join();

t2.join() ;


-lock() ; 다른 쓰레드에 의해 lock되어 있지 않는 경우, 현재 쓰레드에서 락을 건다. unlock을 할 때까지 현재 쓰레드가 뮤텍스를 소유함. 

이미 다른쓰레드가 뮤텍스를 소유하고 있으면, 해제될때까지 블로킹 된다.

- lock을 얻은 상태에서 또 lock()을 하면 안된다. 데드락 발생.  (중복 lock을 하려면 recursive_mutex 사용)


+ bool try_lock() ; lock을 얻지 못하면 바로 리턴한다. 블로킹되지 않는 것이 lock()과 차이. 

뮤텍스를 얻었으면 true를 리턴하고, 작업 완료시 unlock()을 해주어야 한다.

다른 쓰레드가 뮤텍스 소유하고 있으면 false를 바로 리턴한다.


+ recursive_mutex  ; mutex와 비슷하나, lock 등급이 가능.

락을 얻은 상태에서 또 락을 얻을 수 있다. 뮤텍스 소유 레벨을 올림.

나중에 unlock()을 lock() 횟수만큼 해줘야 한다.



==> Mutex를 직접사용하지 말고 아래(lock_guard, unique_lock) 를 사용하기를 권장함.


+ lock_guard  ; 함수 내부에서 사용하여 간단하게 동기화 처리.

내부적으로 mutex를 사용하여 항상 락이 되도록 유지.

constructor에서 락을 얻고, destructor에서 언락을 한다.

std::mutex mtx ;

void func(int id) {

try {

   std::lock_guard<std::mutex> lck(mtx) ;

} catch ( std::logic_error & ) {

}

}


+unique_lock ; 뮤텍스를 사용하여 동기화 처리. lock_guard와 비슷하나 구동 시점을 지정할 수 있다.

lock, unlock을 사용 가능하며, 굳이 사용 안 해도 lock_guard 처럼 작동한다.

함수 일부분내에서 동기화 해제해도 되는 구간이 있을 경우에 사용하면 될 것 같다.

생성시점에 락을 안 걸 수도 있다.

guard(mutex, std::defer_lock) ; 이렇게 초기화하면 락을 얻지 않는다.






'Develop > C&CPP' 카테고리의 다른 글

stack / queue  (0) 2018.06.12
cstring  (0) 2018.06.11
thread  (0) 2018.06.09
utility  (0) 2018.06.08
fstream 1 basic_ifstream  (0) 2018.06.07
반응형

cpp thread

include <thread>


+간단한 thread 예

void func() { cout << "aaa" << endl ; }


thread t(&func) ; // func함수가 쓰레드로 실행.

t.join() ;    // thread t가 종료 될때 까지 기다림.


+ thread 함수에 파라미터 주기

void func(int x) {..} ;

thread t1(&func, 10) ;

thread t2(&func, 20) ;

t1.join() ;

t2.join() ;


+global 변수를 다중 thread로 카운팅하기

std::atomic<int> global_cnt(0) ;    // atomic 하게 작업.

void increase_global(int n) { 

   for (int i=0; i<n; i++) ++global_cnt; 

}

std::vector<std::thread> threads ;

for (int i=0; i<5; i++)

   threads.push_back( std::thread( increase_global, 100) ) ;

// 5개의 쓰레드로 100번씩 돌림. global_cnt=>500


+다른 방식

void increase_ref(std::atomic<int> &v , int n) {

   for (int i=0; i<n; i++) ++v; 

}

std::atomic<int> foo(0) ;

for (int i=0; i<5; i++)

   threads.push_back( std::thread( increase_ref, std::ref(foo), 100) ) ;

// 5개의 쓰레드로 100번씩 돌림. foo=500



+ main thread인지 아닌지 체크
std::thread::id main_thread_id = std::this_thread::get_id() ;    // thread id 얻기

void is_main_thread() {
if ( main_thread_id == std::this_thread::get_id() ) { cout << "Main thread" << endl ;}
else { cout <<"not main thread" << endl ; }
}

is_main_thread();
std::thread t (is_main_thread) ;
t.join() ;





'Develop > C&CPP' 카테고리의 다른 글

cstring  (0) 2018.06.11
thread mutex  (0) 2018.06.10
utility  (0) 2018.06.08
fstream 1 basic_ifstream  (0) 2018.06.07
functional 1 plus,minus,bind1st, bind2nd, equal_to, greater  (0) 2018.06.07
반응형

cpp utility

include <utility>


+swap ; 두 객체의 값들을 바꾼다.

int x=10, y=20 ;

std::swap(x,y) ;    // x=20, y=10


int foo[4] ;

int bar[]={1,2,3,4} ;

std::swap(foo, bar) ;    // foo=1,2,3,4


+make_pair ; 두 객체를 pair로 만들어 리턴한다. 타입이 맞지 않으면 알아서 컨버팅 해준다.

std::pair<int,int> foo ;

foo = std::make_pair(10,20) ;

// access value: foo.first, foo.second



'Develop > C&CPP' 카테고리의 다른 글

thread mutex  (0) 2018.06.10
thread  (0) 2018.06.09
fstream 1 basic_ifstream  (0) 2018.06.07
functional 1 plus,minus,bind1st, bind2nd, equal_to, greater  (0) 2018.06.07
algorithm 4 merge, heap, min, max  (0) 2018.06.06
반응형

cpp fstream

include <fstream>


++ basic_ifstream

Input file stream

ios_base <- basic_ios <- basic_istream <- basic_ifstream


+constructor

explicit basic_ifstream(const char * filename, ios_base::openmode mode=ios_base::in) ;

const char *filename 대신 const string &filename도 지원.

ex)

std::ifstream ifs("test.txt", std::ifstream::in) ;

char c = ifs.get() ;

or

std::ifstream ifs ;

ifs.open( "test.txt", std::ifstream::in) ;

char c = ifs.get() ;


+ bool is_open() const ;  // 파일이 열려있는지 체크. true/false

+ void close() ;    // file close


+operator >>

스트림에서 타입에 맞게 읽음.

int n ;

std::cin >> n ;


+get

int_type get() ;

basic_istream& get(char_type &c) ;

basic_istream& get(char_type *s, streamsize n) ;    // n-1까지 읽음. 마지막은 null

basic_istream& get(char_type *s, streamsize n, char_type delim) ;


char str[256] ;
std::cin.get(str, 256) ;


+getline()
라인을 읽음 또는 구분자 까지 읽음.  버퍼크기는 null을 포함한 크기로 지정.
getline(char_type *s, streamsize n) ;
getline(char_type *s, streamsize n, char_type dilim) ;

std::cin.getline(name, 256) ;

+read()

null 체크없이 무조건 크기대로 읽음. 

read(char_type *s, streamsize n) ;

ex)

std::ifstream is("test.txt", std::ifstream::binary) ;

if ( is ) {

   is.seekg(0, is.end) ;    // move to last

 int length = is.tellg();    // file size

is.seekg(0, is.beg) ;    // move to first


char *buf = new char[length] ;

is.read(buf, length) ;

if ( is ) // read ok

else // read only is.gcount() ;

is.close() ;

delete[] buf;

}


+gcount() ; 읽은 데이터 크기

input operation이 읽은 데이터 크기.

std::cin.getline(str, 20) ;

std::cin.gcount() ;    // 실제 읽은 데이터 크기.


+ignore() ; 데이터를 읽고 버림.

ignore(streamsize n=1, int_type delim) ;

n개의 문자가 추출되거나 delim일 때까지 읽고 버림.


+peek() ; 다음 문자를 읽어 리턴하지만 스트림에서 뽑아내지는 않고 내비둠.

ex) 수 또는 문자열 읽기

std::cout << "input number or wrod:";

std::cout.flush() ;    // ouput 버퍼 출력하여 비움.


std::cin >> std::ws ;     // 앞에오는 white space를 지움

std::istream::int_type c ;

c = std::cin.peek() ;    // 문자 한 개를 미리 보기.

if ( c==std::char_traits<char>::eof() ) return 1 ;    // eof

if ( std::isdigit( c ) ) {

int n ;

std::cin >> n ;

} else {

std::string str ;

std::cin >> str ;

}


+putback(char_type c)

문자 하나를 버퍼에 집어 넣고, 마지막 추출 위치를 back 시킨다.

위의 예제와 동일한 기능을 다음과 같이 사용할 수  있다.

char c = std::cin.get() ;

if ( (c>='0') && (c<='9') ) {

   int n ;

   std::cin.putback(c) ;    // 또는 std.cin.unget() ;

   std::cin >> n ;

}


+ tellg    / tellp

tellg ; 입력스트림에서 현재의 위치를 리턴한다. (파일 오프셋이 마지막에 있으면 파일 크기가 된다.)

tellp ; 출력 스트림에서는 tellp를 쓴다. 

is.seekg(0, is.end ) ;

int filesize = is.tellg() ;


+seekg / seekp

seekg ; 입력 스트림에서 추출할 다음 문자 위치를 지정한다.

seekp ; 출력 스트림에서는 seekp를 쓴다.

seekg(pos_type pos) ;    // 시작 위치 기준으로 위치.

seekg(off_type off, ios_base::seekdir_way) ;    // 상대 위치, 기준.

seekdir_way ; ios_base::beg, ios_base::cur, ios_base::end


std::ofstream outfile ;

outfile.open("test.txt") ;

outfile.write("This is an apple", 16) ;

long pos = outfile.tellp() ;    // file size ; 16. ==> point <EOF>

outfile.seekp(pos-7) ;    // ==> point 'n'

outfile.write(" sam", 4) ;

outfile.close() ;    // => This is a sample












'Develop > C&CPP' 카테고리의 다른 글

thread  (0) 2018.06.09
utility  (0) 2018.06.08
functional 1 plus,minus,bind1st, bind2nd, equal_to, greater  (0) 2018.06.07
algorithm 4 merge, heap, min, max  (0) 2018.06.06
alrorigthm 3 partition, sort, search  (0) 2018.06.05
반응형

cpp functional

#include <functional>


++ operator class


++ 파라미터 바인더

+bind1st ; 함수객체를 리턴한다. 첫번째 파라미터를 지정.

ex) 10을 값으로 갖는 요소의 개수.

cnt = count_if( numbers, numbers+6,  bind1st( equal_to<int>(), 10 ) ) ;


+bind2nd ; 함수 객체를 리턴한다. 두번째 파라미터를 지정.

ex) 0보다 작은 값의 요소 개수.

cnt = count_if( numbers, numbers+6, bind2nd( less<int>(), 0 ) ) ;


++ 연산

+plus ; 두 객체를 더함.

template <class T> struct plus : binary_function <T,T,T> {

T operator() (const T&x, const T&y) const { return x+y ; }

ex) 두 컨테이너를 순서대로 요소별로 더하기

int first[]={1,2,3,4,5} ;

int second[]={10,20,30,40,50} ;

int results[5] ;

std::transform( first, first+5, second, results, std::plus<int>()) ;


+minus: 두 객체를 뺌.

상동

ex)

int numbers[]={10,20,30} ;

int result ;

result = std::accumulate( numbers, numbers+3, 100, std::minus<int>() ) ;

// 100 -10-20-30 = 40


+multiplies ; 두 객체를 더함.

int numbers[]={1,2,3,4,5,6,7,8,9} ;

int factorials[9] ;    // 각각의 factorial을 구함.

std::partial_sum( numbers, numbers+9, factorials, std::multiplies<int>() ) ;

// 시작값=1, 두개의 곲=2, 다음 곱=6, ...

//factorials =  1! 2! 3! 4! 5! 6! 7! 8! 9! 


+divides ; 두 객체를 나눔. first/second

// first = 10, 40, 90, 40, 10 

// second=1,2, 3, 4, 5

std::transform(first, first+5, second, second+5, results, std::divides<int>() ) ;

// results=10, 20, 30, 10, 2


+modulus ; 나눈 나머지. first%second

// numbers= 1,2,3,4,5

std::transform(numbers, numbers+5, remainders, std::bind2nd( std::modulus<int>(), 2) ) ;

// remainders = 1 0 1 0 1


+negate ; nagative   ; -1*x

std::transform(numbers, numbers+5, numbers, std::negate<int>() ) ;

// numbers 값들의 부호를 모두 바꿈.


++비교함수

+equal_to  ; 두 값이 같은 지 확인. 같으면 true, 다르면 false.

// foo = 10,20,30,40,50

// bar = 10,20,40,80,160

// 두 개를 비교하여 처음으로 다른 부분의 값을 각각 구하면

std::pair<int*,int*> ptiter = std::mismatch( foo, foo+5, bar,  std::equal_to<int>() ) ;

// *ptiter.first, *ptiter.second  = 30, 40


+not_equal_to

// 처음으로 나온 다른 값 찾기

// numbers = 10,10,10,20,20

int *pt = std::adjacent_find( numbers, numbers+5, std::not_equal<int>() ) +1 ;

// *pt = 20


+greater

// 내림차순 정렬

std::sort(numbers, numbers+5, std::greater<int>() ) ;    // prev > next


+less

// 오름차순 정렬

std::sort(numbers, numbers+5, std::less<int>() ) ;    // prev < next


+greater_equal

// 0이상인 원소의 개수

cnt = std::count_if( numbers, numbers+5, std::bind2nd(std::greater_equal<int>(), 0) ) ;


+less_equal

// 100이하인 원소의 개수

cnt = std::count_if( numbers, numbers+5, std::bind2nd(std::less_equal<int>(), 100) ) ;


++ 논리 연산

logical_and

logical_or

logical_not

ex) 

bool foo[]={true,false, true,false} ;

bool bar[]={true, true, false, false} ;

bool result[4] ;

std::transform(foo, foo+4, bar, result, std::logical_and<bool>() ) ;

// and 결과 ; true, false, false, false

std::transform(foo, foo+4, bar, result, std::logical_or<bool>() ) ;

// or 결과 ; true, true, true, false

std::transform(foo, foo+4, result, std::logical_not<bool>() ) ;

// not 결과 ; false, true, false, true



+not1  ; 결과를 not한 unary function 객체를 리턴함.

// 홀수가 아닌 원소의 개수.

struct isodd {

bool operator() (const int &x) { return i%2==1 ; }

typedef int argument_type ;

} ;

cx = std::count_if(values, values+5, std::not1(isodd()) ) ;


+not2 ; 결과를 not한 binary function 객체를 리턴함.

firstmismatch = std::mismatch( foo, foo+5, bar, std::not2( std::equal_to<int>() ) ) ;


+ptr_fun ; 함수포인터를 함수객체로 만들어 리턴해 준다.

char* foo[]={"10","20","30"} ;

int bar[3] ;

transform( foo, foo+5, bar, ptr_fun(atoi)) ;


+mem_fun ; 멤버함수를 함수객체로 만들어 리턴해 준다.

vector<string> v ; 

v.push_back( new string("one") ) ;

v.push_back( new string("three") ) ;

vector<int> lens ( v.size() ) ;

transform( v.begin(), v.end(), lens.begin(),  mem_fun( &string::length ) ) ;


+mem_fun_ref ;상동.  레퍼런스 버전.


+ref ; c++11

reference_wrapper 생성자.

객체의 적절한 참조 타입을 생성.

ex)

int foo (10) ;

auto bar = std::ref(foo) ;

bar++ ;

// foo => 11로 업데이트 된다. (참조형인 bar 변경의 영향)















'Develop > C&CPP' 카테고리의 다른 글

utility  (0) 2018.06.08
fstream 1 basic_ifstream  (0) 2018.06.07
algorithm 4 merge, heap, min, max  (0) 2018.06.06
alrorigthm 3 partition, sort, search  (0) 2018.06.05
algorithm 2 copy,swap,transform,replace,fill,generate,remove,unique,..  (0) 2018.06.04

+ Recent posts