파일 로깅

프로그래밍/C++ 2015. 9. 10. 17:07 |

테스트 할 때 로그를 출력하기 거시기 할 때 그냥 파일에 쓰게 간단히 코드를 만들어 둠.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef _BABO_LOG_H
#define _BABO_LOG_H
 
#include <cstdio>
#include <cstdarg>
#include <fstream>
 
using namespace std;
 
class Log {
private:
    Log() { file.open("/var/log/log.txt", ios::out | ios::app); } // 파일에 계속 이어 붙인다.
    ~Log() { file.close(); }
    ofstream file;
public:
    static Log &instance() { // singleton
        static Log _instance;
        return _instance;
    }
    void log(const char *format, ...) {
        char buffer[256];
        va_list args;
        va_start(args, format);
        vsnprintf(buffer, sizeof(buffer), format, args);
        va_end(args);
        file << buffer;
    }
};
 
#define log(format, args...) Log::instance().log(format, ##args)
 
#endif // _BABO_LOG_H

 

 

다음과 같이 사용하면 된다.

1
2
3
4
5
6
7
#include "Log.h"
 
int main() {
    for (int i = 0; i < 10; i++)
        log("%d\n", i);
    return 0;
}


:

pair<> 클래스

 

pair 는 c++98 에도 이미 제공되고 있었다.

pair 는 두 객체를 하나의 타입으로 묶어 사용한다.

예를들면, 2차원 평면 상에서 좌표를 표현하는 경우 다음과 같이 사용할 수 있다.

pair<intint> 2d_point;

또 map 계열의 클래스는 키와 값의 쌍으로 구성되는데 이때도 pair 를 사용한다.

각 타입은 template 으로 정의 되므로 다른 타입이 사용될 수 있다.

pair 를 선언을 하면 선언 시에 사용된 객체의 default constructor 가 불리며 int 와 같은 primitive 타입이라면 0 으로 초기화 된다.

 

pair 정의 코드

bits/stl_pair.h g++ (GCC) 4.8.2
/**
   *  @brief Struct holding two objects of arbitrary type.
   *
   *  @tparam _T1  Type of first object.
   *  @tparam _T2  Type of second object.
   */
  template<class _T1, class _T2>
    struct pair
    {
      typedef _T1 first_type;    /// @c first_type is the first bound type
      typedef _T2 second_type;   /// @c second_type is the second bound type
      _T1 first;                 /// @c first is a copy of the first object
      _T2 second;                /// @c second is a copy of the second object
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 265.  std::pair::pair() effects overly restrictive
      /** The default constructor creates @c first and @c second using their
       *  respective default constructors.  */
      _GLIBCXX_CONSTEXPR pair()
      : first(), second() { }
      /** Two objects may be passed to a @c pair constructor to be copied.  */
      _GLIBCXX_CONSTEXPR pair(const _T1& __a, const _T2& __b)
      : first(__a), second(__b) { }
      /** There is also a templated copy ctor for the @c pair class itself.  */
#if __cplusplus < 201103L
      template<class _U1, class _U2>
    pair(const pair<_U1, _U2>& __p)
    : first(__p.first), second(__p.second) { }
#else
      template<class _U1, class _U2, class typename
           enable_if<__and_<is_convertible<const _U1&, _T1>,
                is_convertible<const _U2&, _T2>>::value>::type>
    constexpr pair(const pair<_U1, _U2>& __p)
    : first(__p.first), second(__p.second) { }
      constexpr pair(const pair&) = default;
      constexpr pair(pair&&) = default;
 
 
      // DR 811.
      template<class _U1, class typename
           enable_if<is_convertible<_U1, _T1>::value>::type>
    constexpr pair(_U1&& __x, const _T2& __y)
    : first(std::forward<_U1>(__x)), second(__y) { }
      template<class _U2, class typename
           enable_if<is_convertible<_U2, _T2>::value>::type>
    constexpr pair(const _T1& __x, _U2&& __y)
    : first(__x), second(std::forward<_U2>(__y)) { }
      template<class _U1, class _U2, class typename
           enable_if<__and_<is_convertible<_U1, _T1>,
                is_convertible<_U2, _T2>>::value>::type>
    constexpr pair(_U1&& __x, _U2&& __y)
    : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
      template<class _U1, class _U2, class typename
           enable_if<__and_<is_convertible<_U1, _T1>,
                is_convertible<_U2, _T2>>::value>::type>
    constexpr pair(pair<_U1, _U2>&& __p)
    : first(std::forward<_U1>(__p.first)),
      second(std::forward<_U2>(__p.second)) { }
      template<typename... _Args1, typename... _Args2>
        pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
      pair&
      operator=(const pair& __p)
      {
    first = __p.first;
    second = __p.second;
    return *this;
      }
 
 
      template<class _U1, class _U2>
    pair&
    operator=(const pair<_U1, _U2>& __p)
    {
      first = __p.first;
      second = __p.second;
      return *this;
    }
      template<class _U1, class _U2>
    pair&
    operator=(pair<_U1, _U2>&& __p)
    {
      first = std::forward<_U1>(__p.first);
      second = std::forward<_U2>(__p.second);
      return *this;
    }
      void
      swap(pair& __p)
      noexcept(noexcept(swap(first, __p.first))
           && noexcept(swap(second, __p.second)))
      {
    using std::swap;
    swap(first, __p.first);
    swap(second, __p.second);
      }
    private:
      template<typename... _Args1, std::size_t... _Indexes1,
               typename... _Args2, std::size_t... _Indexes2>
        pair(tuple<_Args1...>&, tuple<_Args2...>&,
             _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
#endif
    };

 

pair 는 c++11 에서 크게 확장된 것은 없지만 표준 확장에 따라 move constructor 가 제공되고 swap() 이 추가되었다.

그 외 사용법은 c++98 에 비해 크게 달라진 점은 없다.

멈버 변수인 first 와 second 가 public 으로 선언되어 있기 때문에 접근 제한 없이 사용할 수 있다.

 

pair 를 간단히 생성하기 위해서 make_pair() 라는 함수가 존재한다.

make_pair 는 객체 생성을 위해 따로 타입을 쓰지 않아도 된다.

make_pair
pair<intfloat> int_float(0, 0.0f);

위 코드 대신 아래와 같이 사용할 수 있다.

make_pair
auto int_float = make_pair(0, 0.0f);

 

 

make_pair 의 코드:

bits/stl_pair.h g++ (GCC) 4.8.2
   /**
   *  @brief A convenience wrapper for creating a pair from two objects.
   *  @param  __x  The first object.
   *  @param  __y  The second object.
   *  @return   A newly-constructed pair<> object of the appropriate type.
   *
   *  The standard requires that the objects be passed by reference-to-const,
   *  but LWG issue #181 says they should be passed by const value.  We follow
   *  the LWG by default.
   */
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 181.  make_pair() unintended behavior
#if __cplusplus >= 201103L
  // NB: DR 706.
  template<class _T1, class _T2>
    constexpr pair<typename __decay_and_strip<_T1>::__type,
                   typename __decay_and_strip<_T2>::__type>
    make_pair(_T1&& __x, _T2&& __y)
    {
      typedef typename __decay_and_strip<_T1>::__type __ds_type1;
      typedef typename __decay_and_strip<_T2>::__type __ds_type2;
      typedef pair<__ds_type1, __ds_type2>        __pair_type;
      return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
    }
#else
  template<class _T1, class _T2>
    inline pair<_T1, _T2>
    make_pair(_T1 __x, _T2 __y)
    return pair<_T1, _T2>(__x, __y); }
#endif

 

c++11 의 make_pair 는 rvalue 인자를 받으므로,

해당 타입이 move semantics 를 지원한다면 인자로 전달된 객체가 변경된다.

 

간단한 테스트 코드 :

example : make_pair
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
 
void print(const vector<int> &v) {
    cout << "[ ";
    for (auto i : v) {
        cout << i << " ";
    }  
    cout << " ]" << endl;
}
 
int main() {
    vector<int> a;
    a.push_back(1);
    a.push_back(2);
 
    print(a);
    vector<int> b;
    b.push_back(10);
    b.push_back(20);
    print(b);
 
    auto c = make_pair(move(a), move(b)); // 이제 a 와 b 를 사용하지 않는다
    print(a);
    print(b);
    return 0;
}
출력 결과
[ 1 2  ]
[ 10 20  ]
[  ]
[  ]


:

http://www.sublimetext.com/docs/plugin-basics

http://code.tutsplus.com/tutorials/how-to-create-a-sublime-text-2-plugin--net-22685

http://code.tutsplus.com/tutorials/sublime-text-2-tips-and-tricks--net-21519

 

 

examples : 

http://www.sublimetext.com/docs/plugin-examples

 

 

api references : 

http://www.sublimetext.com/docs/api-reference

 


 

 

대략의 설명

 

패키지는 폴더로 만들어 져서 Package 디렉토리에 넣으면 된다. 

나의 패키지는 "Preferences > Browse Packages…" 메뉴를 통해 들어가면 된다.

패키지는 zip 파일로 묶은 다음 확장자를 .sublime-package 로 바꿔 단일 파일로 사용 가능하다. 

 

보통 language 관련 패키지가 있고, 그 외 Default, User 패키지가 있다.

  • Default : 모든 표준 키 바인딩, 메뉴 정의, 파일 설정, 파이썬으로 만든 모든 플러그인
  • User : 마지막에 로딩 되어 기본 값들을 덮어 씀

 

 

기본 구현

Tools > New Plugin... 메뉴 선택

1
2
3
4
5
import sublime, sublime_plugin
 
class ExampleCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.insert(edit, 0"Hello, World!")

 

바로 이런 게 생긴다.

 

일단  Packages/ 에서 폴더를 하나 만들고 그 안에 py 파일로 저장한다.

파일 이름은 뭐든 관계 없고, 관례적으로 플러그인 이름을 사용한다.

 

저장이 되었으면, 콘솔을 열고 (단축키 : Ctrl + ' ) 다음과 같이 입력하면

view.run_command('example')

 

파일 첫 부분에 "Hello World" 가 삽입된다.

 

Command Type

Sublime plugin 은 다음 세 가지 command type 을 제공한다.

  • Text Commands : View 오브젝트를 통해 file 이나 buffer 에 접근
  • Window Commands : Window 오브젝트를 통해 현재 창을 참조
  • Applications Commands : 위 두가지에 속 하지 않는.

 

import sublime, sublime_plugin
class ExampleCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.insert(edit, 0"Hello, World!")
sublime_plugin.TextCommand 를 상속 받은 class 의 이름에서 'Command' 를 제외한 나머지 부분,
CamelCase 형식의 이름을 under_score 형식으로 변경한 것이 커맨드 이름이 된다.

(예를 들면, 클래스 이름이 MyOwnCommand 라면 my_own 이 커맨드 이름이 된다.)

 

 

 

단축키 추가하기

패키지 안에 다음과 같이 파일을 추가한다.

MyPackage/
    Default (Linux).sublime-keymap
    Default (OSX).sublime-keymap
    Default (Windows).sublime-keymap

 

Preferences > Key Bindings – Default 를 통해 겹치지 않는 단축키를 택하면 된다.

다음과 같이 추가하면 된다.

[
    {
        "keys": ["ctrl+alt+x"], "command""command_name" 
    }
]

커맨드의 인자가 필요하면 뒤에다 arg 로 붙인다.

OSX 에서 커맨드 키는 super 라고 쓴다.

 

 

메뉴 추가하기

대략 .sublime-menu 파일을 만들면 된다.

  • Main.sublime-menu : 메인 메뉴
  • Side Bar.sublime-menu : 파일이나 폴더에서 오른쪽 클릭 후 팝업 메뉴
  • Context.sublime-menu : 에디터에서 오른쪽 클릭 후 팝업 메뉴

 

[
{
    "id""edit",
    "children":
    [
        {"id""wrap"},
        "command""prefixr" }
    ]
}
]


:

secure socket programming

 

server

 Collapse source
//SSL-Server.c
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
  
#define FAIL    -1
  
int OpenListener(int port)
{   int sd;
    struct sockaddr_in addr;
  
    sd = socket(PF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
        perror("can't bind port");
        abort();
    }
    if ( listen(sd, 10) != 0 )
    {
        perror("Can't configure listening port");
        abort();
    }
    return sd;
}
  
SSL_CTX* InitServerCTX(void)
{   SSL_METHOD *method;
    SSL_CTX *ctx;
  
    OpenSSL_add_all_algorithms();  /* load & register all cryptos, etc. */
    SSL_load_error_strings();   /* load all error messages */
    method = SSLv23_server_method();  /* create new server-method instance */
    ctx = SSL_CTX_new(method);   /* create new context from method */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}
  
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
 /* set the local certificate from CertFile */
    if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    /* set the private key from KeyFile (may be the same as CertFile) */
    if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    /* verify private key */
    if ( !SSL_CTX_check_private_key(ctx) )
    {
        fprintf(stderr, "Private key does not match the public certificate\n");
        abort();
    }
}
  
void ShowCerts(SSL* ssl)
{   X509 *cert;
    char *line;
  
    cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
    if ( cert != NULL )
    {
        printf("Server certificates:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("Subject: %s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("Issuer: %s\n", line);
        free(line);
        X509_free(cert);
    }
    else
        printf("No certificates.\n");
}
  
void Servlet(SSL* ssl) /* Serve the connection -- threadable */
{   char buf[1024];
    char reply[1024];
    int sd, bytes;
    const char* HTMLecho="<html><body><pre>%s</pre></body></html>\n\n";
  
    if ( SSL_accept(ssl) == FAIL )     /* do SSL-protocol accept */
        ERR_print_errors_fp(stderr);
    else
    {
        ShowCerts(ssl);        /* get any certificates */
        bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
        if ( bytes > 0 )
        {
            buf[bytes] = 0;
            printf("Client msg: \"%s\"\n", buf);
            sprintf(reply, HTMLecho, buf);   /* construct reply */
            SSL_write(ssl, reply, strlen(reply)); /* send reply */
        }
        else
            ERR_print_errors_fp(stderr);
    }
    sd = SSL_get_fd(ssl);       /* get socket connection */
    SSL_free(ssl);         /* release SSL state */
    close(sd);          /* close connection */
}
  
int main(int count, char *strings[])
{   SSL_CTX *ctx;
    int server;
    char *portnum;
  
    if ( count != 2 )
    {
        printf("Usage: %s <portnum>\n", strings[0]);
        exit(0);
    }
    SSL_library_init();
  
    portnum = strings[1];
    ctx = InitServerCTX();        /* initialize SSL */
    LoadCertificates(ctx, "mycert.pem""mycert.pem"); /* load certs */
    server = OpenListener(atoi(portnum));    /* create server socket */
    while (1)
    {   struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL *ssl;
  
        int client = accept(server, (struct sockaddr*)&addr, &len);  /* accept connection as usual */
        printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        ssl = SSL_new(ctx);              /* get new SSL state with context */
        SSL_set_fd(ssl, client);      /* set connection socket to SSL state */
        Servlet(ssl);         /* service connection */
    }
    close(server);          /* close server socket */
    SSL_CTX_free(ctx);         /* release context */
    return 0;
}

컴파일 :

gcc -Wall -o server server.c -lssl -lcrypto

 

 

 

 

client

 Collapse source
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
  
#define FAIL    -1
  
int OpenConnection(const char *hostname, int port)
{   int sd;
    struct hostent *host;
    struct sockaddr_in addr;
  
    if ( (host = gethostbyname(hostname)) == NULL )
    {
        perror(hostname);
        abort();
    }
    sd = socket(PF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = *(long*)(host->h_addr);
    if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
        close(sd);
        perror(hostname);
        abort();
    }
    return sd;
}
  
SSL_CTX* InitCTX(void)
{   SSL_METHOD *method;
    SSL_CTX *ctx;
  
    OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
    SSL_load_error_strings();   /* Bring in and register error messages */
    method = SSLv23_client_method();  /* Create new client-method instance */
    ctx = SSL_CTX_new(method);   /* Create new context */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}
  
void ShowCerts(SSL* ssl)
{   X509 *cert;
    char *line;
  
    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
    if ( cert != NULL )
    {
        printf("Server certificates:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("Subject: %s\n", line);
        free(line);       /* free the malloc'ed string */
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("Issuer: %s\n", line);
        free(line);       /* free the malloc'ed string */
        X509_free(cert);     /* free the malloc'ed certificate copy */
    }
    else
        printf("No certificates.\n");
}
  
int main(int count, char *strings[])
{   SSL_CTX *ctx;
    int server;
    SSL *ssl;
    char buf[1024];
    int bytes;
    char *hostname, *portnum;
  
    if ( count != 3 )
    {
        printf("usage: %s <hostname> <portnum>\n", strings[0]);
        exit(0);
    }
    SSL_library_init();
 hostname=strings[1];
 portnum=strings[2];
  
    ctx = InitCTX();
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);      /* create new SSL connection state */
    SSL_set_fd(ssl, server);    /* attach the socket descriptor */
    if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
        ERR_print_errors_fp(stderr);
    else
    {   char *msg = "Hello???";
  
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        ShowCerts(ssl);        /* get any certs */
        SSL_write(ssl, msg, strlen(msg));   /* encrypt & send message */
        bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
        buf[bytes] = 0;
        printf("Received: \"%s\"\n", buf);
        SSL_free(ssl);        /* release connection state */
    }
    close(server);         /* close socket */
    SSL_CTX_free(ctx);        /* release context */
    return 0;
}
 

컴파일 :

gcc -Wall -o server client.c -lssl -lcrypto

references:

[1] Secure programming with the OpenSSL API, Part 1: Overview of the API : http://www.ibm.com/developerworks/library/l-openssl.html

[2] Korean Version of [1] : http://hasu0707.tistory.com/153

[3] Secure Server Client using OpenSSL in C : http://simplestcodings.blogspot.kr/2010/08/secure-server-client-using-openssl-in-c.html

[4] HTTPS와 SSL 인증서 : http://opentutorials.org/course/228/4894

[5] SSL/TLS Programming : http://www.cs.odu.edu/~cs772/fall08/lectures/ssl_programming.pdf

:


ipython

대략 ipython.tar.gz 파일을 다운로드 받은 후에 아래와 같이 실행

$ tar -xzf ipython.tar.gz
$ cd ipython
$ python setup.py install

상세한 내용은 http://ipython.org/ipython-doc/stable/install/install.html [2]



ipython notebook

1. Tornado

https://github.com/downloads/facebook/tornado/tornado-2.4.1.tar.gz

$ tar -xzf tornado-2.4.1.tar.gz $ cd cd tornado-2.4.1/ $ python setup.py build $ python setup.py install


2. zeroMQ

https://github.com/downloads/zeromq/pyzmq/pyzmq-2.2.0.1.tar.gz

$ tar -xzf pyzmq-2.2.0.1.tar.gz $ cd pyzmq-2.2.0.1/ $ python setup.py build $ python setup.py install


cygwin 에서 실패한다면, [4] 참조

$ wget 'http://download.zeromq.org/zeromq-2.1.7.zip'
$ unzip zeromq-2.1.7.zip
$ cd zeromq-2.1.7
$ ./configure
$ make 
    ... succeeds...
$ make install
...
$ wget --no-check-certificate 'https://github.com/downloads/zeromq/pyzmq/pyzmq-2.1.7.zip' $ python setup.py configure --zmq=/usr/local $ cd pyzmq-2.1.7 $ python setup.py build $ python setup.py install

아놔 ... 근데 왜 나는 안 되지 ㅠㅠ



references : 

[1] http://ipython.org/

[2] http://ipython.org/ipython-doc/stable/install/install.html

[3] http://ipython.org/ipython-doc/rel-1.1.0/interactive/public_server.html

[4] https://github.com/zeromq/pyzmq/issues/113

[5] http://blog.daum.net/maxmin93/13380905

:


http://www.w3schools.com 에는 대략 이렇게 쓰여져 있다.[1]

Semicolon ;

Semicolon separates JavaScript statements.

Normally you add a semicolon at the end of each executable statement.

Using semicolons also makes it possible to write many statements on one line.

NoteYou might see examples without semicolons. 
Ending statements with semicolon is optional in JavaScript.


자바스크립트엔 auto semicolon insertion(ASI) 가 동작하며, 세미콜론을 붙이지 않아도 자동으로 들어간다.

또한 ASI 로 인해서 공백문자(특히 newline)도 중요해진다. [2]

c/java 등에서 연산자 우선순위를 신경쓰지 않고 괄호를 사용하듯이

자바스크립트에서 ASI 규칙에 의존하기 보단 세미콜론을 항상 다는 것이 이롭다.

http://en.wikipedia.org/wiki/JavaScript_syntax

위 링크에 이와 관련한 자바스크립트 문법 예제가 몇 있다.


한 가지 예를 보자면

대략 이런 일이 일어날 수도 있다. 

ASI 의 원리를 대략 이해하고, 들여쓰기 등의 규칙을 절대적으로 준수하고 세미콜론을 항상 붙이자.



references : 

[1] http://www.w3schools.com/js/js_statements.asp

[2] http://en.wikipedia.org/wiki/JavaScript_syntax

:

cygwin repo

프로그래밍/tips 2013. 12. 5. 16:49 |




repo 다운로드

curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > /usr/bin/repo

chmod +x /usr/bin/repo



그냥 다운받아서 적당한 위치에 놓고 실행 모드로 설정만 해 주면 된다.


references : 

http://source.android.com/source/downloading.html


:

JavaScript 기본 래퍼 타입을 직접 사용하면 안 좋은 일이 일어날 수 있다.



결과는,


x 를 객체 타입으로 사용하여, if 검사에서 null 또는 undefined 가 아닌 값으로 체크되어 true 가 되었다.

:

대략 winsock 으로 braodcast 하는 c++ 소스입니다.





아래는 테스트용 reader 코드


references : 

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=7103&ref=7103
http://blog.daum.net/jjiyong/12873890


:

c/c++ 에서 unsigned 변수를 사용할 땐 주의해야 합니다.

수식에서 signed 변수와 unsigned 변수를 섞어 사용하면 타입 변환이 일어납니다.

타입 변환 규칙을 분명히 알고 사용해야 합니다.

(어렵지는 않습니다. 다른 타입을 가지는 변수들의 연산 결과는 더 넓은 표현 범위의 타입을 가집니다.

고로 signed int 와 unsigned int 의 연산 결과는 unsigned int 입니다.

결과는,

4294967295

4294967295

-1 

입니다.


또한 unsigned 변수를 뺄셈에 사용하면 역시 버그가 발생할 가능성이 생깁니다.

결과가 음수가 나오면 overflow 가 발생하여 예상치 못한 결과가 발생할 수 있습니다.

논리적으로 음수가 절대 발생하지 않는 경우 unsigned 변수를 사용하는 것은 장점이 됩니다.

변수가 0 보다 작은 지를 체크하지 않아도 되기 때문이죠. 예를 들면


대략 이런 식입니다.
array 의 boundary 체크가 빠졌다고 ? 물론 두 가지 함수에 모두 존재해야하므로 생략했습니다.


하지만 좋은 방법은 아니지만, 의도한 경우 이렇게 사용할 수는 있습니다.


약간의 장점이 있지만, 조심해서 사용해야합니다.

제 생각엔 몇 가지 경우를 제외하면 가능한 unsigned 변수를 사용할 필요가 없다고 생각합니다.

대략 count, size 를 표현해야 하는 경우에만 사용하면 되지 않을까 생각합니다.

java 에는 unsigned 변수 타입이 없습니다. (굳이 따지면 char 는 unsigned 타입이긴 합니다만)

왜냐하면 약간의 장점에 비해 복잡하기 때문입니다.

: