programing

포인터 표현: **ptr++*++*ptr 및 ++**ptruse

powerit 2023. 10. 5. 23:37
반응형

포인터 표현: **ptr++*++*ptr 및 ++**ptruse

나는 C 포인터 문헌에 손을 대고 있습니다.한 삽화에서 다음과 같은 코드를 접했습니다.

# include <stdio.h>

int main()
{
     static int a[]={0,1,2,3,4};
     static int *p[]={a, a+1, a+2, a+3, a+4};

     int **ptr;

     ptr =p;

     **ptr++;
     printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

     *++*ptr; 
     printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

     ++**ptr;
     printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

     return 0;
}

저는 출력물을 로 받습니다.

1 1 1
1 2 2
1 2 3

이 출력을 정당화하는 데 문제가 있습니다.저는 문제를 쉽게 파악하기 위해 복사판에 상자를 많이 만들었습니다.출력을 정당화할 수 있습니다.1 1 1, 내 문제는 그 진술로부터 시작됩니다.*++*ptr.

단항 연산자는 오른쪽에서 왼쪽으로 실행되기 때문에,*ptr먼저 대처한 다음에 가치가 있습니다.ptr증가할 것입니다.이 증가 후에, 무슨 일이 일어날지 확실하지 않아요, 책은 어떻게든 그렇게 말하고 있습니다.p는 또한 이 배열의 다음 요소를 가리키도록 증분됩니다.산출량1 2 2다음의 증분을 통해서만 달성할 수 있습니다.p.

이런 질문이 스택 오버플로우에 정확히 맞는지 잘 모르겠습니다.
저는 최선을 다해 노력했고, 상자들이 그려진 채로 적어도 10페이지를 낭비했습니다.

어떤 해명이라도 해주시면 감사하겠습니다.

배열 이름은 대부분의 식에서 첫 번째 요소에 대한 포인터로 쉽게 붕괴될 수 있음을 기억하십시오(배열 이름이 첫 번째 요소에 대한 포인터로 붕괴되지 않는 일부 예외를 읽습니까? @HCO23 의해 가능하게 응답됨).
더 나은 이해를 위해 내 다이어그램을 고려해 보십시오.

먼저, 다음과 같이 가정합니다.a다음과 같이 메모리에 저장됩니다.

  a 
+----+----+----+----+---+
|  0 |  1 | 2  | 3  | 4 |
+----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲
  |    |    |    |    | 
  a    a+1  a+2  a+3  a+3

선언.static int *p[] = {a, a+1, a+2, a+3, a+4};는 다음 값을 사용하여 정수에 대한 포인터 배열을 새로 만듭니다.

p[0] == a
p[1] == a + 1
p[2] == a + 2
p[3] == a + 3
p[4] == a + 4

지금이다,p다음과 같이 메모리에 저장된다고 가정할 수도 있습니다.

  p
+----+----+----+----+-----+
| a  |a +1| a+2| a+3| a+4 | 
+----+----+----+----+-----+
  ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |
  p    p+1  p+2  p+3  p+4

과제후ptr = p;상황은 다음과 같습니다.

  p                              a 
+----+----+----+----+-----+    +----+----+----+----+---+
| a  |a +1| a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 |
+----+----+----+----+-----+    +----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |          |    |    |    |    | 
  p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3
  ptr 


Notice: ptr points to first location in pointer array p[]

식: **ptr++;

이제 우리는 표현을 생각해 봅니다.**ptr++;첫번째 printf 진술 전에.

  1. ptr와 같음.p그것은 포인터 배열의 첫번째 요소의 주소입니다.이런 이유로,ptr첫번째 요소를 가리키다p[0]줄을 지어 (아니면 우리는 말할 수 있습니다)ptr==&p[0]).

  2. *ptr수단p[0]그 이유는p[0]a,그렇게*ptra(그러니까)*ptr==a).

  3. 그 이유는*ptra,그리고나서**ptr*a==*(a + 0)==a[0]그것은0.

  4. 식에 있는 참고**ptr++;, 우리는 그 값을 lhs 변수에 할당하지 않습니다.
    그래서 의 효과**ptr++;와 단순히 같습니다.ptr++;==ptr = ptr + 1=p + 1
    이 식후에 이런 식으로ptr가리킴p[1](아니면 우리는 말할 수 있습니다.ptr==&p[1]).

인쇄-1:

처음 인쇄하기 전에 다음 사항을 수행합니다.

  p                              a 
+----+----+----+----+-----+    +----+----+----+----+---+
| a  | a+1| a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 |
+----+----+----+----+-----+    +----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |          |    |    |    |    | 
  p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3
       ptr 


Notice: ptr is equals to  p + 1 that means it points to p[1]

이제 First printf를 이해할 수 있습니다.

  1. ptr - p산출량1이유:
    ptr = p + 1,그렇게ptr - p==p + 1 - p==1

  2. *ptr - a산출량1이유:
    ptr = p + 1,그렇게*ptr==*(p + 1)==p[1]==a + 1
    이것은 다음을 의미합니다.*ptr - a=a + 1 - a==1

  3. **ptrt1이유:
    *ptr==a + 1점-2부터
    그렇게**ptr==*(a + 1)==a[1]==1

식: *++*ptr;

번째 는 식 가 있습니다.*++*ptr;.

본 -2.*ptr==p[1].그렇게,++*ptr,)++p[1]) 윌 증분(will increments)p[1].a + 2

합니다에서 *++*ptr;다의 에는 그 *++*ptr;정당합니다++*ptr;.

자, 이제 두 번째 인쇄가 시작되기 전에:

  p                              a 
+----+----+----+----+-----+    +----+----+----+----+---+
| a  |a+2 | a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 |
+----+----+----+----+-----+    +----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |          |    |    |    |    | 
  p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3
       ptr 


Notice: p[1] became a + 2 

인쇄-2:

이제 두 번째 인쇄물을 이해할 수 있습니다.

  1. ptr - pt1이유:
    ptr = p + 1,그렇게ptr - p==p + 1 - p==1

  2. *ptr - at2이유:
    ptr = p + 1그렇게*ptr==*(p + 1)==p[1]==a + 2
    이것은 다음을 의미합니다.*ptr - a==a + 2 - a==2

  3. **ptrt2이유:
    *ptr==a + 2점-2부터
    그렇게**ptr==*(a + 2)==a[2]==2

식: ++**ptr;

++**ptr;세 번째 인쇄 전에

에서 본 3번 **ptr==a[2].그렇게++**ptr==++a[2]가 점증하는a[2].3

따라서 세 번째 인쇄 전에는 다음과 같은 작업이 수행됩니다.

  p                              a 
+----+----+----+----+-----+    +----+----+----+----+---+
| a  | a+2| a+2| a+3| a+4 |    |  0 |  1 | 3  | 3  | 4 |
+----+----+----+----+-----+    +----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |          |    |    |    |    | 
  p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3
       ptr 


 Notice: a[2] = 3

인쇄-3:

이제 세 번째 인쇄물을 이해할 수 있습니다.

  1. ptr - pt1이유:
    ptr = p + 1그렇게ptr - p==p + 1 - p==1

  2. *ptr - at2이유:
    ptr = p + 1그렇게*ptr==*(p + 1)==p[1]==a + 2
    이것은 다음을 의미합니다.*ptr - a=a + 2 - a==2

  3. **ptr3이유:
    *ptr==a + 2점-2부터
    그렇게**ptr==*(a + 2)==a[2]==3

노트 편집:두 포인터의 차이는 유형을 갖습니다.ptrdiff_t는 , %td,것은 아니다.%d.

추가 사항:
신규 학습자에게 도움이 될 것으로 생각하여 추가하고자 합니다.

만약 우리가 당신의 코드에 4개의th 프린트가 하나 더 있는 두개의 라인을 가지고 있다고 가정합니다.return 0;

**++ptr;    // additional 
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);  // fourth printf

이 작동 코드 @Codepade, 이 라인 출력을 확인할 수 있습니다.2 2 3.

식: **++ptr;

.ptr음과 .p + 1 후,,++nptr 됩니다.p + 2(아니면 우리는 말할 수 있습니다.ptr==&p[2]).
두 의 detergence ** ==> **(p + 2)==*p[2]==*(a + 2)==a[2]==3.
과,자라는 의 효과 에 이 .**++ptr;정당합니다++ptr;.

표현 것.**++ptr;다.

  p                              a 
+----+----+----+----+-----+    +----+----+----+----+---+
| a  | a+2| a+2| a+3| a+4 |    |  0 |  1 | 3  | 3  | 4 |
+----+----+----+----+-----+    +----+----+----+----+---+
  ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲
  |    |    |    |    |          |    |    |    |    | 
  p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3
            ptr 

 Notice: ptr is equals to  p + 2 that means it points to p[2] 

인쇄-4:

문제가 된 Forth printf를 고려하면 다음과 같습니다.

  1. ptr - pt2이유:
    ptr = p + 2그렇게ptr - p==p + 2 - p==2

  2. *ptr - at2이유:
    ptr = p + 2그렇게*ptr==*(p + 2)==p[2]==a + 2
    이것은 다음을 의미합니다.*ptr - a=a + 2 - a==2

  3. **ptr3이유:
    *ptr==a + 2에서부터-2 지점
    그렇게**ptr==*(a + 2)==a[2]==3

일부 도 않음)의 관련 없는 (에) 3 하면이 *오퍼레이터들.미친 듯이 보이는 표현을 단순화하면 다음과 같은 효과를 얻을 수 있습니다.

ptr++;
++*ptr;
++**ptr;

그리고 이를 통해 여러분은 무슨 일이 일어나고 있는지 분명히 알 수 있을 것입니다.

  1. ptr++ptr 의 .p..ptr - p 것입니다.1.

  2. ++*ptr증이 이든 증가합니다.ptr . 의 두 됩니다.pa(초기화된) 두 번째가 아닌.서를 .*ptr - a2로.저도 마찬가지예요.**ptr. 2a.

  3. ++**ptr가가 합니다.ptr . 시킵니다의 세 합니다.a, 그것을 만드는 것3.

int*에서 값eptr했습니다 에 의해 했습니다.*++*ptr;준)++*ptr 선행분,,*는 미사용 참조)입니다.장의 .int *p[]이제 다음과 같이 보여야 합니다.

int *p[]={a, a+2, a+2, a+3, a+4};

.++**ptr;했습니다.a+2 원래 과 같이 ..

int a[]={0,1,3,3,4};

하라 요.++다보다 우선 .*, 그래서 당신이 할때는**ptr++ 대 가가 활성화된 해야 합니다 포인터를 증가시키고 이전 값을 이중으로 dere하므로 유효한 포인터 대 pointer가 아니라면 충돌 이상의 효과가 없으며 컴파일러(적어도 경고가 활성화된 상태에서) 사용되지 않은 결과에 대해 경고해야 합니다.

 static int a[]={0,1,2,3,4};

 static int *p[]={a, a+1, a+2, a+3, a+4};

 int **ptr;

 ptr = p; // ptr = &(p[0]); *ptr = a; **ptr = 0.

 **ptr++; // ptr = &(p[1]); *ptr = a+1; **ptr = 1
 printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

 *++*ptr; // ptr = &(p[1]); *ptr = a+2; **ptr = 2; p = {a, a+2, a+2, a+3, a+4} 
 printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

 ++**ptr; // ptr = &(p[1]); *ptr = a+2; **ptr = 3; a = {0, 1, 3, 3, 4}
 printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);

언급URL : https://stackoverflow.com/questions/17752549/pointer-expressions-ptr-ptr-and-ptr-use

반응형