윈도우를 구동할시에는 윈도우가 자동적으로 로드를 하여 구동을 시키는 프로그램들이 있는데, 이를 (자동)시작프로그램 이라고 합니다.


보통, 시작표시줄 -> 모든 프로그램 -> 시작 프로그램 에 해당 프로그램의 바로가기 아이콘을 넣어두면 자동으로 시작하게 되며, 윈도우에 대해 잘 아시는 유저라면 레지스트리에 해당 프로그램의 경로 및 명령프롬프트를 작성하여 자동실행을 시킬 수도 있다는 것을 아실겁니다.


이런 레지스트리 경로로 설정하여 시작프로그램을 처리하는 레지스트리 경로에는 몇몇 다른 경로가 존재하며, 각각의 경로마다 로드되어지는 순서가 다르게 됩니다.


편의상 자동적으로 시작되어져야 하는 프로그램 중 가장 먼저 자동으로 실행되게 해야 하거나, 나중에 실행되어 져야 하는 등 순차적인 실행이 필요한 경우나, 로그인 전에 자동시작 되어야 하는 프로그램을 설정하여야 하는 경우 또는 이런 시작 순서의 차이로 인해 부팅 후 윈도우를 시작하는데 딜레이가 생기거나 해당 어플리케이션의 문제가 생기는 경우도 있는데, 이러한 위의 예를 든 경우 아래의 정보가 유용하게 사용되어 질수 있을 듯 합니다.

또한 추가적으로 아래의 자동시작 프로그램의 레지스트리 경로를 알고 있다면 악성 프로그램 등의 시작 프로그램이 어느 경로로 설치되어 있는지 등도 부가적으로 확인할 수가 있으며, 윈도우를 관리하는데 편리하게 사용할 수도 있을 듯 합니다.

 




이제 차례대로 알아본다면,


1. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce


2. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices


<로그인>


3. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce


4. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run


5. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run


6. All Users Startup folder : Documents and Settings\All Users\Start Menu\Programs\Startup folder


7. Startup folder : Documents and Settings\user\Start Menu\Programs\Startup folder

                            NT 경우 : path is Profiles\user\Start Menu\Programs\Startup


8. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce


의 레지스트리 경로 순서대로 시작프로그램들이 순차적으로 로드 되며, 각 키 안에서의 우선순위는 먼저 설치된 프로그램 순입니다. (오른쪽 창의 데이터순서)


* 시스템구성 유틸리티(msconfig) 안에서 실행되는 시작프로그램은 4,5,6,7번과 같습니다.

   1,2,3,8번을 제외하고 msconfig 내의 시작프로그램순서는 프로그램이 로드되는 순과 같습니다.


* HKEY_LOCAL_MACHINE\...\RunOnce 레지스트리 키에 있는 실행프로그램들의 실행순서는 정해져있지 않고,

  동시에 로드되게 됩니다.


* RunServicesOnce 키와 RunServices 키는 사용자가 로그온 하기 전에 로드됩니다.(일부 백신프로그램 등의 경우

  에는 이 경로에 해당 시작프로그램 경로를 작성하기도 합니다. 로그인 전에 자동실행 시킬 어플리케이션이 있다면

  여기에 경로및 데이터를 작성하시면 됩니다.)


* 만일 다른 프로그램에 종속되어 실행되는 시작프로그램이 있다면, 종속되어진 시작 프로그램은 선행된 시작프로그

  램이 완전히 끝날 때 까지 대기하게 되며, 이것을 제외하고는 위에 나열된 순으로 로드됩니다.


* 안전 모드에서 시작할 경우 Run 키가 모두 무시됩니다. RunOnce 키의 경우 값의 이름 앞에 별표(*)를 붙여 안전

  모드에서도 관련된 경로의  프로그램을 실행시킬 수도 있습니다.


* 물론, 윈도우즈는 프로그램을 배치 프로세싱 하는 것이 아니고 멀티 프로세싱을 하기 때문에 프로그램의 로드를

  시작하는 순서는 정할 수 있어도 프로그램의 크기에 따라 최종 로드 시간이 서로 다르고 또 그 당시의 CPU 상황

  과 디스크의 단편화 등등... 편차가 무척 많기 때문에 로드가 끝나는 순서는 충분히 달라 질수 있습니다.


위의 각 키별 시작 레지스트리를 조작할 경우에는 큰 문제가 생기지는 않으나, 다른 경로의 레지스트리들을 사용자 임의로 처리할 경우 윈도우에 심각한 문제가 생길수도 있으므로 조심해야 할 듯 합니다.


다소 난이도가 있는 팁이지만, 필요하신 분도 있을 듯해서 한번 올려봅니다.



추가로 한가지 더...


간혹 시작프로그램에서 지우고픈 것이 잇어서, 시작레지의 RUN에서 목록을 지워도 이게 레지스트리를 다시 실행 할 때 마다 등록 되는 놈들이 있습니다. (일부 악성코드, 에드웨어 등등을 수동으로 잡을 경우)


그 것은 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\MSConfig\startupreg]

여기에 등록이 되어 있기 때문에 레지스트리 실행 할 때마다 해당 값을 복구 합니다... 



http://cafe.naver.com/xpiapc.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=107

블로그 이미지

란마12

,

충격적인 사실은.. C/C++에는 2차원 배열이 없다는 것입니다. 물론, 3차원, 4차원 배열도 없습니다. C/C++에는 1차원의 선형 배열만 있을 뿐입니다.
그렇다면 우리가 2차원, 3차원 배열이라고 사용하는 것은 무엇일까요?
C/C++은 2차원 이상의 배열은 '배열을 원소로 가지는 배열'로서 구현하고 있습니다.
즉, int array[3][256];라고 했을때, 이것은 3*256의 배열이 아니라, int[256]의 배열을 원소로 하여 그 배열이 3개 연속으로 있는 구조를 취합니다. (행중심 배열이라고 하지요)
C/C++에서 배열의 이름은 그 배열의 첫번째 원소에 대한 포인터입니다.
즉, int a[3]의 경우, a라는 이름은 int형에 대한 포인터, 즉 int*타입이 되지요.
그렇다면, int array[3][256];라고 했을 때, array라는 이름은 배열의 첫번째 원소에 대한 포인터가 되어야 옳습니다. 이때, 2차원 이상의 배열은 배열을 원소로 가지는 배열이라고 했습니다. 즉, 이때, array라는 배열의 원소는 int형의 원소가 256개 있는 배열이 되지요. 따라서 array라는 이름은 int[256]에 대한 포인터, 즉 int*[256] 타입이 되어야 옳습니다. 이는, 포인터 연산을 위해서는 포인터가 가리키는 대상의 크기가 얼마인지가 확정되어야 하기 때문이지요. 이를테면, p가 int*타입일 경우, p++이라고 하면 int형의 크기만큼 증가하게 됩니다. 만약, p가 int array[3][256]를 가리킨다고 하면, p++이라고 했을 때, array의 각 원소의 크기만큼 증가해야 합니다, 즉, 배열의 각 원소의 크기를 컴파일러가 알 필요가 있다는 얘기지요. 따라서 2차원 배열의 열의 크기를 알아야 합니다. (하나의 열이 배열의 원소 하나이기 때문이지요)
따라서 2차원 배열을 인자로 받아들이는 함수는 다음과 같은 프로토타입은 유효하지 않습니다.
Matrix( int **k);
Matrix( int k[][]);
Matrix( int (*k)[]);
이들 모두 2차원 배열의 열의 크기가 무엇인가를 알려주는 힌트가 하나도 없기 때문이지요.
제대로 선언하려면 열의 크기를 알려주는 힌트가 필요합니다. 다음과 같이 말이죠.
Matrix( int k[3][256]);
Matrix( int k[][256]);
Matrix( int (*k)[256]);
단, Matrix( int *k[256]); 과 같은 표현은 유효하지 않습니다. 이 표현은 int*의 배열을 인자로 받는다는 선언이지, int형의 256개짜리 배열에 대한 포인터를 인자로 받는다는 표현이 아니지요.

'포인터는 포인팅하는 대상의 크기가 분명해야 한다'는 원칙



int a[4];
int *p = a;
일때 a[0] == p[0], a[1] == p[1] 이라고 하는 것을 보고

in a[3][4]; 일 때
int **p =a;
이고 a[0][0] == p[0][0], a[1][2]== p[1][2]로 알고 계시는 분들이 있으십니다.
혹은 왜 이게 안되는지 궁금해 하십니다.

그래서 이런 글을 올립니다. 참고하세요

배열의 등가포인터 의미와 생성 그리고 활용에 대하여 다룹니다.

자 이런 배열이 있습니다
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
이때 배열의 이름 a는 배열의 정의상 배열의 첫요소의 주소입니다.
그러면 이는 배열의 첫요소 즉, a[0][0]의 주소 즉, &a[0][0] 일까요?
아니면 &a[0] 일까요? 값만 놓고 보면 둘 다 같은 값이 나옵니다.
그러면 의미상 정확하게 맞는 표현은 무엇일까요?

int a[3][4] 배열은 요소 12개 짜리 1차원 배열이 아닙니다.
메모리에는 12개의 숫자가 연속해서 존재하기는 하나 이를
편의를 위하여 2차원 배열처럼 생각하는 거지요

고로 int a[3][4]는 요소수 3개 짜리 배열입니다. 즉, 3칸짜리 배열이지요

그런데 이 배열은 각 칸칸마다 뭐가 들어 있냐면 정수가 있는것이 아니라
int [4] 즉, int 4개짜리 배열이 들어있는 겁니다.

따라서 이 배열의 요소수는 3개이고 이 배열의 첫요소는 a[0] 가 됩니다.
고로 배열명 a == &a[0]라고 해야합니다.

그러면 어차피 값은 &a[0][0]나 &a[0]이나 같은데 왜 꼭 &a[0]가 맞다고 할까요?
자 다음을 보시지요

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int *p = a;
int (*q)[4] = a;
int **r = a;

세개의 포인터에 배열명 a를 담았습니다. 어느것이 옳을까요?
여기서 옳다는 것은 단지 대입이 되느냐 아니냐가 아니라
컴파일리 에러, 경고 없는 경우입니다.

사실 대부분 컴파일러는 int *p = a; 는 경고를 내거나 엄격한 컴파일러는
에러를 냅니다. 고로 에러, 경고를 막으려면 casting을 써서
int *p = (int *)a; 라고 해야 합니다.

그러나 두번째 int (*q)[4] = a; 는 에러, 경고 나지 않습니다.
즉, 두개는 완벽히 일치하는 데이터 타입이라는 뜻이지요...

세번째 2중 포인터는 int **r = p;는 역시 첫번째와 마찬가지로
타입이 다른 주소가 대입되므로 에러 혹은 경고가 납니다.
정상이려면 int **r = (int **)a; 하셔야 합니다.

자 왜 두번째 포인터만 정상일까요?
위에서 얘기 했듯이 int a[3][4] 일때 배열명 a는 &a[0]의 주소인데
a[0]은 a배열의 첫요소 즉, 3칸 짜리 배열에는 int [4]
즉, int 4개 짜리 배열이 들어 있으므로
a[0]는 그 속의 int [4] 배열의 이름이 됩니다.

고로 &a[0]는 바꿔 말하면 int [4] 배열의 주소이므로
타입은 int (*)[4] 라고 쓸수 있습니다.
그런데 a == &a[0] 이니 결국 배열 이름은 int (*)[4] 와 같은 타입입니다.

그러므로 이러한 주소를 받는 포인터는 int (*q)[4] 로 선언하게되고
int (*q)[4] = a; 가 성립하는 것입니다.

그럼 다시 다음에서 봅시다.

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int *p = (int *)a;
int (*q)[4] = a;
int **r = (int **)a;

이렇게 강제로라도 a를 대입했다면 이 포인터들로
배열에 있는 a[1][2] 즉,  7을 억세스 하려면 어떻게 할까요?

int *p는 현재 값이 정수 즉, 1의 주소를 갖으므로
그리고 정수(int)의 포인터 이므로
printf("%d\n", *(p+6)); 하거나 혹은 [ ] 연산자를 이용하여
printf("%d\n", p[6]); 으로 해야 합니다.

그러나 두번째는 int (*q)[4]의 현재값이 {1,2,3,4} 배열의 주소이므로
a[1][2]와 동일한 표현은 q[1][2] 가 됩니다.
이것이 왜 이렇게 되는지는 다차원 배열을 공부하시면 됩니다.

즉,
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
에서 a[1][2] 와 같은 값을 억세스 하기 위하여 
int *p = (int *)a; 로 하면 p[6]  혹은 *(p+6)
int (*q)[4] = a; 로 하면 q[1][2] 로 됩니다.
두 방법중 어떤것이 이해가 쉽습니까? 

이와같이 배열의 이름을 대입받을 때 에러, 경고, 캐스팅 없이 대입 가능한
포인터를 배열의 등가포인터라고 하고 등가포인터가 배열의 이름을 받으면
그때부터는 포인터가 배열과 표현식이 동일하게 사용가능합니다.

물론 그렇다고 이것이 완전히 동일해 지는것은 아닙니다.
배열은 배열이고 포인터는 포인터입니다. 단지 배열명을 갖는 포인터이지요

단, 억세스는 간접연산(포인터로 인하여)이므로 억세스 속도는 배열보다 느립니다.

그럼 1차원 함수에 넘기는 경우를 보지요...

void main(void)
{
   int a[4] = {1,2,3,4};
   func(a);
}
라고 할때 func 함수는 넘겨받은 배열의 이름을 이용하여
배열내의 a[2]인 3을 인쇄한다고 합시다.

그럼 어떻게 하나요?
void func(int *p)
{
    printf("%d\n", p[2]);
}
라고 할것입니다.

 이 상황을 잘보면 

(1) main에서 func를 호출하면서 넘긴것은 배열의 이름 a입니다.
1차원 배열이므로 이 이름은 첫요소의 주소 즉, &a[0]  이고 a[0]는 정수 1이므로
int * 타입입니다.

(2) 고로 func에서는 이런 배열의 이름과 등가인 int *p로 받는것입니다.
즉, int *p = a; 가 가능하므로 int *로 한것이지요
고로 p는 표현식에서 a 배열과 동일하므로 a[1] ==p[1]이 됩니다.

즉, 배열은 전체를 넘기지 못하고 그 첫요소의 주소(배열명)를 넘기므로
이를 등가포인터로 받고 활용은 마치 배열인듯이 하는 겁니다.

이것이 등가포인터의 활용이지요...

그럼 2차원 배열을 넘기면 어떻게 되나요?

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
func(a);
에서 a[1][2] 와 값을 인쇄하는 함수는 어떻게 만드나요?

(1) int func(int *p)
(2) int func(int (*p)[4]);
(3) int func(**p); 어느것이 옳을까요?

만약 1처럼 하면?

func(a); 하면 경고가 발생하므로
억지로 캐스팅 하여 func((int *)a); 로 해야 합니다.
그리고 함수는 이렇게 만들지요

int func(int *p)
{
    printf("%d\n", p[6]);
    또는 
    printf("%d\n", *(p+6));
}

그런데 2번처럼 하면 아까 얘기했듯이 int (*p)[4]는 배열명 a 와 등가이므로
int (*p)[4] = a; 가 가능합니다.

고로 활용이 마치 a 배열처럼 되므로 다음과 같이 됩니다.

int func(int (*p)[4])
{
    printf("%d\n", p[1][2]);
}

3번 처럼 단순히 2중포인터라고 생각한다면?
이거 골치아퍼집니다.
아마 세가지 방법에서 제일 골치아프겠네요
한번 직접 해보세요...

이때 p[1][2]는 절대 배열이 아닙니다. p는 엄연한 포인터입니다.
그럼 어떤것이 쉽고 정상적인 방법일까요? 

배열을 넘기고(배열명을 넘기는 거지만) 이를 등가 포인터로 받고
그리고 이를 활용할때는 마치 원래의 배열처럼 하는것 이게 등가포인터를 활용한 겁니다.

다음은 2차원 배열을 넘기고  배열요소의 전체 합을 구하는 함수를 설계합니다.
역시 등가 포인터를 활용합니다.

결국

void main(void)
{
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; 
    printf(""%d\n", sum(a));
}

int sum(int (*p)[4])
{
    int a = 0, i, j;
    for(i=0; i<3; i++)
   {
       for(j=0; j<3; j++)
      {
           a += p[i][j];
      }       
   }
  return a;
}

다시한번 말씀드리지만
위와 같이 배열을 다른 함수로 넘기거나 다른함수에서 리턴하거나
할때 배열명을 넘기고 받기는 포인터(등가포인터)로 받고
활용은 넘겨준 배열과 동일하게 하는것이 좋습니다.
이런 포인터를 등가포인터라고 합니다.

결국 등가포인터를 이용하면 배열, 함수를 함수로 넘기거나 함수 리턴으로 줄 때
매우 쉬워 집니다.

참고로 다음은 등가적인 포인터의 예를 보입니다.

(1) int a[4]  ==> int *p
(2) int *a[4] ==> int **p
(3) int a[3][4] ==> int (*p)[4]
(4) int a [2][3][4] ==> int (*p)[3][4]
(5) int *(*a[3])(int) ==> int *(**p)(int)
...
위에서 등가포인터 만드는 공식(?) 내지는 꼼수를 찾아보세요.

http://kin.naver.com/open100/detail.nhn?d1id=1&dirId=1040101&docId=545702&qb=MuywqOybkCDrsLDsl7TsnbQg642U67iU&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=gLF%2Bvsoi5T0ssZOkRHosss--332099&sid=TNkPTesN2UwAABudDlI

'language > C/C++' 카테고리의 다른 글

클래스내의 배열변수의 크기를 상수로 지정하고 싶을 때  (0) 2014.12.11
const  (0) 2012.05.21
Use 'static const' instead of '#define'  (0) 2011.12.06
메모리오류 시 디버거가 설정해 주는 값  (0) 2010.09.17
지침  (0) 2010.09.17
블로그 이미지

란마12

,

같은 dll을 하나의 프로세스에서 두번 로딩하면 어떨까 하고 테스트해봤다.

- 두번째 로드된 dll핸들은 처음 로드된 dll핸들을 참조한다.(참조카운터만 1증가)
- 두번째 dll은 로드될 때 DllMain에서 ATTACH/DETACH관련 이벤트가 발생하지 않는다.
- 두 핸들은 같지만 로드된 모든 dll핸들을 FreeLibrary하기 전까지 free되지 않는다.
  (참조카운터가 0이 되면 free)
블로그 이미지

란마12

,

새로운 프로젝트를 만들고 기존에 쓰던 프로젝트의 속성을 상속해서 쓸 수 있다.
상속한 속성을 전혀 수정하지 않고 쓰고 싶은데 유독 출력파일명 설정은 수정해줘야 한다.
프로젝트 속성페이지 -> 구성 속성 -> 링커 -> 일반 순으로 찾아 들어가면
'출력 파일'항목이 보이는데 이것을 $(Target*)관련 속성으로 지정하면 재귀호출 오류가 발생한다.
그래서 일단 아래와 같이 쓰고 있는데..

 $(OutDir)\$(ProjectName).exe

이렇게 되면 dll이나 lib프로젝트같은 경우 확장자를 수동으로 수정해줘야 한다..
혹시 수정없이 사용할 수 있는 방법 아시는 분?


속성 상속 후 <부모 또는 프로젝트 기본값에서 상속>으로 바꿔야 할 사항들
+ 구성속성
   + 일반
     - 출력 디렉터리 
     - 중간 디렉터리
   + C/C++
     + 미리 컴파일된 헤더
       - 미리 컴파일된 헤더 파일
     + 출력 파일
       - ASM 목록 위치
       - 개체 파일 이름
       - 프로그램 데이터베이스 파일 이름
     + 고급
       - 호출 규칙
   + 찾아보기 정보
     + 일반
       - 출력 파일


릴리즈 모드에서 디버깅

프로젝트 속성에서 맨위 왼쪽 구성을 Release로 한다.

"메뉴 -> 프로젝트 -> 속성 -> 구성 속성 -> C/C++ -> 일반" 으로 이동을 한다. 그리고

그리고 디버깅 정보 형식은 "편집하며 계속하기를 위한 프로그램 데이터베이스(/ZI)" 로 변경한다.

그리고 "메뉴 -> 프로젝트 -> 속성 -> 구성 속성 -> C/C++ -> 최적화 -> 최적화"로 가서 "속도 최대화(/O2)"에서 "사용 안 함"으로 설정.

그리고 "메뉴 -> 프로젝트 -> 속성 -> 구성 속성 -> C/C++ -> 최적화 -> 전체 프로그램 최적화"로 가서 "링크 타임 코드 생성 사용(/GL)" "아니요"로 설정한다.

'tool' 카테고리의 다른 글

doxygen  (0) 2011.12.06
crash dump  (0) 2011.11.11
WinDbg  (0) 2011.01.30
VC .Net에서 산출물(output/intermediate) 관리하기  (0) 2010.12.23
Visual Studio 2008과 Windows 98  (0) 2009.06.12
블로그 이미지

란마12

,
  • 0xcccccccc (3435973836) - 초기화 되지 않은 지역변수.
  • 0xcdcdcdcd (3452816845) - 초기화되지 않은 힙에 할당된 메모리.
  • 0xdddddddd (3722304989) - 힙에서 free된 메모리.
  • 0xfeeefeee (4277075694) - 힙에서 free된 메모리.
  • 0xfdfdfdfd (4261281277) - 힙에 할당된 메모리의 초과범위(할당된 메모리의 양쪽 끝)
  • 'language > C/C++' 카테고리의 다른 글

    클래스내의 배열변수의 크기를 상수로 지정하고 싶을 때  (0) 2014.12.11
    const  (0) 2012.05.21
    Use 'static const' instead of '#define'  (0) 2011.12.06
    2차원 배열이 더블포인터인가?  (0) 2010.11.10
    지침  (0) 2010.09.17
    블로그 이미지

    란마12

    ,

    지침

    language/C/C++ 2010. 9. 17. 10:21

    1. 클래스나 구조체같은 변수는 무조건 포인터로 선언하자.
        : 생성/소멸 시점을 명확하게 제어할 수 있다.

    2. 클래스 초기화는 생성자에서 하지 말고 초기화/해제 함수를 따로 만들어 하자.
       특히 생성자에서 다른 생성자를 호출하면 안된다. 다른 인스턴스의 생성자가 호출되어 의미없는 동작이 되어버림.


    블로그 이미지

    란마12

    ,

    map insert 반환값

    library/STL 2010. 9. 12. 19:51

    #include <stdio.h>
    #include <map>
    #include <string>
     
     
    int main(int argc, char *argv[])
    {
     
        map<int, string>                        mmNames;
        map<int, string>::iterator              iter;
        pair<map<int, string>::iterator, bool>  ret;
     
     
        iter = mmNames.find(1);
        if(iter!=mmNames.end())
        {
            printf("\nmmNames contains 1");
        }
        else
        {
            printf("\nmmNames does not contains 1");
        }
     
     
        ret = mmNames.insert(map<int, string>::value_type(1, string("Lee")));
        if(ret.second == true)
        {
            printf("\ninsert success");
        }
        else
        {
            printf("\ninsert fail");
        }
     
        iter = mmNames.find(1);
        if(iter!=mmNames.end())
        {
            printf("\nmmNames contains 1");
        }
        else
        {
            printf("\nmmNames does not contains 1");
        }
     
        return(0);
    }

    'library > STL' 카테고리의 다른 글

    STL관련 step into무시하기  (0) 2011.04.21
    erase  (0) 2010.12.14
    copy  (0) 2010.02.09
    블로그 이미지

    란마12

    ,

    횟수? 회수?

    yonjh/잡생각 2010. 9. 7. 10:18

    사이시옷을 붙이는 경우

    1) 앞말이 모음으로 끝나고 뒷말의 첫소리가 된소리로 나거나(나무+가지→나뭇가지, 해+볕→햇볕)
    2) 뒷말의 첫소리 ㄴ, ㅁ 앞에서 ㄴ 소리가 덧나거나(코+노래→콧노래, 아래+이→아랫니)
    3) 뒷말의 첫소리 모음 앞에서 ㄴ 소리가 덧날때(깻잎, 나뭇잎, 훗일)

    ※한자어는 사이시옷을 붙이지 않는 것이 원칙이다.
    갯수(X)→ 개수(個數)
    촛점(X)→ 초점(焦點)

    하지만 예외가 6개 있다.

    찻간(車間), 곳간(庫間), 셋방(貰房), 숫자(數字), 횟수(回數), 툇간(退間) 

    그러므로 개수와 갯수에서는 개수가 맞고, 회수와 횟수중에서는 횟수가 맞는 표현이다.

    .. 문법시간에 외웠던 '차고세수회퇴'가 아직도 머리에 남아있군...

    'yonjh > 잡생각' 카테고리의 다른 글

      (0) 2010.08.05
    블로그 이미지

    란마12

    ,

    yonjh/잡생각 2010. 8. 5. 15:29

    태어나기전 나의 존재가 無였듯이 죽으면 다시 無로 돌아간다.
    주변의 자연과 동화되어 내 육신을 이루던 물질들이 흩어져 있다가
    일부는 구름, 흙, 공기가 되고 일부는 수많은 생명체들의 일부가 되겠지.
    나 자신도 우주 탄생 이후 존재했던 모든 것들의 일부였으니까.

    'yonjh > 잡생각' 카테고리의 다른 글

    횟수? 회수?  (0) 2010.09.07
    블로그 이미지

    란마12

    ,

    - Android.mk 파일에 LOCAL_LDLIBS:= -llog

    #include <android/log.h>
    __android_log_print(ANDROID_LOG_INFO, "ExecSamba", "pid = 0");
    __android_log_print(ANDROID_LOG_INFO, "Return2: ", "%d", returnvalue2);


    - 한글문제

    Android Printing Unicode Log
    안드로이드에서 유니코드 한글 메세지 보기

    Logcat provides valuable information but sadly it cannot show unicode character like below.
    이클립스의 로그켓에서는 아래와 같이 한글이 깨저 보입니다. 패배의 이클립스.. 안타깝습니다.

    Eclipse LogCat

    Eclipse LogCat

    I know you found something but what! I cannot read square.
    Eclipse LogCat does not have any encording option.

    이클립스의 로그켓에서 유니코드로 인코딩 하는 옵션을 지원하지 않아서 그런건데요.
    해결 방법이 있습니다.

    Here is solution.
    Android tool adb.exe  can show logcat as well as eclipse logcat.

    cmd를 유니코드로 출력하게 설정한뒤 adb.exe를 통해 로그켓을 보는 겁니다. +_+

    // run cmd with unicode mode
    c:\> cmd /u

    // change characterset
    c:\> chcp 65001

    // change font
    // cmd font has to be changed to TTF font such as Lucida Console in the CMD property – font tab

    // run logcat on cmd
    c:\> adb logcat

    then you can magically see the unicode character!
    자 고생했던걸 생각하면 놀랍게도 참 이쁘게 나옵니다.

    Android adb log

    Android adb log


    출처: http://www.cleancode.pe.kr/?p=68

    'mobile > Android' 카테고리의 다른 글

    WiFi Debugging in Android  (0) 2014.04.14
    stlport  (0) 2010.07.26
    c와 연동  (0) 2010.07.23
    자바프로젝트에서 export한 jar를 안드로이드프로젝트에서 불러오기  (0) 2010.07.22
    블로그 이미지

    란마12

    ,