이중 포인터 읽기 질문드립니다.
글쓴이: kysu5095 / 작성시간: 토, 2020/04/25 - 4:34오전
이중포인터가 매개변수인 함수에서 매개변수의 값을 출력하고 싶습니다.
아래 코드의 func의 매개변수값이 void형 이중포인터 val값인 1을 출력하고 싶습니다.
void형이기때문에 일단 int형 포인터로 바꿔줘야할 거 같아서 (int*)val로 바꾸고
역참조를 두번해야해서 **(int*)val이나 *&(int*)val을 해주어야 한다고 생각했는데
둘 다 오류가 뜨네요ㅠㅠ 어떤 방식으로 출력해야 하나요???
// 함수 원형 void func(void** val){ printf("%d\n", ???); } // 전달할 인자 int val = 1; void* deliver_val = &val; func(&deliver_val);
Forums:
일단 체크할 사항이 굳이 void 형으로 받을 필요가
일단 체크할 사항이 굳이 void 형으로 받을 필요가 있나요?
int *deliver_val 이 맞을까요? int **deliver_val이 맞을까요?
한번만 참조하면 주소값이 나오더라고요,,
*(int*)val << 이렇게 참조하면 val의 주솟값이 나와서요,,,
*(int *)val은 *val과 똑같습니다. 그래서
*(int *)val은 *val과 똑같습니다. 그래서 주소값이 나오는 것이지요.
int **deliver_val 로 하시고, func(int** val) 로 하시고, **val로 하시면 값이 나올 겁니다.
답변 감사합니다. 제가 void로 사용한 것은
답변 감사합니다. 제가 void로 사용한 것은 사용하는 함수의 파라미터가 void형으로 되어있어서 그랬습니다.
라스코니님의 형식을 응용하여 해결하였습니다. 감사합니다!!!
고민하실 때, void 와 void *를 다르게
고민하실 때, void 와 void *를 다르게 생각하셔야합니다.
전자는 참조를 할 수 없지만, 후자는 포인터로서 일단 한번의 참조는 가능합니다.
(크기를 말할 때도 표준은 void에 대한 크기는 정해지지 않았습니다만 포인터는 정해져있죠.)
func가 받는 void ** val을 *val 로 참조하면 void *가 됩니다. 이것을 int *로 캐스팅하다음 다시 참조해야 int로 접근이 가능합니다.
*(int *) val
---
http://coolengineer.com
*(int*)retval은 void* retval같이
*(int*)retval은 void* retval같이 일차원 포인터형이 인자로 들어올 때 값을 참조하고
더블형 포인터인 void** retval을 위와같이 참조하면 retval의 주솟값(인자로 보낸값의)이 나오더라구요..
*(int **) var 이걸 출력하면 되지 않을까요
*(int **) var 이걸 출력하면 되지 않을까요?
답변 감사합니다. *(int**)var을 해요 똑같이
답변 감사합니다. *(int**)var을 해요 똑같이 주솟값이 나옵니다ㅠ
compiler는 format %d expects argument of type int, but argument 3 has type int* 타입이 안맞다네요ㅠ
c에서 주로 사용하는 포인터는 *, ** 입니다.
c에서 주로 사용하는 포인터는 *, ** 입니다. 간혹 *** 도 사용하는 경우도 있습니다.
아래 코드를 보시고, 써먹는 법을 익히면 되겠습니다. 그냥 외워서 함수로 만들어서 ruby, 자바 써먹듯이 그렇게 써먹으면 편합니다.
와 정말 감사합니다. 이렇게 한번에 보니깐 확실히
와 정말 감사합니다. 이렇게 한번에 보니깐 확실히 이해가 잘 되네요ㅠ
추가적으로 궁금한게 있는데 func2에서 (int**)에서 *을 왜 2개 사용하신 건가요??
위 코드도 돌아가고 제가 생각한 (int*)으로 사용해도 똑같은 결과가 나오더라구요
void ** 이라서 타입을 맞추기 위해 int **
void ** 이라서 타입을 맞추기 위해 int ** 했습니다.
아, 제가 말로 설명한 것과 코드를 잘못썼군요.
아, 제가 말로 설명한 것과 코드를 잘못썼군요.
제 설명에 대한 코드는 위와 같아야합니다. ;-)
---
http://coolengineer.com
음 ..
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
감사합니다!!. 위에 분과 마찬가지로 한번에 여러
감사합니다!!. 위에 분과 마찬가지로 한번에 여러 동작을 보니 이해가 훨씬 잘 되는것 같습니다.
여기서도 궁금한게 있는데 func2에 *(int *)*(int **)val 에서 (int*)을 하고 또 (int**)을 하신 이유가 있을까요?
제 딴에서는 이해가 잘 되지 않아서요ㅠㅠ
음 ..
void 는 type 이 없기 때문에, void pointer 는 dereference 할 수 없습니다.
실제 type 을 모르면 dereference 할 때, 해당 주소에서 몇 바이트를 읽어와야 할 지 알 수 없기 때문입니다.
그래서 void ptr 로 받으면, 원하는 data type 의 ptr 로 casting 해서 써야 합니다.
원래는 **(int **)val 과 같이 바로 접근하면 되는데..
어떤 원리로 그렇게 되는지 보이기 위해 풀어서 쓴 겁니다.
dereference 연산자는 변수에 가장 가까운 녀석부터 해석됩니다.
그걸 보이기 위해 func() 에서 *(*val) 을 일부러 넣었습니다.
(int **)val 을 dereference 하면, 이 값의 type 은 int * 가 되기 때문에..
(int *)*(int **)val 과 같이 (int *) 를 붙여서 int * 임을 보인거고..
*(int *)*(int **)val 과 같이 한 번 더 dereference 하면, 원래의 int 값이 들어가게 되는거죠.
사실상 *(int **)val 의 type 은 int * 이기 때문에, 필요 없으므로 빼면 됩니다.
결과적으로 double pointer 는 **(int **)val 과 같이 ** 로 dereference 한다는 것만 남는거죠.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
명쾌한 설명입니다. 초보자분들께서는 잘 이해가 되지
명쾌한 설명입니다. 초보자분들께서는 잘 이해가 되지 않으실텐데, 일단, 포인터 써먹는 법 외우시고 포인터 써먹는데도 문제가 없게 하시고, 그렇게 시간이 1년, 2년 지나면 포인터가 뭔지 이해가 되는 때가 올 겁니다. 그 때 되면.. 아하~~~~~~~~~~~~ kldp 에서 그 ymir님이.. 한 말이 그말이구나.. 떠오를겁니다.
c 어렵다고 회피하지 마시고, 포인터 부분은 활용법을 일단 외우세요.
집에서 열공하면서 코로나를 극복합시다.
아자~~~~~~ 아자 화이팅~~~~~~~~~~!!!!!
댓글 달기