logo

C 이중 포인터(포인터 대 포인터)

우리가 알고 있듯이 포인터는 C에서 변수의 주소를 저장하는 데 사용됩니다. 포인터는 변수의 액세스 시간을 줄여줍니다. 그러나 C에서는 다른 포인터의 주소를 저장하는 포인터를 정의할 수도 있습니다. 이러한 포인터를 이중 포인터(포인터에 대한 포인터)라고 합니다. 첫 번째 포인터는 변수의 주소를 저장하는 데 사용되고 두 번째 포인터는 첫 번째 포인터의 주소를 저장하는 데 사용됩니다. 아래의 도표를 통해 이해해 봅시다.

C의 포인터에 대한 포인터

이중 포인터를 선언하는 구문은 다음과 같습니다.

 int **p; // pointer to a pointer which is pointing to an integer. 

다음 예를 고려하십시오.

문자열 분할 C++
 #include void main () { int a = 10; int *p; int **pp; p = &a; // pointer p is pointing to the address of a pp = &p; // pointer pp is a double pointer pointing to the address of pointer p printf('address of a: %x
',p); // Address of a will be printed printf('address of p: %x
',pp); // Address of p will be printed printf('value stored at p: %d
',*p); // value stoted at the address contained by p i.e. 10 will be printed printf('value stored at pp: %d
',**pp); // value stored at the address contained by the pointer stoyred at pp } 

산출

 address of a: d26a8734 address of p: d26a8738 value stored at p: 10 value stored at pp: 10 

C 이중 포인터 예제

한 포인터가 다른 포인터의 주소를 가리키는 예를 살펴보겠습니다.

C 포인터 대 포인터 예제

위 그림에서 볼 수 있듯이 p2에는 p의 주소(fff2)가 포함되고, p에는 number 변수의 주소(fff4)가 포함됩니다.

 #include int main(){ int number=50; int *p;//pointer to int int **p2;//pointer to pointer p=&number;//stores the address of number variable p2=&p; printf('Address of number variable is %x 
',&number); printf('Address of p variable is %x 
',p); printf('Value of *p variable is %d 
',*p); printf('Address of p2 variable is %x 
',p2); printf('Value of **p2 variable is %d 
',*p); return 0; } 

산출

 Address of number variable is fff4 Address of p variable is fff4 Value of *p variable is 50 Address of p2 variable is fff2 Value of **p variable is 50 

Q. 다음 프로그램의 출력은 무엇입니까?

 #include void main () { int a[10] = {100, 206, 300, 409, 509, 601}; //Line 1 int *p[] = {a, a+1, a+2, a+3, a+4, a+5}; //Line 2 int **pp = p; //Line 3 pp++; // Line 4 printf('%d %d %d
',pp-p,*pp - a,**pp); // Line 5 *pp++; // Line 6 printf('%d %d %d
',pp-p,*pp - a,**pp); // Line 7 ++*pp; // Line 8 printf('%d %d %d
',pp-p,*pp - a,**pp); // Line 9 ++**pp; // Line 10 printf('%d %d %d
',pp-p,*pp - a,**pp); // Line 11 } 

설명

이중 포인터 질문

위의 질문에서는 포인터 연산이 이중 포인터와 함께 사용됩니다. 포인터 p의 배열이 가리키는 6개 요소의 배열이 정의됩니다. 포인터 배열 p는 이중 포인터 pp에 의해 지정됩니다. 그러나 위 이미지는 메모리가 배열 a와 포인터 배열 p에 할당되는 방법에 대한 간략한 아이디어를 제공합니다. p의 요소는 배열 a의 모든 요소를 ​​가리키는 포인터입니다. 배열 이름에 배열의 기본 주소가 포함되어 있으므로 포인터로 작동하고 *(a), *(a+1) 등을 사용하여 값을 탐색할 수 있습니다. 이미지에 표시된 대로 , a[0]은 다음과 같은 방법으로 액세스할 수 있습니다.

  • a[0]: 배열의 첫 번째 요소에 액세스하는 가장 간단한 방법입니다.
  • *(a): 배열의 첫 번째 요소 주소를 저장하므로 해당 요소에 대한 간접 포인터를 사용하여 해당 값에 액세스할 수 있습니다.
  • *p[0]: 포인터 p를 사용하여 a[0]에 액세스하려면 포인터 배열 p의 첫 번째 요소, 즉 *p[0]에 간접 연산자(*)를 사용할 수 있습니다.
  • **(pp): pp는 포인터 배열의 기본 주소를 저장하므로 *pp는 정수 배열의 첫 번째 요소 주소인 포인터 배열의 첫 번째 요소 값을 제공합니다. **p는 정수 배열의 첫 번째 요소의 실제 값을 제공합니다.

프로그램에 들어가면 1행과 2행에서는 정수와 포인터 배열을 상대적으로 선언합니다. 3행에서는 포인터 배열 p에 대한 이중 포인터를 초기화합니다. 이미지에 표시된 것처럼 배열의 주소가 200부터 시작하고 정수의 크기가 2인 경우 포인터 배열에는 200, 202, 204, 206, 208, 210의 값이 포함됩니다. 포인터 배열의 기본 주소는 300입니다. 이중 포인터 pp에는 포인터 배열의 주소(예: 300)가 포함됩니다. 줄 번호 4는 pp의 값을 1만큼 증가시킵니다. 즉, pp는 이제 주소 302를 가리킵니다.

문자열 n 자바

5번 줄에는 pp - p, *pp - a, **pp 등 세 가지 값을 인쇄하는 표현식이 포함되어 있습니다. 그들 각각을 계산해 봅시다.

  • pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, 즉 1이 출력됩니다.
  • pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, 즉 1이 인쇄됩니다.
  • pp = 302, *pp = 202, *(*pp) = 206, 즉 206이 인쇄됩니다.

따라서 라인 5의 결과로 출력 1, 1, 206이 콘솔에 인쇄됩니다. 6번째 줄에는 *pp++를 씁니다. 여기서 우리는 두 개의 단항 연산자 *와 ++가 동일한 우선순위를 갖는다는 점에 주목해야 합니다. 따라서 연관성의 규칙에 따라 오른쪽에서 왼쪽으로 평가됩니다. 따라서 *pp++ 표현식은 (*(pp++))로 다시 쓸 수 있습니다. pp = 302이므로 이제 304가 됩니다. *pp는 204를 제공합니다.

7행에는 pp-p, *pp-a, *pp 등 세 가지 값을 인쇄하는 표현식이 다시 작성됩니다. 각각을 계산해 봅시다.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, 즉 2가 인쇄됩니다.
  • pp = 304, *pp = 204, a = 200 => *pp-a = (204 - 200)/2 = 2, 즉 2가 인쇄됩니다.
  • pp = 304, *pp = 204, *(*pp) = 300, 즉 300이 인쇄됩니다.

따라서 7행의 결과로 출력 2, 2, 300이 콘솔에 인쇄됩니다. 8행에는 ++*pp가 작성됩니다. 결합성 규칙에 따라 이는 (++(*(pp)))로 다시 작성할 수 있습니다. pp = 304, *pp = 204이므로 *pp = *(p[2]) = 206의 값은 이제 a[3]을 가리킵니다.

C의 문자열

9행에는 pp-p, *pp-a, *pp라는 세 가지 값을 인쇄하는 표현식이 다시 작성됩니다. 각각을 계산해 봅시다.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, 즉 2가 인쇄됩니다.
  • pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, 즉 3이 인쇄됩니다.
  • pp = 304, *pp = 206, *(*pp) = 409, 즉 409가 인쇄됩니다.

따라서 9행의 결과로 출력 2, 3, 409가 콘솔에 인쇄됩니다. 10번째 줄에는 ++**pp를 씁니다. 결합성 규칙에 따라 이는 (++(*(*(pp))))로 다시 작성할 수 있습니다. pp = 304, *pp = 206, **pp = 409, ++**pp => *pp = *pp + 1 = 410. 즉, a[3] = 410입니다.

11번째 줄에는 pp-p, *pp-a, *pp라는 세 가지 값을 인쇄하는 표현식이 다시 작성됩니다. 각각을 계산해 봅시다.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, 즉 2가 인쇄됩니다.
  • pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, 즉 3이 인쇄됩니다.
  • 8행에서는 **pp = 410입니다.

따라서 9행의 결과로 출력 2, 3, 410이 콘솔에 인쇄됩니다.

마지막으로 전체 프로그램의 출력은 다음과 같이 제공됩니다.

산출

 1 1 206 2 2 300 2 3 409 2 3 410