반응형


+ SELECT AND INSERT
한 테이블에서 선택한 레코드들을 다른 테이블에 추가하기.  (values 대신 select 절을 사용)

INSERT INTO TABLEA (f1, f2, f3)
  SELECT f1, f2, f3 FROM TABLEB

데이터베이스가 다르면 테이블명 앞에 DB명을 써준다.
 ex)  DB1.TABLEA


+ SELECT AND UPDATE
다른 테이블에서  이 테이블의 특정필드로 select한 값을 이 테이블에서 다른 테이블의 값으로 업데이트를 한 번에 하기.

UPDATE TABLEA log, TABLEB user
SET log.MOBILE_NO = user.MOBILE_NO
WHERE log.DEVICE_ID=user.DEVICE_ID;





반응형

mysql

+그룹별로 처음 나오는 하나의 줄만 뽑아낼때


ex) CAT_ID가 같은 것들끼리 묶어서 그룹별 처음으로 나온 레코드만 그룹 대표로 하나씩 추출한다.

select * from TABLE_A group by CAT_ID ;


그룹 내에서 어떤 키로 소팅하여 최신 값을 뽑는 경우, min, max 함수등을 이용하거나 미리 order by로 정렬 후 group by로 한다.

ex)

select * from (select * from TABLE_A order by NAME desc) a group by a.CAT_ID ;

select CAT_ID, min(NAME) from TABLE_A group by CAT_ID ;



+ group by 에러

only_full_group_by 에러가 발생.

=> mysql 5.7이상 부터 group by로 select 할 때 다른 값들이 있는 컬럼들을 조회하면 에러 발생.

처음 나온 것들을 자동으로 선택하여 조회하게 하려면 서버 설정을 바꿔주어야 한다.

/etc/mysql/my.cnf

[mysqld]

sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

위와 같이 설정을 추가하여 서비스 재시작

service mysql restart





반응형

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

+ Recent posts