포인터 표현: **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페이지를 낭비했습니다.
어떤 해명이라도 해주시면 감사하겠습니다.
배열 이름은 대부분의 식에서 첫 번째 요소에 대한 포인터로 쉽게 붕괴될 수 있음을 기억하십시오(배열 이름이 첫 번째 요소에 대한 포인터로 붕괴되지 않는 일부 예외를 읽습니까? @HCO에23 의해 가능하게 응답됨).
더 나은 이해를 위해 내 다이어그램을 고려해 보십시오.
먼저, 다음과 같이 가정합니다.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 진술 전에.
ptr
와 같음.p
그것은 포인터 배열의 첫번째 요소의 주소입니다.이런 이유로,ptr
첫번째 요소를 가리키다p[0]
줄을 지어 (아니면 우리는 말할 수 있습니다)ptr
==&p[0]
).*ptr
수단p[0]
그 이유는p[0]
가a
,그렇게*ptr
가a
(그러니까)*ptr
==a
).그 이유는
*ptr
가a
,그리고나서**ptr
가*a
==*(a + 0)
==a[0]
그것은0
.식에 있는 참고
**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를 이해할 수 있습니다.
ptr - p
산출량1
이유:
ptr = p + 1
,그렇게ptr - p
==p + 1 - p
==1
*ptr - a
산출량1
이유:
ptr = p + 1
,그렇게*ptr
==*(p + 1)
==p[1]
==a + 1
이것은 다음을 의미합니다.*ptr - a
=a + 1 - a
==1
**ptr
t1
이유:
*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:
이제 두 번째 인쇄물을 이해할 수 있습니다.
ptr - p
t1
이유:
ptr = p + 1
,그렇게ptr - p
==p + 1 - p
==1
*ptr - a
t2
이유:
ptr = p + 1
그렇게*ptr
==*(p + 1)
==p[1]
==a + 2
이것은 다음을 의미합니다.*ptr - a
==a + 2 - a
==2
**ptr
t2
이유:
*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:
이제 세 번째 인쇄물을 이해할 수 있습니다.
ptr - p
t1
이유:
ptr = p + 1
그렇게ptr - p
==p + 1 - p
==1
*ptr - a
t2
이유:
ptr = p + 1
그렇게*ptr
==*(p + 1)
==p[1]
==a + 2
이것은 다음을 의미합니다.*ptr - a
=a + 2 - a
==2
**ptr
3
이유:
*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를 고려하면 다음과 같습니다.
ptr - p
t2
이유:
ptr = p + 2
그렇게ptr - p
==p + 2 - p
==2
*ptr - a
t2
이유:
ptr = p + 2
그렇게*ptr
==*(p + 2)
==p[2]
==a + 2
이것은 다음을 의미합니다.*ptr - a
=a + 2 - a
==2
**ptr
3
이유:
*ptr
==a + 2
에서부터-2 지점
그렇게**ptr
==*(a + 2)
==a[2]
==3
일부 도 않음)의 관련 없는 (에) 3 하면이 *
오퍼레이터들.미친 듯이 보이는 표현을 단순화하면 다음과 같은 효과를 얻을 수 있습니다.
ptr++;
++*ptr;
++**ptr;
그리고 이를 통해 여러분은 무슨 일이 일어나고 있는지 분명히 알 수 있을 것입니다.
ptr++
ptr
의 .p
..ptr - p
것입니다.1
.++*ptr
증이 이든 증가합니다.ptr
. 의 두 됩니다.p
세a
(초기화된) 두 번째가 아닌.서를 .*ptr - a
2
로.저도 마찬가지예요.**ptr
.2
a
.++**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
'programing' 카테고리의 다른 글
cygwin - UNC 공유에 파일 복사 (0) | 2023.10.05 |
---|---|
여러 열을 요인에 한 번에 강제 적용 (0) | 2023.10.05 |
자바스크립트에 대한 코딩 표준이 있습니까? (0) | 2023.10.05 |
MySQL 데이터베이스에서 두 열을 업데이트하는 방법은? (0) | 2023.10.05 |
.ajax() 호출에서 knout.jsobservableArray() 로드 (0) | 2023.10.05 |