gmp (gnu multiprecision) 라이브러리를 쓸 일이 있어서 메뉴얼과 헤더파일을 보던 중 재밌는 코드를 발견!
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
typedef __mpz_struct mpz_t[1];
이 부분에 대해서 메뉴얼은 다음과 같이 설명하고 있다.
For interest, the GMP types mpz_t etc are implemented as one-element arrays of certain structures. This is why declaring a variable creates an object with the fields GMP needs, but then using it as a parameter passes a pointer to the object. Note that the actual fields in each mpz_t etc are for internal use only and should not be accessed directly by code that expects to be compatible with future GMP releases.
이 정의를 활용하는 코드를 보면 다음과 같다.
void
foo (mpz_t result, const mpz_t param, unsigned long n)
{
unsigned long i;
mpz_mul_ui (result, param, n);
for (i = 1; i < n; i++)
mpz_add_ui (result, result, i*7);
}
int
main (void)
{
mpz_t r, n;
mpz_init (r);
mpz_init_set_str (n, “123456”, 0);
foo (r, n, 20L);
gmp_printf (“%Zd\n”, r);
return 0;
}
foo (mpz_t result, const mpz_t param, unsigned long n)
{
unsigned long i;
mpz_mul_ui (result, param, n);
for (i = 1; i < n; i++)
mpz_add_ui (result, result, i*7);
}
int
main (void)
{
mpz_t r, n;
mpz_init (r);
mpz_init_set_str (n, “123456”, 0);
foo (r, n, 20L);
gmp_printf (“%Zd\n”, r);
return 0;
}
이렇게 선언해 놓고 참조하면 자연스럽게 함수 호출할 때 call-by-reference가 가능하다. c언어의 묘미란 이런게 아닐까?
다음과 같은 활용도 가능할듯
1..문자열형 만들기
typedef char[] String; //typedef char* String; 도 가능할 듯
//테스트 해보지 않아서 되는지는 모름
2.클래스 포인터 없이 생성하고 사용하기
typedef class Test
{
public:
엠버들
}Test;
Test t = new T();
//↑역시 테스트 해보지 않아서 어찌 될련지는..
혹은..
class Test
{
public:
멤버들
};
typedef Test* test;
이런식으로 해서
test t = new test(); // 잘 될련지는..
test t = new Test(); // 이것도 마찬가지.. 둘중 하나만 되거나 다 안되거나.. 할거 같음.
테스트 해보고 알려 주시면 좋았을 것을… ^^; 최근에는 function pointer type을 typedef로 놓고 사용하니 정말 편리하더라구요. 워낙 parameter가 많은 함수였거든요.
몇몇은 되는거 같더군요.. 다시 테스트해봐야지.. 그리고.. 근래에 C++빌더로 이벤트 만들어보는 연습하다가 알게 됬는데.. typedef가 함수 포인터까지 자료형화 해버리네요..
즉 typedef void (*pFunc)();
하면 나중에
pFunc Func1, Func2;
Func1 = Func; //Func() 함수가 있다고 가정
Func2 = TestFunc; //이것역시 있다고 가정
…
Func1();
Func2();
…
식의 기묘한 코드가 가능함..
위에 가능할것 같다고 한 소스를 직접 확인해봤는데 확인결과 아래 2가지만 에러없이 컴파일되고 실행되네요..
1.문자열
#include
typedef char* String; //typedef char[] String; 하면 에러남
void main()
{
String str = “테스트”;
printf(“%s\n”,str);
}
2.포인터 없이 객체 생성, 사용하기
– 클래스에 직접 적용
#include
typedef class Test
{
public:
int a;
}* test;
void main()
{
test t = new Test(); //test t = new test(); 하면 에러남
t->a = 5;
printf(“%d\n”,t->a);
delete t;
}
-별도로 지정
#include
class Test
{
public:
int a;
};
typedef Test* test;
void main()
{
test t = new Test(); //test t = new test(); 하면 에러남
t->a = 5;
printf(“%d\n”,t->a);
delete t;
}
좋은 글에 거지같은 리플이네요.