역참조 편집하기

이동: 둘러보기, 검색

경고: 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. 로그인하거나 계정을 생성하면 편집자가 아이디(ID)으로 기록되고, 다른 장점도 있습니다.

편집을 되돌릴 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.
최신판 당신의 편집
1번째 줄: 1번째 줄:
'''역참조'''(dereference)란 프로그래밍에서 [[데이터]]가 저장된 [[주소]]로 가서, 그 주소에 해당하는 데이터 값에 접근하는 것을 말한다. [[포인터]](pointer)는 데이터가 저장된 주소값을 가리키지만, 역참조는 그 반대로 주소를 통해 데이터에 접근한다.
+
'''역참조'''란 프로그래밍에서 포인터는 데이터가 저장된 주소값을 가리키지만 데이터가 저장된 주소로 가서 값에 접근 하는것을 역참조라고 한다.
  
 
== 개요 ==
 
== 개요 ==
역참조는 값에 직접 접근하는 것이 아니라 [[주소]]를 이용해 간접적으로 접근하는 것이다. 그래서 [[간접연산자]]라고도 한다. 이제까지 [[함수]]에서 [[매개변수]]를 통해 [[인자]]를 전달하는 등 모든 데이터를 복사해서 썼다면, 역참조를 하면 원본에 접근 가능하다. 즉 컴퓨터 구조에서(CPU, 메모리 등) 데이터를 오랫동안 메모리에 저장할 수 있다. 역참조 원리는 먼저 포인터를 지정하고 있는 메모리 위치로 간 다음 그곳에 지정된 값에 접근하는 원리이다.<ref>hahehohoo, 〈[https://bite-sized-learning.tistory.com/265 포인터 이해하기2_참조와 역참조/역 참조 연산자]〉, 《티스토리》, 2020-07-18</ref>
+
역참조는 값에 직접 접근하는것이 아닌 주소를 이용해 간접적으로 접근하는 것이다. 그래서 간접 연산자라고도 한다. 이제까지 함수에서 매개변수를 통해 인자를 전달하는 등 모든 데이터를 복사해서 썼다면 역참조를 하면 원본에 접근가능하다. 즉 컴퓨터 구조에서(CPU, 메모리 등) 데이터를 오랫동안 메모리에 저장할 수 있다.
 
+
* '''역참조 원리'''
== 예제 ==
+
:* 1. 포인터를 지정하고 있는 메모리 위치로 간다.
포인터 연산으로 조작한 메모리 주소도 역참조 연산을 사용하여 메모리에 접근할 수 있다.
+
:* 2. 그곳에 저장된 값에 접근한다.<ref>hahehohoo, 〈[https://bite-sized-learning.tistory.com/265 포인터 이해하기2_참조와 역참조/역 참조 연산자]〉, 《티스토리》, 2020-07-18</ref>
#include <stdio.h>
 
 
 
int main()
 
{
 
    int numArr[5] = { 11, 22, 33, 44, 55 };
 
    int *numPtrA;
 
    int *numPtrB;
 
    int *numPtrC;
 
 
    numPtrA = numArr;    // 배열 첫 번째 요소의 주소를 포인터에 저장
 
 
    numPtrB = numPtrA + 1;    // 포인터 연산. numPtrA + 4바이트
 
    numPtrC = numPtrA + 2;    // 포인터 연산. numPtrA + 8바이트
 
 
    printf("%d\n", *numPtrB);    // 22: 역참조로 값을 가져옴, numArr[1]과 같음
 
    printf("%d\n", *numPtrC);    // 33: 역참조로 값을 가져옴, numArr[2]와 같음
 
 
    return 0;
 
}
 
 
 
실행 결과
 
22
 
33
 
 
 
numPtrB에는 numPtrA에 1을 더해서 4바이트만큼 순방향으로 이동한 메모리 주소를 저장했고, numPtrC에는 numPtrA에 2를 더해서 8바이트만큼 순방향으로 이동한 메모리 주소를 저장했다.
 
 
 
numPtrB = numPtrA + 1;    // 포인터 연산. numPtrA + 4바이트
 
numPtrC = numPtrA + 2;    // 포인터 연산. numPtrA + 8바이트
 
 
 
numPtr8와 numPtrC도 일반 포인터이므로 * (역참조 연산자)를 사용하여 메모리의 값을 가져올 수 있다. 여기서 포인터 연산은 결과적으로 numPtrA + 1과 numArr[1]은 같고, numPtrA와 numArr[2]는 같다.
 
 
 
printf("%d\n", *numPtrB);    // 22: 역참조로 값을 가져옴, numArr[1]과 같음
 
printf("%d\n", *numPtrC);    // 33: 역참조로 값을 가져옴, numArr[2]와 같음
 
 
 
포인터 연산과 동시에 역참조 연산을 사용하는 법은 다음과 같다. 포인터 연산을 한 부분을 () 괄호로 묶어준 뒤 맨 앞에 *를 붙이면 된다.<ref>〈[https://dojang.io/mod/page/view.php?id=510 C 언어 코딩 도장:59.2 포인터 연산과 역참조 사용하기]〉, 《코딩도장》</ref>
 
 
 
struct Object {
 
    int key;
 
    int value;
 
};
 
 
 
위 구조체를 이용하여 배열을 만들었을 때의 값이다.
 
 
 
struct Object array[3] = { { 1, 10 }, { 2, 20 }, { 3, 30 } };
 
struct Object *ptr = array;
 
 
 
printf("%d\n", ptr->key)   // 1
 
printf("%d\n", ptr->value)   // 10
 
printf("%d\n", (ptr + 1)->key)   // 2
 
printf("%d\n", (ptr + 1)->value)  // 20
 
printf("%d\n", (ptr + 2)->key)   // 3
 
printf("%d\n", (ptr + 2)->value)  // 30
 
 
 
포인터 연산과 역참조를 이용해 구조체 배열과 동일하게 값을 저장할 수도 있다.
 
 
 
void *ptr = malloc(24);
 
 
 
*((int *)ptr) = 1;
 
*((int *)ptr + 1) = 10;
 
*((int *)ptr + 2) = 2;
 
*((int *)ptr + 3) = 20;
 
*((int *)ptr + 4) = 3;
 
*((int *)ptr + 5) = 30;
 
 
 
printf("%d\n", *((char *)ptr));   // 1
 
printf("%d\n", *((char *)ptr + 4));   // 10
 
printf("%d\n", *((char *)ptr + 8));   // 2
 
printf("%d\n", *((char *)ptr + 12));   // 20
 
printf("%d\n", *((char *)ptr + 16));   // 3
 
printf("%d\n", *((char *)ptr + 20));   // 30<ref>emplam27, 〈[https://velog.io/@emplam27/C%EC%96%B8%EC%96%B4-void-%ED%8F%AC%EC%9D%B8%ED%84%B0%EC%9D%98-%EC%97%B0%EC%82%B0%EA%B3%BC-%EC%97%AD%EC%B0%B8%EC%A1%B0 void 포인터의 연산과 역참조]〉, 《벨로그》, 2021-01-26</ref>
 
  
 
{{각주}}
 
{{각주}}
  
 
== 참고자료 ==
 
== 참고자료 ==
* hahehohoo, 〈[https://bite-sized-learning.tistory.com/265 포인터 이해하기2_참조와 역참조/역 참조 연산자]〉, 《티스토리》, 2020-07-18
 
* 〈[https://dojang.io/mod/page/view.php?id=510 C 언어 코딩 도장:59.2 포인터 연산과 역참조 사용하기]〉, 《코딩도장》
 
* emplam27, 〈[https://velog.io/@emplam27/C%EC%96%B8%EC%96%B4-void-%ED%8F%AC%EC%9D%B8%ED%84%B0%EC%9D%98-%EC%97%B0%EC%82%B0%EA%B3%BC-%EC%97%AD%EC%B0%B8%EC%A1%B0 void 포인터의 연산과 역참조]〉, 《벨로그》, 2021-01-26
 
  
 
== 같이 보기 ==
 
== 같이 보기 ==
* [[참조]]
 
* [[포인터]]
 
* [[C언어]]
 
 
{{프로그래밍|검토 필요}}
 

위키원에서의 모든 기여는 다른 기여자가 편집, 수정, 삭제할 수 있다는 점을 유의해 주세요. 만약 여기에 동의하지 않는다면, 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다 (자세한 사항은 위키원:저작권 문서를 보세요). 저작권이 있는 내용을 허가 없이 저장하지 마세요!

취소 | 편집 도움말 (새 창에서 열림)