Console

 

taskkill /f /im explorer.exe
attrib %userprofile%appdatalocaliconcache.db -s -r -h
del /q %userprofile%appdatalocaliconcache.db
start explorer.exe

'Development > 기타' 카테고리의 다른 글

유용한 C program  (0) 2012.06.17
Ubuntu 에서 Synergy 사용하기  (0) 2011.01.01
Mulplication without using '*' operator  (0) 2010.12.21
Mobile XE 설정하기  (0) 2010.08.24
[GPS]GPS모듈 구현중  (0) 2009.12.14
Posted by 까 치
,
1. 제일 오른쪽에 있는 '1'의 위치 구하기

rightBit = bitf ^ (bitf & (bitf - 1));



00010000b - 00000001b = 00001111b 라는 숫자의 기본 개념과 &, ^ 연산의 오묘함을 이용한 것이다.

실제로 아무 숫자나 넣어서 해보면 금방 이해할 수 있다.

최상위 비트도 이처럼 간단하게 구할 수 없을까? 해서 이렇게 저렇게 생각해 봤지만 현재로선 모르겠다.

추가사항: 2의 보수 아키텍처를 사용한다면 더욱 간편하고 빠른 식을 사용할 수 있다.
rightBit = -bitf & bitf;
결과값에 영향은 없으나 bitf가 unsigned형일 경우 컴파일 시 경고가 나타난다.
따라서 아래와 같이 수정한다.
rightBit = -(signed)bitf & bitf;

예) 40, -40
40 = 00101000, -40=11011000
따라서 결과값은 8




2. 주어진 수가 2의 제곱수(1, 2, 4, 8, 16 등등)인지 검사하기(출처: flipCode)

inline bool isPowOf2(int value) {   return !(value & (value - 1));   }


최하위 비트 구하기와 비슷한 원리다.

다른 버전(출처: java api)
inline bool isPowOf2(int value) {   return (value & -value) == value;   }



3. 임시 변수없는 SWAP 매크로(출처: Graphics Gems)

#define SWAP(a, b) ((a)^=(b)^=(a)^=(b))



위의 매크로는 정수형 타입에만 해당되는 연산이다.

부동소수일 경우엔 그냥 std::swap()을 사용해라.

템플릿 함수를 만들어 봤는데 알고보니 이미 std::swap()라는 게 제공되고 있더라.

매크로를 함수화해서 사용하는 건 보통의 함수 호출만큼 안전하지 않다.

예를들면, 아래의 경우



int a = 6, b = 9;

SWAP(++a, ++b);



a=10, b=7이 아니라 a=11, b=8이 된다. 왜 그런지는 말 안해도 알 것이라 믿는다.

그렇다고 함수화하는 건 속도 면에서 매크로보다 메리트가 떨어진다.

그래서 이를 사용할 때는 이것은 매크로이므로 복잡한 연산과 함께하지 말고 단순하게 사용하라는 걸 경각시키기 위해서 함수와는 달리 이름을 대문자로 하였다. (사실 이런 이유 등으로 매크로는 대개 대문자로 하는 거 같다.)

아, 그리고 a와 b의 어드레스가 같다면 결과는 무조건 0이 된다.



4. 0이 아닌 비트들의 개수 세기(예를 들어 0xf0는 4개)(출처: flipCode)



8비트용:



v = (v & 0x55) + ((v >> 1) & 0x55);

v = (v & 0x33) + ((v >> 2) & 0x33);

return (v & 0x0f) + ((v >> 4) & 0x0f);



참고로 0x55 = 01010101b, 0x33 = 00110011b, 0x0F = 00001111b



32비트용:



#define g31 0x49249249ul // = 0100_1001_0010_0100_1001_0010_0100_1001

#define g32 0x381c0e07ul // = 0011_1000_0001_1100_0000_1110_0000_0111



v = (v & g31) + ((v >> 1) & g31) + ((v >> 2) & g31);

v = ((v + (v >> 3)) & g32) + ((v >> 6) & g32);

return (v + (v >> 9) + (v >> 18) + (v >> 27)) & 0x3f;



8비트는 그럭저럭 봐줄만해도 32비트의 복잡도는... 제길

그래서 8비트에서의 원리를 이용해 32비트 짜리를 한 번 만들어 보았다.

성능이야 위에 거보단 떨어지겠지만 이해하기 쉽고 64비트로의 확장 또한 용이하다.



int cntBit32(long value)

{

    value = (value & 0x55555555) + ((value >>  1) & 0x55555555);

    value = (value & 0x33333333) + ((value >>  2) & 0x33333333);

    value = (value & 0x0F0F0F0F) + ((value >>  4) & 0x0F0F0F0F);

    value = (value & 0x00FF00FF) + ((value >>  8) & 0x00FF00FF);

    return   (value & 0x0000FFFF) + ((value >> 16) & 0x0000FFFF);

}



굳이 연산을 이해하지 않아도 누구라도 확장된 버전을 만들 수 있을거라 생각한다.





5.32비트 색상 두 개의 50% 혼합(출처: flipCode)

32비트 AARRGGBB 형식의 색상들을 1:1로 혼합...



알파채널이 있는 경우

color = ((color & 0xfefefefe) >> 1) + ((backColor & 0xfefefefe) >> 1)

            + ((color | backColor) & 0x01010101);



알파 채널 안쓰는 경우

color = ((color & 0x00fefefe >> 1) + (backColor & 0x00fefefe) >> 1)

            + ((color | backColor) & 0x00010101);



그래픽쪽은 잘 모르더라도 비트 연산은  어느 정도 이해 가능했다.

(color & 0xfefefefe) >> 1 은 각 ARGB의 값을 2로 나눈 것이다.

하지만 왜 굳이 ((color | backColor) & 0x01010101) 연산을 해서 각 ARGB값에 0이나 1을 더했는지는 모르겠다. 그리고 출처에는 알파 채널 안쓰는 경우

color = ((ccolor & 0x00fefefe) + (backColor & 0x00fefefe) >> 1)

            + ((color | backColor) & 0x00010101);

라고 나와 있지만 아무래도 오타인 거 같다.

추가.
1. 간단한 홀짝 판정
int odd = num & 1;  // 짝수면 0, 홀수면 1이 된다.

2. n개의 1로 채우기. mask에 유용하다.
int mask = (1 << n) - 1;  // n=4이면 1이 다음과 같이 변한다. 00000001 => 00010000 => 00001111
혹은 int mask = ~(~0 << n);

3. n개의 0으로 채우기. 위에꺼 응용
int mask = ~(1 << n) + 1; // n = 4이면 1이 다음과 같이 변한다. 00000001 => 00010000 => 11101111 => 11110000
혹은 int mask = ~0 << n;

4. 비트 뒤집기(리눅스에서는 이렇게 한단다)
x = (x >> 4) | (x << 4);
x = (x >> 2 & 0x33) | (x << 2 & 0xcc);
x = (x >> 1 & 0x55) | (x << 1 & 0xaa);

5. 비트 연산들이 잘 나와있는 곳
http://graphics.stanford.edu/~seander/bithacks.html
http://www.hackersdelight.org/
left most bit detection 으로 구글링하다 발견했다. 최고다. 역시 스탠포드 킹왕짱

'Development > 기타' 카테고리의 다른 글

Window7에서 아이콘이 깨질때  (0) 2012.06.17
Ubuntu 에서 Synergy 사용하기  (0) 2011.01.01
Mulplication without using '*' operator  (0) 2010.12.21
Mobile XE 설정하기  (0) 2010.08.24
[GPS]GPS모듈 구현중  (0) 2009.12.14
Posted by 까 치
,
Starting the Synergy SERVER on boot up.

Sample configuration  file
section: screens
        youngseok7_lee:
        magpie-desktop:
                super = meta
end

section: links
        youngseok7_lee:
                left = magpie-desktop
        magpie-desktop:
                right = youngseok7_lee
end

section: options
        switchDelay = 0
end



Make a directory in /etc to store the configuration:

Code:
sudo mkdir /etc/synergy
Setup my synergy server configuration file:
Code:
sudo gedit /etc/synergy/synergy.conf
To make the server run when gdm runs, but before anyone has logged in:

edit /etc/gdm/Init/Default:
Code:
sudo gedit /etc/gdm/Init/Default
Added the following lines in the middle of the file BEFORE the "sysmodmap=/etc/X11/Xmodmap" line:

Code:
SYNERGYS=`gdmwhich synergys`
if [ x$SYNERGYS != x ] ; then
$SYNERGYS --config /etc/synergy/synergy.conf
fi
The only problem with that is once you log in it kills off the server, so you need to make it start again for you.

edited /etc/gdm/Init/Default:
Code:
sudo gedit /etc/gdm/PreSession/Default
Added the following lines in the middle of the file BEFORE the "XSETROOT=`gdmwhich xsetroot`" line:
Code:
SYNERGYS=`gdmwhich synergys`
if [ x$SYNERGYS != x ] ; then
$SYNERGYS --config /etc/synergy/synergy.conf
fi
Log out and back in again.

The synergy server should now startup and run whenever your gdm session does.




Starting the Synergy CLIENT on boot up.
These instructions should work for running the synergy client on your UBUNTU machine to connect to a locally networked computer running the synergy server. (I've not actually tried them myself.)
Let us know how you get on.

NOTE:
The <address of server machine> will probably be an ip address that looks something like 192.168.0.1 (DON'T put in the exact string <address of server machine>)

To make the client run when gdm runs, but before anyone has logged in:

edit /etc/gdm/Init/Default:
Code:
sudo gedit /etc/gdm/Init/Default
Added the following lines in the middle of the file BEFORE the "sysmodmap=/etc/X11/Xmodmap" line:

Code:
SYNERGYC=`gdmwhich synergyc`
if [ x$SYNERGYC != x ] ; then
$SYNERGYC <address of server machine>
fi
The only problem with that is once you log in it kills off the client, so you need to make it start again for you.

edited /etc/gdm/Init/Default:
Code:
sudo gedit /etc/gdm/PreSession/Default
Added the following lines in the middle of the file BEFORE the "XSETROOT=`gdmwhich xsetroot`" line:
Code:
SYNERGYC=`gdmwhich synergyc`
if [ x$SYNERGYC != x ] ; then
$SYNERGYC <address of server machine>
fi
Log out and back in again.

The synergy client should now startup and run whenever your gdm session does.

NOTE:
The <address of server machine> will probably be an ip address that looks something like 192.168.0.1 (DON'T put in the exact string <address of server machine>)

'Development > 기타' 카테고리의 다른 글

Window7에서 아이콘이 깨질때  (0) 2012.06.17
유용한 C program  (0) 2012.06.17
Mulplication without using '*' operator  (0) 2010.12.21
Mobile XE 설정하기  (0) 2010.08.24
[GPS]GPS모듈 구현중  (0) 2009.12.14
Posted by 까 치
,


//C Program for Multiplication without Using Multiply Operator *
#include<stdio.h>
#include<conio.h>
void main()
{
int n,m,s=0;
clrscr();
printf(“nEnter the values”);
scanf(“%d%d”,&n,&m);
while(m!=0)
{
s=s+n;
m–;
}
printf(“Result = %d”,s);
getch();

}


By http://mycfiles.wordpress.com

'Development > 기타' 카테고리의 다른 글

유용한 C program  (0) 2012.06.17
Ubuntu 에서 Synergy 사용하기  (0) 2011.01.01
Mobile XE 설정하기  (0) 2010.08.24
[GPS]GPS모듈 구현중  (0) 2009.12.14
static 용어의 개념 및 성질  (0) 2009.10.25
Posted by 까 치
,

'Development > 기타' 카테고리의 다른 글

Ubuntu 에서 Synergy 사용하기  (0) 2011.01.01
Mulplication without using '*' operator  (0) 2010.12.21
[GPS]GPS모듈 구현중  (0) 2009.12.14
static 용어의 개념 및 성질  (0) 2009.10.25
Mozilla XPCOM document  (0) 2009.10.25
Posted by 까 치
,
GPS 모듈정보 http://www.u-blox.com/products/sam_ls.html
블루투스 모듈정도 http://www.bluetooth4u.co.kr

'Development > 기타' 카테고리의 다른 글

Mulplication without using '*' operator  (0) 2010.12.21
Mobile XE 설정하기  (0) 2010.08.24
static 용어의 개념 및 성질  (0) 2009.10.25
Mozilla XPCOM document  (0) 2009.10.25
[펌]회사에서 네이트 온 하기!!  (0) 2008.06.13
Posted by 까 치
,

1. 정적 지속성(static storage duration):static 객체들은 일단 한번 생성이 되면 프로그램이 종료 될 때까지 유지.
즉 객체의 소멸 시점이 scope에 영향 받지 않고 항상 일정함.
2. 유일성(singleton): 어떤 모듈 단위 (function, class, file)에서든지 static 객체는 단 한번만 생성
3. 내부 연결성(internal linkage):전역 static 객체나 함수는 link단계에서 외부 바인딩이 일어나지 않음.
즉, 외부 파일에서는 내부 전역 static 객체/함수를 참조하거나 호출할 수 없음

Binding

static
에 대해서 이해하기 위해서는 우선 binding이라는 개념을 이해하여야 합니다. 바인딩이라는 단어 역시 다양한 의미로 사용되는 용어인데 프로그래밍 언어에서 말하는 바인딩이란 어떤 심볼(변수나 함수)의 속성을 결정짓는 것을 의미합니다.

int main()
{
  int x;
  x = 3;
  return 0;
}

위와 같은 C 소스가 있을 때 이것을 컴파일러가 컴파일 하게 되면 우선 컴파일러는 int x; 라는 선언문을 보고서 x라는 이름의 변수를 자신의 심볼 테이블에 기록을 하며 이 때 그 변수의 속성(type, scope, value )을 저장하게 됩니다. 그리고 그 다음에 있는 x = 3; 이라는 구문에서 x라는 변수가 자신의 심볼 테이블에 있는지 살펴보고, 있으면 그 속성을 참고하여 해당 구문의 타입 체크와 같은 문법 검사를 수행하게 됩니다.(물론 x가 심볼 테이블에 없다면 그런 변수를 찾을 수 없다는 컴파일 에러를 발생시킵니다.)

이제 좀 더 복잡한 예를 살펴보겠습니다.

/// test1.cpp
#include <iostream>
  int global; // ---> 1)
  void extern_fun(int a);
  int main() 
  {
 
  global = 5; // ---> 2)
 
  extern_fun(3);
 
  std::cout << global << 'n';
   
return 0;
  }

 

/// test2.cpp
extern int global;  // ---> 3)
void extern_fun(int a)
{
  global += a;      // ---> 4)
  }

 위 소스에서는 global이라는 전역 변수를 두 개의 파일에서 참조하고 있습니다. 위에서 언급했듯이 컴파일러는 변수 선언문이 나타나면 해당 변수를 심볼 테이블에 등록하고 이후에 변수를 사용하는 구문을 만날 때마다 해당 변수가 자신의 심볼 테이블에 등록되어 있는지 살펴보고 그 정보에 따라 문법 검사를 수행하게 됩니다.

 그런데 컴파일러는 항상 파일 단위로 컴파일을 수행하며 새로운 파일을 컴파일 할 때 이전에 이미 컴파일 한 파일에 대한 정보 같은 것들은 따로 기록하지 않습니다. , 항상 새로운 마음가짐으로 각각의 파일들을 독립적으로 컴파일 하게 됩니다.

그래서 위의 경우 test1.cpp를 먼저 컴파일 했다고 해서 test2.cpp에서 global변수를 사용하는 구문을 컴파일 할 때 test1.cpp에서 만든 심볼 테이블을 참조하지는 않습니다.

 때문에 두 개 이상의 파일에서 같은 전역 변수를 참조하게 되면 그런 사실을 미리 소스 코드를 통해 컴파일러에게 알려줘야 합니다. 만약 그렇지 않으면 test2.cpp에서 4)구문을 컴파일 할 때 global이라는 변수가 선언되어 있지 않다 라고 에러를 발생시키거나 혹은 test1.cpp test2.cpp global변수를 별개의 변수로 취급하게 될 것입니다.

 그러므로 프로그래머는 사전에 test1.cpp test2.cpp에서 사용하는 global 변수가 동일한 것이다라는 사실을 컴파일러에게 알려주게 되는데 위의 소스에서 3)에 있는 extern은 바로 그런 역할을 수행하는 키워드입니다.

extern의 의미는 '해당 변수는 외부에서 참조하여 사용하겠다'라는 뜻입니다. 만약 3)이 없다면 test2.cpp를 컴파일 할 때 4)에서 global이라는 변수를 찾을 수 없다는 에러가 발생할 것이며, 3)에서 extern이 없다면 test1.cpp test2.cpp global은 별개의 변수로 취급되어 프로그램 결과가 8이 아니라 5가 나오게 될 것입니다.

 그렇다면 컴파일러는 각각의 파일을 컴파일 할 때 다른 파일의 심볼 값들을 참조하지 않음에도 불구하고 어떻게 전역 변수를 공유할 수 있을까요? 그것은 바로 링크 과정이 있기 때문에 가능합니다.

컴파일 시 컴파일러는 전역 변수나 함수에 대한 참조/호출을 직접적인 어셈블리어 구문으로 변환하는 것이 아니라(다시 말하면 해당 변수의 메모리 주소나 함수의 코드 주소로 바로 변환하지 않고) 특정한 이름을 부여하여 해당 이름의 전역 변수나 함수에 대한 참조/호출 구문으로 바뀌게 되는 것입니다.

 예를 들어 위의 소스의 경우에 test2.cpp에서 참조하는 global이 외부에서 참조되는 변수이다라는 사실을 컴파일 한 목적 코드(object code)에 기록해 두면 링커는 해당 변수와 동일한 이름으로 정의된 파일을 검색하고 test1.cpp에서 일치된 이름을 발견하면 해당 전역 변수 참조 구문들을 올바른 속성(상대 주소)값으로 바꾸게 됩니다.

 이렇게 어떤 변수나 함수의 속성값을 결정짓는 과정을 바인딩이라고 합니다. 그리고 위의 경우처럼 링크 과정에서 그런 속성값을 결정짓는 것을 링크 바인딩(link binding), 혹은 동적 바인딩(dynamic binding)이라 합니다.

정적 바인딩에 의해 정의되는 변수나 함수는 링크 과정 이전에 이미 속성이 결정되기 때문에 아래와 같은 특징을 가지게 됩니다.  

1. 정적 바인딩 변수는 extern 키워드를 통해 외부 파일에서 참조가 불가능하다.
2. 정적 바인딩 함수는 외부 파일에서 호출이 불가능하다.

static 전역 변수나 함수를 사용해 보신 분들은 아시겠지만 위의 특징은 바로 static 전역 변수와 함수의 특징과 일치합니다. , static 키워드는 해당 전역 변수나 함수를 컴파일러가 정적으로 바인딩을 하도록 프로그래머가 '지시'하는 역할을 합니다.

컴파일 타임 바인딩을 정적(static) 바인딩이라고 말하는 이유는 아마도 한번 컴파일 시에 속성이 결정되고 나면 '변하지 않는다' 라고 하는 불변성 때문이 아닌가 추측됩니다. 어쨌든 이런 특징을 가지고 있기에 static 변수는 독특한 성질을 지니고 있습니다.

 아래의 예제는 초보자가 흔히 하게 되는 실수입니다.

 /// header.h
int global;

/
// a.cpp
#include <iostream>
#include "header.h"
void b_func();
int main()
{
  global = 3;
  b_func();
  std::cout << global << std::endl;
  return 0;
}

/// b.cpp
#include "header.h"
void b_func()
{
  global = 5;
}

위 소스는 정상적으로 컴파일 됩니다.

앞에서 언급했듯이 컴파일러는 파일 별로 독립적으로 컴파일을 수행합니다.
따라서 a.cpp 컴파일 시 header.h에 있는 global 선언문을 통해 global 변수를 하나 생성하여 3을 할당합니다.
또한 b.cpp 역시 header.h에 있는 global 선언문을 통해 global 변수를 하나 생성하여 5를 할당합니다. 따라서 둘 다 적법한 소스입니다.

 하지만 링크 과정에서 링커는 a.cpp b.cpp가 동일한 이름(global)의 전역 변수를 두 개 생성한 것을 보고 링크 에러를 발생시킵니다.
(
이 때 발생하는 에러는 redefinition error입니다. 아마 초보자들이 가장 많이 접하는 에러 중 하나일 것입니다.)

 그러면 위 소스를 아래와 같이 수정해 보겠습니다.

 // header.h
static int global; /// int global static 전역 변수로 수정

// a.cpp
///원 소스와 동일...

// b.cpp
/// 원 소스와 동일....

이렇게 수정하면 정상적으로 컴파일 및 링크가 수행됩니다. 왜냐하면 static 전역 변수는 컴파일 시점에 바인딩이 완료되고 따라서 링크 과정에서 해당 변수에 대한 바인딩 처리를 하지 않으므로 중복 정의를 검사하지 않기 때문입니다.

그러나 대신 a.cpp b.cpp에서 사용하는 global 변수는 완전히 별도의 객체로 처리됩니다. 따라서 위 프로그램에서 a.cpp가 출력하는 global값은 - b_func()함수를 호출함으로써 바뀌는 값- 5가 아니라 - 원래 a.cpp에서 할당한 값 - 3이 됩니다.

, a.cpp b.cpp에서 사용하는 global 전역 변수는 사실 이름만 똑같을 뿐 별개로 취급되는 다른 변수가 됩니다.
(
따라서 이런 식의 사용은 프로그래머에게 혼란을 줄 뿐이며 버그를 야기시키는 좋지 않은 코딩 방식입니다. 그러므로 static 전역 변수를 선언할 때는 항상 header 파일이 아닌 c/cpp 파일에 해줘야 합니다.)

어쨌든 static 전역 변수는 항상 해당 변수가 선언된 파일 내부에서만 참조가 가능합니다. 그리고 이것은 static 전역 함수 역시 마찬가지이며 static으로 선언된 전역 함수는 외부 파일에서는 사용이 불가능합니다.(만약 외부에서 호출하려고 하면 링크 에러가 발생합니다.) 

때문에 보통 C프로그래머들은 외부 파일에서 사용할 필요가 없는 혹은 외부에서 사용하기를 원치 않는 함수들은 static으로 정의하곤 합니다. 이렇게 함으로써 이름 중복에 의한 혼란 등을 피할 수 있는 부수적인 장점을 얻을 수도 있습니다.
(
C++에서는 namespace class가 생기면서 이런 장점이 많이 사라졌습니다.)

그리고 이렇게 파일 내부에서만 참조 가능한 static 의 성질을 internal linkage(내부 연결성)이라고 부릅니다.

 

storage duration and scope

다 아시는 이야기 하나 해보겠습니다. 변수는 관점에 따라 다양하게 분류가 될 수 있습니다. 우선 공간(scope)범위에 따라 전역 변수와 지역 변수로 분류가 가능합니다. 그리고 메모리 할당 주체에 따라 정적 할당 변수와 동적 할당 변수로 분류할 수도 있습니다. 또한 메모리 할당 위치에 따라 스택(stack) 변수와 정적 영역 변수, 동적 영역(heap) 변수로 나눌 수 있으며 그 외에도 정적(static)변수, 상수(const)변수, 포인터 변수 등등 여러 종류로 구분이 가능합니다.

게다가 이러한 분류는 복합적으로 정의될 수 있습니다. 가령, 정적 전역 변수(static global variable), 정적 지역 변수(static local variable), 전역 상수 변수(global const variable) 등등이 있습니다.

심지어 어떤 분류 정의는 서로 밀접한 관계(혹은 동등한 의미)를 가집니다. 스택 변수와 비정적(non-static) 지역 변수는 사실 같은 의미를 가지고 있으며, 전역(global) 변수와 정적(static) 변수는 정적 영역 변수에 해당합니다.

 이렇게 변수의 종류가 다양하게 분류되는 것은 프로그래밍 시 여러 가지 상황이 발생하게 되고 이때 이런 상황에 맞는 변수 설정을 위한 여러 가지 개념들이 필요했기 때문이며 이러한 여러 개념들이 서로 복합적인 관계를 맺으며 사용되는 것은 그러한 개념들을 구체화 시키는 과정에서 구현 상의 이유로 만들어진 부수효과(side-effect)라 할 수 있습니다.

가령 포트란 같은 경우 모든 변수가 전역 변수로 지정됩니다(참고로 저는 포트란을 직접 사용해 본적은 없습니다.). , 지역 변수라는 개념이 없습니다. 따라서 파라미터 전달이나 스택 변수 생성에 따른 함수 호출 오버헤드가 없기 때문에 간단한 프로그래밍 시 좋은 성능을 보여줍니다.

그러나 대신 일회성 변수를 사용하더라도 지속적인 변수 유지가 필요하기 때문에 이름 짓기(naming) 문제나 혹은 같은 변수를 다른 용도로 계속 재사용하게 되고 따라서 복잡한 프로그래밍 시 코드가 난해해지는 단점이 있습니다.

그래서 C와 같은 프로그래밍 언어에서는 지역 변수라는 개념을 도입했으며 그에 따라 scope라는 개념이 생겨났습니다.

그리고 이런 scope라는 개념이 들어가면서 동시에 storage duration이라는 개념이 생겨났습니다. 더 이상 참조가 필요 없는, 다시 말하면 scope를 벗어난 지역 변수에 대해서 프로그래머가 일일이 지정하지 않아도 자동적으로 해당 지역 변수의 메모리를 컴파일러가 알아서 해제해줌으로써 보다 추상화된 프로그래밍이 가능하게 되는 것입니다.

그래서 이런 지역 변수의 특징을 구체화하는 과정에서 가장 손쉽고 오버헤드가 적게 드는 기법을 구현한 것이 바로 스택을 통한 지역 변수 관리 기법인 것입니다.(따라서 스택 변수는 곧 비정적 지역 변수가 됩니다.)

어쨌든 점점 프로그래밍이 고난이도 작업이 되고 그에 따라 요구 조건이 까다로워지면서 보다 다양한 개념의 메모리 및 변수 관리가 필요하였고 그에 따라 C/C++와 같은 언어에서는 직접 사용자가 메모리를 관리하는 포인터 및 동적 할당 개념이 생겨났습니다.

그런 와중에 '특정 scope를 가지면서 해당 변수의 storage duration scope에 상관없이 프로그램 실행 시간 내내 유지 될 수 있는' 그런 기법이 필요하게 되었습니다. 전역 변수는 프로그램 실행 시간 내내 유지되지만 대신 다른 블럭이나 모듈, 파일들에서 해당 변수를 참조할 수 있게 되고 그러면 프로그램의 안정성이 떨어질 수 있기 때문에, 가급적 참조 범위를 최소화하는 것을 미덕으로 여기는 프로그래밍 세계에서는 다른 대안을 필요로 한 것입니다.

한편, static 변수는 앞서 말한 바와 같이 컴파일 시점에 바인딩이 되는 변수입니다. 그런데 이 변수를 전역이 아닌 지역 변수로 선언을 한다면 뭔가 비 논리적인 상황이 발생합니다. 왜냐하면 지역 변수는 스택을 통해 관리되므로 그 속성(여러 속성들이 있겠지만 여기서는 메모리 주소값)이 수시로 바뀌게 되는데 이는 static의 원칙에 어긋나는 동작입니다.

결국 static 지역 변수는 허용을 하지 말거나 혹은 지역 변수와는 독립적인 처리가 필요하게 되었습니다. 그리고 C/C++ 에서는 후자를 선택하였습니다. 그 이유는 아마도 앞서 언급한 필요성 때문이 아닐까 생각합니다.(사실 위의 이야기들은 다 제가 추측한 이야기입니다. 실제로 어떤 이유로 static 지역 변수가 생겨났는지는 K&R만이 알겠죠...)

따라서 static으로 선언된 지역 변수는 다른 지역 변수와 달리 스택이 아니라 정적 영역에 할당이 됨으로써 해당 scope를 벗어나 스택이 해제되더라도 그 상태를 유지할 수 있게 되었습니다. 어차피 static 전역 변수 역시 정적 영역에 할당되므로 구현 상으로도 통일된 처리가 가능하여 이는 충분히 합리적인 결정이라 생각됩니다.

어쨌든 결국 static 지역 변수는 지역 변수의 일부 특성(scope)과 전역 변수의 일부 특성(static storage duration)을 갖는 독특한 존재가 됐습니다. 예를 들자면,

 

#include <iostream>

 

int sum(int a)

  {

  static int x = 0; /// 최초 sum 호출 시 한번 만 생성&초기화됨

  x += a;

  return x;         /// sum()함수 종료 시에도 소멸 안됨

  }

 

/* 1부터 100까지 합을 출력하는 프로그램*/

int main()

  {

  int i = 0;

  for (; i < 100; ++i)

    sum(i);

   

  std::cout << sum(100) << 'n';

 

  return 0;       /// main()함수 종료 시 sum()함수 내에 있는 x 변수 소멸

  }

 

이런 식의 사용이 가능합니다. ,

 

#include <iostream>

int* local_fun(int a)

  {

  int x = 0;

  x += a;

  return &x;

 

int* static_fun(int a)

  {

  static int x = 0;

  x += a;

  return &x;

  }

 

int main()

  {

  int* p = NULL;

  p = local_fun(3);

  std::cout << *p << 'n';   /// 비정상적인 값 출력

  p = static_fun(3);

  std::cout << *p << 'n';   /// 정상값(3) 출력

  return 0;

  }

 

이처럼 지역 변수의 경우 스택을 통해 메모리가 관리되므로 외부 참조가 불가능하지만 static 지역 변수의 경우 정적 영역에서 메모리가 관리되므로 포인터 혹은 레퍼런스를 통한 참조가 가능합니다. 여기서 scope에 대한 제약은 어떤 실행 메카니즘에 의한 것이 아니라 단지 컴파일러에 의한 문법 검사에 의한 것임을 알 수 있습니다.(이런 특징 때문에 static 객체는 singleton 패턴을 구현하는데 사용되기도 합니다.)

어쨋든 이렇게 static 객체는 전역 객체로 선언되면 internal linkage 특성을 가지지만 지역 객체로 선언될 경우 static storage duration 특성을 가지게 됩니다. 그리고 이런 특성이 모두 static이라고 하는 용어가 가진 개념에 의해 발생된 것임을 알 수 있습니다.

 

C++에서의 static

C에서 static이 가진 의미는 위에서 말한 두 가지가 전부입니다. 그러나 C++에서는 객체지향 패러다임이 도입되었고 그에 따라 클래스라고 하는 개념이 도입되었습니다.

클래스는 다 아시다시피 '무언가 공통된 책임을 수행하기 위해 같이 모아 놓으면 좋을 만한 변수와 함수들을 하나의 모듈로 캡슐화시킨 사용자 정의 타입'입니다. 그리고 이런 클래스 타입에 의해 생성된 변수들을 '객체(Object)'라고 합니다.

사실 이런 클래스나 객체라는 것은 이름은 그럴 듯 하지만 막상 그 세부 구조를 밑바닥까지 파헤쳐 보면 C에서 사용하는 구조체(structure)와 큰 차이가 없습니다. 멤버 변수들은 단지 구조체 멤버에 사용자 권한이라고 하는 컴파일 타임 제약 사항만을 추가한 것에 불과하며, 멤버 함수라고 하는 것은 실상 해당 클래스 객체의 포인터를 파라미터로 자동 추가해 주는 편이성 높은 함수에 불과합니다. ,

 

class CppClass

  {

  public:

    CppClass() : x_(0) {}

    void SetX(int a) { x_ = a; }

    int x_;

  }

 

위의 클래스를 C언어로 바꾸게 되면

 

struct CStruct

  {

  int x_;

  }

 

void CStruct_ctor(CStruct* this)

  {

  this->x_ = 0;

  }

 

void CStruct_SetX(CStruct* this, int a)

  {

  this->x_ = a;

  }

 

이렇게 됩니다. 그래서 실제 사용시에

 

CStruct tmp;

CStruct_ctor(&tmp);

CStruct_SetX(&tmp, 3);

 

이렇게 사용할 것을 클래스를 이용해서

 

CppClass tmp;

tmp.SetX(3);

 

이런 식으로 사용함으로써 생성자나 SetX()와 같은 멤버 함수가 CppClass라는 클래스의 객체에 밀접하게 관련되었다는 것을 프로그래머가 보기에 보다 직관적이 될 수 있도록 해준 장치에 불과합니다.

물론 이렇게 맥 빠지게 말을 하였지만 C++, JAVA, Smalltalk들과 같은 객체 지향 언어들은 객체 지향 패러다임을 통해 상속, 다형성, 캡슐화라는 다양한 장치를 제공하여 현재 가장 널리 사용되는 프로그래밍 언어인 것은 틀림없습니다.(적어도 이제 사람들이 더 이상 C를 반드시 배우려고 하지는 않습니다.)

어쨋든 객체 지향 언어들은 모든 프로그래밍을 객체 단위로 구현하고 조직화하게 되며 따라서 모든 변수들은 자신이 속한 객체와 그 생명 주기(life time)를 같이 합니다. 다시 말하면 멤버 변수의 scope storage duration은 자신이 속한 객체에 영향을 받는다는 뜻입니다.

그런데 여기서도 지역 변수에서와 유사한 문제가 발생합니다. , 클래스 멤버 변수 선언 시에 static을 앞에 붙히게 되면 어떻게 되느냐 하는 것입니다.

클래스 멤버 변수는 객체가 생성될 때 같이 생성되고 객체가 소멸될 때 같이 소멸됩니다. 게다가 객체가 지역 변수로 선언되면 멤버 역시 스택에 위치하게 되며 객체가 동적 할당되면 멤버 역시 동적 영역에 위치합니다.

그런데 앞서 언급했듯이 static은 지역 변수든 전역 변수든 상관없이 static storage duration을 갖습니다. 따라서 아무리 객체 지향이라 하더라도 이러한 기존의 법칙을 거스르는 행동을 하는 것은 논리적이지 못합니다.

따라서 이것 역시 두 가지 선택이 필요하게 되었습니다. 멤버 변수에 대한 static을 허용하느냐, 그렇지 않느냐...그리고 C++은 전자를 선택하였습니다. 단 이렇게 하고 나니 한 가지 문제가 발생하였습니다. static 멤버 변수를 허용하게 되면 기존의 static 특성을 따르기 위해서 static storage duration을 가져야 하고 그러려면 이 변수는 정적 영역에 위치하여야 하는데 객체는 반드시 정적 영역에 위치하리라는 보장이 없기 때문입니다.

결국 이런 모순을 해결하기 위해서는 static 멤버 변수를 객체에서 분리하여야 합니다. , 객체의 부분 집합으로써가 아니라 단지 클래스의 이름 공간에 한정 받는 전역 변수처럼 취급이 되는 것입니다. 다행스럽게도 이것은 기존의 static 정의에서 크게 벗어나지 않는 개념입니다. ,

 

  1. static 변수는 한 번 생성되면 프로그램 종료 시까지 계속 유지된다.(static storage duration)

  2. static 변수는 scope에 영향을 받는다.

    - 전역 객체는 정의된 파일 scope에 한정되어 참조 가능하며(internal linkage), 지역 객체는 정의된 local scope에 한정되어 참조 가능하다.(no linkage)

 

static 클래스 멤버 변수는 위의 정의에서 1번과 일치하며 2번의 경우 영향 받는 scope를 클래스 이름공간(namespace)라는 것으로 확장하여 생각하면 역시 문제될 것이 없습니다.

결국 static 클래스 멤버 변수는 객체와 상관없이 클래스 범위 연산자(::)를 통해서 참조가 가능한 독특한 특징을 가진 전역 객체가 되었으며 동시에 '객체가 몇 개가 생성되든 오직 하나만 존재함(singleton)'이라는 성질을 가지게 되었습니다.

실제 프로그래밍에서 static 멤버 변수는 어떤 클래스에 관련되지만 특정 객체에 영향을 받지 않는 성질을 가진 데이터를 취급하는데 아주 유용하게 사용됩니다. reference counter가 그 대표적인 예라 할 수 있습니다.

한편 클래스 멤버 함수는 다른 경우가 됩니다. 함수라는 것은 어차피 storage duration이라는 것이 존재하지 않기 때문에 일반 함수의 경우 static, non-static의 구분이 'internal linkage인가 아니면 external linkage인가'로 결정이 됩니다.

여기서 클래스 멤버 함수의 경우는 internal linkage라는 것이 큰 의미가 없습니다. 어차피 private이나 protected와 같은 권한 지정 키워드가 있기 때문에 얼마든지 사용 범위에 제한을 가할 수 있기 때문입니다. 따라서 이것 역시 두 가지 선택 사항이 존재하게 됩니다. 멤버 함수에 대해서 static을 허용하느냐 그렇지 않느냐...C++는 역시 허용하는 쪽에 손을 들어 줍니다.

사실 static이라는 키워드는 기본적으로 모든 선언문 형식에 들어갈 수 있는 storage class specifier라고 하는 지정자의 일종이기 때문에(C에서 그렇게 정의했기 때문에) 자꾸 이런 저런 제약을 가하는 것은 C의 자유로운 문법을 계승한 C++ 입장에서 그다지 바람직하지 않다라고 생각했을 것입니다.

어쨌든 멤버 함수에 static을 허용하였고 그에 따른 어떤 의미 부여가 필요하였습니다.(앞서 말한 대로 internal linkage라는 성질은 큰 의미가 없으므로...)

여기서 C++은 멤버 변수가 객체에 영향을 받지 않는 클래스 이름 공간에 속한 전역 객체로써 취급되었듯이 멤버 함수 역시 동일한 성질을 부여하게 됩니다. , static 멤버 함수는 객체가 없어도 호출이 가능하며 단지 클래스 이름 공간에 한정을 받는 함수가 된 것입니다. 따라서 static 멤버 함수는 다른 멤버 함수처럼 this 포인터를 암시적으로 받는 특성이 없이 일반 함수와 똑같은 호출 구조를 가지게 되었습니다. 결국

 

class StaticClass

  {

  public:

    static int x_;

    static int func() {};

  }

 

이것은

 

namespace gimmesilver

  {

  extern int x;

  int func() {};

  }

 

이것과 거의 동일한 특성을 가집니다. 따라서 non-static 멤버 함수들은 암묵적으로 넘겨받은 this 포인터를 통해서 해당 객체의 멤버 변수나 다른 non-static 멤버 함수를 참조/호출할 수 있지만 static 멤버 함수들은 그러한 참조할 만한 객체 포인터가 없으므로 객체의 멤버 변수나 non-static 멤버 함수를 참조/호출할 수 없는 것입니다.(이것 역시 초보자들이 흔히 하는 실수입니다.)

 

Post face

정리 들어갑니다...

 

static 변수

  1. static storage duration을 갖는다.

  2. scope의 영향을 받는다.

           - 전역 변수 : file scope의 영향을 받으며 internal linkage라고 한다.

           - 지역 변수 : block scope의 영향을 받는다.

           - 클래스 멤버 변수 : 클래스 이름공간의 영향을 받는 전역 객체이다.

   

static 함수

  1. 일반 함수 : internal linkage를 갖는다. , 외부 파일에서 해당 함수를 호출하지 못한다.

2. 클래스 멤버 함수 : this 포인터를 갖지 않는다. 따라서 객체의 멤버 변수나 멤버 함수를 직접 참조/호출할 수 없다. , 같은 클래스의 static 멤버 변수나 static 멤버 함수는 직접 참조/호출이 가능하다.

 

'Development > 기타' 카테고리의 다른 글

Mobile XE 설정하기  (0) 2010.08.24
[GPS]GPS모듈 구현중  (0) 2009.12.14
Mozilla XPCOM document  (0) 2009.10.25
[펌]회사에서 네이트 온 하기!!  (0) 2008.06.13
Creating Application with mozila  (0) 2008.05.13
Posted by 까 치
,

XPCOM

From MDC


An Introduction to XPCOM

A five part tutorial from IBM developerWorks: Part I, Part II, Part III, Part IV, Part V

XPCOM is a cross platform component object model, similar to Microsoft COM. It has multiple language bindings, letting the XPCOM components be used and implemented in JavaScript, Java, and Python in addition to C++. Interfaces in XPCOM are defined in a dialect of IDL called XPIDL.

XPCOM itself provides a set of core components and classes, e.g. file and memory management, threads, basic data structures (strings, arrays, variants), etc. The majority of XPCOM components is not part of this core set and is provided by other parts of the platform (e.g. Gecko or Necko) or by an application or even by an extension.


Documentation

Core XPCOM documentation

XPCOM API Reference
Documentation of core components, interfaces, and functions provided by XPCOM.
String, hashtable, and array guides
Using the basic data structures.
XPCOM Glue
The XPCOM Glue allows using XPCOM utility functions and classes, without having a dependency on unfrozen parts of XPCOM (xpcom_core.{dll,so,dylib}).

Creating XPCOM components

Creating XPCOM Components
This book provides a tutorial about building an XPCOM component that controls browsing behavior.
How to Build an XPCOM Component in Javascript
Quick-start guide for writing JavaScript components
How to Build an XPCOM Component in C++
Creating Custom Firefox Extensions with the Mozilla Build System . Don't let extensions in the title fool you - the article is mainly about binary components
Linux and Windows HowTo
Windows HowTo
Redux
OS/X HowTo

Miscellaneous

Using XPCOM in JavaScript without leaking
Using XPCOM in JavaScript (also known as XPConnect) is an environment where memory management issues are not obvious. Despite this, it's easy to write JavaScript code that leaks, because some of the objects you're dealing with are reference-counted behind the scenes.

View All...

Community

Tools

JavaScript Component Wizard
Visual C++ Component Wizard

Related Topics

Language Bindings, JavaXPCOM, XPConnect, PlXPCOM

'Development > 기타' 카테고리의 다른 글

[GPS]GPS모듈 구현중  (0) 2009.12.14
static 용어의 개념 및 성질  (0) 2009.10.25
[펌]회사에서 네이트 온 하기!!  (0) 2008.06.13
Creating Application with mozila  (0) 2008.05.13
xpcom  (0) 2008.05.11
Posted by 까 치
,

[출처] http://qwe1qwe.tistory.com/1057 펌글입니다.

Real Tunnel을 사용해서 회사에서 네이트온을 하는 방법입니다.

1. Real Tunnel down

 사용자 삽입 이미지

real turnel 의 홈에서 사용자 등록을 통해 ID/PS 받음.

사용자 삽입 이미지

2. MSN 의 환경을 복사 후에 nate on 환경에 적용함

사용자 삽입 이미지


마지막 과정 접속!!

'Development > 기타' 카테고리의 다른 글

static 용어의 개념 및 성질  (0) 2009.10.25
Mozilla XPCOM document  (0) 2009.10.25
Creating Application with mozila  (0) 2008.05.13
xpcom  (0) 2008.05.11
하나포스 FTP계정  (0) 2008.03.23
Posted by 까 치
,
http://www.csie.ntu.edu.tw/~piaip/docs/CreateMozApp/index.html
http://blog.naver.com/choi2song?Redirect=Log&logNo=80025162484
http://developer.mozilla.org/en/docs/How_to_Build_an_XPCOM_Component_in_Javascript
http://www.builderau.com.au/program/soa/Creating-XPCOM-components-with-JavaScript/0,339024614,339206503,00.htm
http://forums.mozillazine.org/viewtopic.php?t=308369
http://publib.boulder.ibm.com/infocenter/wasinfo/v4r0/index.jsp?topic=/com.ibm.websphere.v4.doc/wasee_content/corbaio/ref/rcidlatd.htm

'Development > 기타' 카테고리의 다른 글

Mozilla XPCOM document  (0) 2009.10.25
[펌]회사에서 네이트 온 하기!!  (0) 2008.06.13
xpcom  (0) 2008.05.11
하나포스 FTP계정  (0) 2008.03.23
eclips debug  (0) 2008.03.23
Posted by 까 치
,