Programing

포인터 표현식 : * ptr ++, * ++ ptr 및 ++ * ptr

lottogame 2020. 7. 19. 09:52
반응형

포인터 표현식 : * ptr ++, * ++ ptr 및 ++ * ptr


최근에 나는 스스로 이해할 수없는이 문제를 겪었습니다.

이 세 가지 표현은 무엇을 정말 의미?

*ptr++
*++ptr
++*ptr

나는 Ritchie를 시도했다. 그러나 불행히도이 3 가지 작업에 대해 그가 말한 것을 따를 수 없었습니다.

나는 그들이 가리키는 포인터 / 값을 증가시키기 위해 모두 수행된다는 것을 알고 있습니다. 또한 우선 순위와 평가 순서에 대해 많은 것들이있을 수 있습니다. 하나는 포인터를 먼저 증가시킨 다음 해당 포인터의 내용을 가져 오는 것처럼 단순히 콘텐츠를 가져온 다음 포인터 등을 증가시킵니다. 보시다시피 실제 작업 에 대한 명확한 이해가 없습니다. 가능한 빨리 클리어하십시오. 그러나 프로그램에 적용 할 수있는 기회를 얻게되면 진정으로 길을 잃었습니다. 예를 들면 다음과 같습니다.

int main()
{
    const char *p = "Hello";
    while(*p++)
         printf("%c",*p);
    return 0;
}

나 에게이 출력을 제공합니다 :

ello

그러나 나는 그것이 인쇄 될 것이라고 기대했다 Hello. 하나의 최종 요청-주어진 코드 스 니펫에서 각 표현식이 작동하는 방법에 대한 예를 알려주십시오. 대부분의 경우 이론의 단지 단락 만이 나의 머리 위로 날아간다.


도움이 되길 바라는 자세한 설명은 다음과 같습니다. 설명하는 것이 가장 간단하므로 프로그램부터 시작하겠습니다.

int main()
{
    const char *p = "Hello";
    while(*p++)
        printf("%c",*p);
    return 0;
}

첫 번째 진술 :

const char* p = "Hello";

p대한 포인터로 선언 합니다 char. "포인터를 가리키는 포인터 char"란 무엇을 의미합니까? 값이 pa의 주소임을 의미합니다 char. p메모리에 a를 저장할 공간이 어디에 있는지 알려줍니다 char.

또한 문 p은 문자열 리터럴의 첫 번째 문자를 가리 키도록 초기화 됩니다 "Hello". 이 연습 p을 위해 전체 문자열이 아니라 첫 번째 문자 만 가리키는 것으로 이해 하는 것이 중요합니다 'H'. 결국 전체 문자열이 아닌 pone에 대한 포인터 char입니다. 의 값 p의 주소이다 'H'에서 "Hello".

그런 다음 루프를 설정하십시오.

while (*p++)

루프 조건 *p++은 무엇을 의미합니까? 이 수수께끼를 만드는 세 가지 사항이 있습니다 (적어도 친숙해질 때까지).

  1. 두 연산자의 우선 순위, 접두사 ++및 간접*
  2. 접미사 증가 표현식의 값
  3. 접미사 증가 표현식의 부작용

1. 우선 순위 . 연산자에 대한 우선 순위 표를 간략하게 살펴보면 접미사 증가분이 역 참조 / 간접 지정 (15)보다 우선 순위가 높은 것 (16)을 알 수 있습니다. 이는 복잡한 표현 *p++이 다음과 같이 그룹화 됨을 의미합니다 *(p++). 즉, *부품이 부품의 가치에 적용됩니다 p++. p++먼저 참여 하겠습니다 .

2. 접미사 표현식 값 . 의 값은 증분 전의p++ 값입니다 . 당신이 가지고 있다면:p

int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);

출력은 다음과 같습니다.

7
8

증분 전에 i++평가 i되기 때문 입니다. 마찬가지로 p++의 현재 값으로 평가하려고합니다 p. 아시다시피 현재 값 p은의 주소입니다 'H'.

이제 p++일부 *p++가 평가되었습니다. 의 현재 값입니다 p. 그런 다음 *부분이 발생합니다. *(current value of p)의미 :가 보유한 주소의 값에 액세스합니다 p. 해당 주소의 값은 'H'입니다. 따라서 표현식은로 *p++평가됩니다 'H'.

이제 잠깐만 요. *p++평가 'H'되면 왜 'H'위의 코드에서 인쇄 되지 않습니까? 그것이 부작용이 나오는 입니다.

3. 접두사 표현 부작용 . 접미사 ++현재 피연산자 을 갖지만 해당 피연산자를 증가 시키는 부작용 이 있습니다. 응? 해당 int코드를 다시 살펴보십시오 .

int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);

앞에서 언급했듯이 출력은 다음과 같습니다.

7
8

i++첫 번째에서 평가 되면 7 로 평가되지만 printf()C 표준은 두 번째 printf()실행이 시작 되기 전에 어느 시점 에서 작업자 부작용이 발생 했음을 보증합니다 ++. 즉, 두 번째 printf()가 발생 하기 전에 첫 번째 연산자 i의 결과로 증가했을 것 입니다. 그건 그렇고, 표준이 부작용의 타이밍에 대해 제공하는 몇 가지 보장 중 하나입니다.++printf()

그런 다음 코드에서 표현식 *p++이 평가되면로 평가됩니다 'H'. 그러나 당신이 이것을 얻을 때까지 :

printf ("%c", *p)

그 성가신 부작용이 발생했습니다. p증가되었습니다. 우와! 더 이상을 가리키는 것이 'H'아니라 한 문자를 지나는 'H''e', 즉을 가리 킵니다 . 그것은 cockneyfied 출력을 설명합니다 :

ello

따라서 다른 답변에서 유용하고 정확한 제안의 합창 : "Hello"코니가 아닌 수신 된 발음을 인쇄 하려면 다음과 같은 것이 필요합니다.

while (*p)
    printf ("%c", *p++);

그렇게 많은. 나머지는 어떻습니까? 다음의 의미에 대해 묻습니다.

*ptr++
*++ptr
++*ptr

우리는 방금 첫 번째에 대해 이야기 했으므로 두 번째를 살펴 보겠습니다 *++ptr.

앞의 설명에서 접두사 증가 p++는 특정 우선 순위 , 부작용있음을 보았습니다 . 접두사 증분 ++p접미사 대응 항목과 동일한 부작용을습니다. 피연산자가 1 씩 증가합니다. 그러나 우선 순위 이 다릅니다 .

접두사 증분은 접두사보다 우선 순위가 낮습니다. 다시 말해서 우선 순위가 15입니다. 다시 말해서 역 참조 / 간접 연산자와 같은 우선 순위를 갖습니다 *. 같은 표현에서

*++ptr

중요한 것은 우선 순위가 아닙니다. 두 연산자는 우선 순위가 같습니다. 따라서 연관성이 시작됩니다. 접두사 증분 및 간접 연산자에는 오른쪽 왼쪽 연관성이 있습니다. 이 연관성으로 인해 피연산자 ptr++연산자보다 왼쪽에 있는 가장 오른쪽 연산자로 그룹화됩니다 *. 다시 말해, 표현은 그룹화 될 것 *(++ptr)입니다. 따라서 *ptr++다른 이유로 와 마찬가지로 여기에서도 해당 *부품이 부품의 가치에 적용됩니다 ++ptr.

그래서 그 가치는 무엇입니까? 접두어 증가 표현식의 값은 증가 후 피연산자의 값입니다 . 이것은 후위 증가 연산자와는 매우 다른 짐승입니다. 가지고 있다고 가정 해 봅시다.

int i = 7;
printf ("%d\n", ++i);
printf ("%d\n", i);

출력은 다음과 같습니다.

8
8

... 우리가 postfix 연산자로 본 것과 다릅니다. 마찬가지로 다음과 같은 경우 :

const char* p = "Hello";
printf ("%c ", *p);    // note space in format string
printf ("%c ", *++p);  // value of ++p is p after the increment
printf ("%c ", *p++);  // value of p++ is p before the increment
printf ("%c ", *p);    // value of p has been incremented as a side effect of p++

출력은 다음과 같습니다.

H e e l                // good dog

왜 그런지 알아?

이제 세 번째 표현 인 ++*ptr. 그것은 실제로 가장 까다로운 것입니다. 두 연산자 모두 우선 순위가 같고 오른쪽 왼쪽 연관성이 있습니다. 이는 표현식이 그룹화됨을 의미합니다 ++(*ptr). ++부품 부품 값에 적용됩니다 *ptr.

우리가 가지고 있다면 :

char q[] = "Hello";
char* p = q;
printf ("%c", ++*p);

놀랍게도 이기적인 결과는 다음과 같습니다.

I

뭐?! 자, *p파트는로 평가됩니다 'H'. 그런 다음 ++에 게임이 시작됩니다.이 시점 'H'에서 포인터가 아닌에 적용됩니다 ! 1을 추가하면 어떻게됩니까 'H'? 1에 ASCII 값 'H'72를 더한 값을 얻습니다 . 당신은 73을 얻습니다 char. 그리고 그것을 charASCII 값으로 73 을 얻습니다 : 'I'.

그것은 당신이 당신의 질문에서 세 가지 표현을 처리합니다. 다음은 귀하의 질문에 대한 첫 번째 의견에서 언급 한 또 다른 내용입니다.

(*ptr)++ 

그것도 흥미 롭습니다. 당신이 가지고 있다면:

char q[] = "Hello";
char* p = q;
printf ("%c", (*p)++);
printf ("%c\n", *p);

그것은 당신에게 다음과 같은 열정적 인 결과를 줄 것입니다.

HI

무슨 일이야? 다시 말하지만 우선 순위 , 표현식 값부작용 의 문제입니다 . 괄호로 인해 *p파트는 기본 표현식으로 취급됩니다. 기본 표현은 다른 모든 것을 능가합니다. 그들은 먼저 평가를받습니다. 그리고 *p아시다시피,로 평가됩니다 'H'. 나머지 표현식 인 ++부분은 해당 값에 적용됩니다. 따라서이 경우 (*p)++에는가됩니다 'H'++.

의 가치는 'H'++무엇입니까? 이라고 말하면 'I'접미사 증가와 함께 가치 대 부작용에 대한 논의를 잊어 버렸습니다 (이미!). 기억 'H'++평가 의 현재 값을 'H' . 그래서 먼저 printf()인쇄 할 것 'H'입니다. 그리고, 같은 부작용 , 즉 'H'로 증가 될 예정이다 'I'. 두 번째 printf()는 인쇄합니다 'I'. 그리고 당신은 당신의 기분 좋은 인사가 있습니다.

좋아요,하지만 마지막 두 경우에는 왜 필요한가요?

char q[] = "Hello";
char* p = q;

왜 난 그냥 뭔가를 가질 수 없습니다

/*const*/ char* p = "Hello";
printf ("%c", ++*p);   // attempting to change string literal!

"Hello"문자열 리터럴 이기 때문 입니다. 시도 하면 문자열 ++*p의을로 변경 하여 전체 문자열을 만듭니다. C에서 문자열 리터럴은 읽기 전용입니다. 이를 수정하려고하면 정의되지 않은 동작이 호출됩니다. 영어로도 정의되어 있지 않지만 우연의 일치입니다.'H''I'"Iello""Iello"

반대로, 당신은 가질 수 없습니다

char p[] = "Hello";
printf ("%c", *++p);  // attempting to modify value of array identifier!

왜 안돼? 이 경우 p에는 배열 이기 때문입니다 . 배열은 수정 가능한 l 값이 아닙니다. p배열의 이름이 상수 포인터 인 것처럼 작동하므로 사전 또는 사후 증분 또는 감소 포인트의 위치를 변경할 수 없습니다 . (실제로는 그렇지 않습니다. 편리하게 볼 수있는 방법입니다.)

요약하면 다음과 같은 세 가지 질문을했습니다.

*ptr++   // effectively dereferences the pointer, then increments the pointer
*++ptr   // effectively increments the pointer, then dereferences the pointer
++*ptr   // effectively dereferences the pointer, then increments dereferenced value

그리고 여기에 다른 세 개만큼 재미 있고 네 번째가 있습니다 :

(*ptr)++ // effectively forces a dereference, then increments dereferenced value

ptr실제로 배열 식별자 인 경우 첫 번째와 두 번째가 충돌합니다 . ptr문자열 리터럴을 가리키는 경우 세 번째와 네 번째가 충돌합니다 .

거기 있어요 나는 그것이 모두 수정되기를 바랍니다. 당신은 훌륭한 청중이었고, 나는 일주일 내내 여기에 있습니다.


ptrarray의 i 번째 요소를 가리키는 것으로 가정하십시오 arr.

  1. *ptr++평가 arr[i]하고 세트 ptr의 (I + 1) 번째 원소를 차례로 arr. 와 같습니다 *(ptr++).

  2. *++ptrptr의 (i + 1) 번째 요소를 가리 키도록 설정 arr하고로 평가합니다 arr[i+1]. 와 같습니다 *(++ptr).

  3. ++*ptr1 씩 증가 arr[i]하고 증가 된 값으로 평가됩니다. 포인터 ptr는 그대로 유지됩니다. 와 같습니다 ++(*ptr).

하나 더 있지만 그것을 작성하려면 괄호가 필요합니다.

  1. (*ptr)++1 씩 증가 arr[i]하고 증가 하기 전에 그 값으로 평가됩니다. 포인터 ptr는 다시 그대로 유지됩니다.

나머지는 스스로 알아낼 수 있습니다. 또한 @Jaguar가 답변했습니다.


*ptr++ : post increment a pointer ptr

*++ptr : Pre Increment a pointer ptr

++*ptr : preincrement the value at ptr location

사전 증분 및 사후 증분 연산자에 대해 여기읽으 십시오


이것은 Hello출력으로 줄 것입니다

int main()
{
    const char *p = "Hello";
    while(*p)
         printf("%c",*p++);//Increment the pointer here 
    return 0;
}

루프 상태가 좋지 않습니다.

while(*p++)
    printf("%c",*p);

와 같다

while(*p)
{
    p++;
    printf("%c",*p);
}

그리고 그것은 틀 렸습니다. 이것은 다음과 같아야합니다 :

while(*p)
{
    printf("%c",*p);
    p++;
} 

*ptr++와 동일합니다 *(ptr++).

const char  *ptr = "example";
char  value;

value = *ptr;
++ptr;
printf("%c", value); // will print 'e'

*++ptr와 동일합니다 *(++ptr).

const char  *ptr = "example";
char  value;

++ptr;
value = *ptr;
printf("%c", value); // will print 'x'

++*ptr와 동일합니다 ++(*ptr).

const char  *ptr = "example";
char  value;

value = *ptr;
++value;
printf("%c", value); // will print 'f' ('e' + 1)

우선 순위에 대해서는 바로 *접두사 증가보다 우선하지만 접두사 증가보다는 우선합니다. 이러한 분류 방법은 다음과 같습니다.

*ptr++ -왼쪽에서 오른쪽으로 이동하여 포인터를 역 참조한 다음 포인터 값을 증가시킵니다 (역 참조 이후의 접두사 우선 순위로 인해 포인터 값이 아님).

*++ptr -포인터를 증가시킨 후 역 참조합니다. 이는 접두사와 역 참조가 동일한 우선 순위를 가지므로 오른쪽에서 왼쪽으로 순서대로 평가되기 때문입니다.

++*ptr-우선 순위 측면에서 위와 유사하며 포인터를 역 참조하고 포인터가 가리키는 것을 증가시키기 위해 오른쪽에서 왼쪽으로 다시 이동합니다. 읽기 전용 변수 ( char* p = "Hello";) 를 수정하려고하므로 정의되지 않은 동작으로 이어질 수 있습니다.


다른 답변이 정확하지만 뭔가 빠진 것 같아서 테이크를 추가하겠습니다.

 v = *ptr++

방법

 temp = ptr;
 ptr  = ptr + 1
 v    = *temp;

어디로

 v = *++ptr

방법

 ptr = ptr + 1
 v   = *ptr

사후 증가 (및 사후 감소)의 의미는

 temp = ptr       // Temp created here!!!
 ptr  = ptr + 1   // or - 1 if decrement)
 v    = *temp     // Temp destroyed here!!!

왜 중요한가요? C에서는 그렇게 중요하지 않습니다. C ++에서는 ptr반복자와 같은 복잡한 유형 일 수 있습니다. 예를 들어

 for (std::set<int>::iterator it = someSet.begin(); it != someSet.end(); it++)

이 경우 it복잡한 유형 it++이므로 temp생성으로 인해 부작용이있을 수 있습니다 . 물론 운이 좋으면 컴파일러는 필요하지 않은 코드를 버리려고 시도하지만 반복자의 생성자 또는 소멸자가 무언가를 수행 it++하면 생성 할 때 해당 효과를 보여줍니다 temp.

내가 말하려는 것 중 짧은 것은 Write What You Mean 입니다. 증가 ptr의미하는 경우 ++ptrnot 작성하십시오 ptr++. 당신이 의미 temp = ptr, ptr += 1, temp한다면 쓰기ptr++


*ptr++    // 1

이것은 다음과 같습니다.

    tmp = *ptr;
    ptr++;

따라서가 가리키는 객체의 값 ptr이 검색된 다음 ptr증가합니다.

*++ptr    // 2

이것은 다음과 같습니다.

    ++ptr;
    tmp = *ptr;

따라서 포인터 ptr가 증가한 다음에 가리키는 객체 ptr가 읽 힙니다.

++*ptr    // 3

이것은 다음과 같습니다.

    ++(*ptr);

로 가리키는 객체 ptr가 증가합니다. ptr그 자체는 변하지 않습니다.


postfix와 prefix는 역 참조보다 우선 순위가 높으므로

* ptr ++ 여기에 ptr 증가를 게시 한 다음 새로운 ptr 값을 가리 킵니다.

* ++ ptr 여기서 Pre 증분 주먹은 새로운 ptr 값을 가리 킵니다

++ * ptr 여기서 먼저 ptr의 값을 가져 와서 그 vlaue를 증가시킵니다.


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

참고 : 포인터는 초기화되어야하며 유효한 주소가 있어야합니다. 우리의 프로그램 (a.out)과는 다른 RAM에서 동시에 더 많은 프로그램이 동시에 실행되기 때문에, 즉 당신이 당신을 위해 예약되지 않은 일부 메모리에 액세스하려고 시도하면 Segmentation fault를 통해 OS가 작동합니다.

이것을 설명하기 전에 간단한 예를 생각해 보자.

#include<stdio.h>
int main()
{
        int num = 300;
        int *ptr;//uninitialized pointer.. must be initialized
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr = *ptr + 1;//*ptr means value/data on the address.. so here value gets incremented
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        /** observe here that "num" got changed but manually we didn't change, it got modified by pointer **/
        ptr = ptr + 1;//ptr means address.. so here address got incremented
        /**     char pointer gets incremented by 1 bytes
          Integer pointer gets incremented by 4 bytes
         **/
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

위 코드의 출력을 분석하면 위 코드의 출력을 얻었기를 바랍니다. 위의 코드에서 분명한 것은 포인터 이름 ( ptr )은 주소 에 대해 이야기 하고 * ptr 은 abbout / 데이터에 대해 이야기하고 있다는 것을 의미 합니다.

사례 1 : * ptr ++, * ++ ptr, * (ptr ++) 및 * (++ ptr) :

위에서 언급 한 4 가지 구문은 모두 비슷 address gets incremented하지만 주소가 어떻게 증가하는지는 다릅니다.

참고 : 식을 풀려면 식에 몇 개의 연산자가 있는지 확인한 다음 연산자의 우선 순위 를 찾으십시오 . 우선 순위가 동일한 여러 연산자가 왼쪽에서 오른쪽으로 오른쪽에서 왼쪽으로 (L) 오른쪽 으로 진화 또는 연관성 순서를 확인 합니다.

* ptr ++ : 여기에 2 개의 연산자, 즉 de-reference (*)와 ++ (increment)가 있습니다. 둘 다 동일한 우선 순위를 가지므로 R에서 L까지의 연관성을 점검하십시오. 따라서 연산자가 먼저 오는 모든 것이 오른쪽에서 왼쪽으로 해결되기 시작합니다.

* ptr ++ : R에서 L로 해결하는 동안 첫 번째 ++가 왔으므로 주소는 증가하지만 포스트는 증가합니다.

* ++ ptr : 첫 번째 주소와 동일하지만 주소도 증가하지만 사전 증가입니다.

* (ptr ++) : 여기에는 우선 순위가 가장 높은 그룹화 () 그룹화하는 3 개의 연산자가 있습니다. 따라서 먼저 ptr ++로 해결됩니다. 즉 주소가 증가하지만 게시됩니다.

* (++ ptr) : 위의 경우와 동일하지만 주소도 증분되지만 사전 증분됩니다.

사례 2 : ++ * ptr, ++ (* ptr), (* ptr) ++ :

위에서 언급 한 4 가지 구문은 모두 비슷 하지만 모든 값 / 데이터가 증가 하지만 값이 어떻게 변경되는지는 다릅니다.

++ * ptr : first *는 R에서 L로 해결하는 동안 왔으므로 값은 변경되지만 사전 증분됩니다.

++ (* ptr) : 위의 경우와 동일하게 값이 수정됩니다.

(* ptr) ++ : 여기에는 우선 순위가 가장 높은 그룹화 (), 내부 () * ptr이있는 3 개의 연산자가 있습니다. 따라서 먼저 * ptr이 해결됩니다. 즉, 값이 증가하지만 게시됩니다.

참고 : ++ * ptr과 * ptr = * ptr + 1은 모두 동일하며 두 경우 모두 값이 변경됩니다. ++ * ptr : 하나의 명령어 (INC) 만 사용되며, 단일 샷에서 직접 값이 변경됩니다. * ptr = * ptr + 1 : 여기서 첫 번째 값은 증분 (INC) 된 다음 할당됩니다 (MOV).

포인터의 증가 증분 구문을 이해하려면 간단한 코드를 고려하십시오.

#include<stdio.h>
int main()
{
        int num = 300;
        int *ptr;
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//address changed(post increment), value remains un-changed
//      *++ptr;//address changed(post increment), value remains un-changed
//      *(ptr)++;//address changed(post increment), value remains un-changed
//      *(++ptr);//address changed(post increment), value remains un-changed

//      ++*ptr;//value changed(pre increment), address remains un-changed
//      (*ptr)++;//value changed(pre increment), address remains un-changed
//      ++(*ptr);//value changed(post increment), address remains un-changed

        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

위의 코드에서 주석을 주석 처리하거나 주석 해제하고 출력을 분석하십시오.

상수 포인터 : 포인터를 일정하게 만들 수있는 방법은 없습니다.

1) const int * p OR int const * p : 여기 value상수가 있습니다 . 주소가 일정하지 않습니다. 즉 p가 가리키는 곳은 무엇입니까? 일부 주소? 그 주소에서 값은 무엇입니까? 어떤 가치 맞습니까? 그 값은 일정하며 그 값을 수정할 수 없지만 포인터가 가리키는 위치는 무엇입니까? 주소가 맞습니까? 다른 주소를 가리킬 수도 있습니다.

이것을 이해하려면 아래 코드를 고려하십시오.

#include<stdio.h>
int main()
{
        int num = 300;
        const int *ptr;//constant value, address is modifible
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//
//      *++ptr;//possible bcz you are trying to change address which is possible
//      *(ptr)++;//possible
//      *(++ptr);//possible

//      ++*ptr;//not possible bcz you trying to change value which is not allowed
//      (*ptr)++;//not possible
//      ++(*ptr);//not possible

        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

위 코드의 출력을 분석하십시오

2) int const * p : ' **constant pointe**r'즉, ' address is constant but value is not constant. 여기에서는 주소를 변경할 수 없지만 값을 수정할 수 있습니다.

참고 : 상수 포인터 (위의 경우)는 선언하는 동안 초기화해야합니다.

이를 이해하려면 간단한 코드를 확인하십시오.

#include<stdio.h>
int main()
{
        int x = 300;
        int* const p;
        p = &x;
        printf("x = %d p =%p and *p = %d\n",num,p,*p);
}

In above code, if you observe that there is no ++*p or *p++ So you may thought this is simple case because we are not changing address or value but it will produce error. Why ? Reason I mention in comments.

#include<stdio.h>
int main()
{
        int x = 300;
        /** constant pointer must initialize while decaring itself **/
        int* const p;//constant pointer i.e its pointing to some address(here its pointing to garbage), it should point to same address(i.e garbage ad
dress only 
        p = &x;// but here what we are doing ? we are changing address. we are making p to point to address of x instead of garbage address.
        printf("x = %d p =%p and *p = %d\n",num,p,*p);
}

So whats the Solution of this problem ?

     int* const p = &x;

for more about this case lets consider below example.

#include<stdio.h>
int main()
{
        int num = 300;
        int *const ptr = &num;//constant value, address is modifible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//not possible
//      *++ptr;//not possible bcz you are trying to change address which is not possible
//      *(ptr)++;//not possible
//      *(++ptr);//not possible

//      ++*ptr;// possible bcz you trying to change value which is allowed
//      (*ptr)++;// possible
//      ++(*ptr);// possible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

3)const int* const p : Here both address and value are constant.

To understand this lets check below code

#include<stdio.h>
int main()
{
        int num = 300;
        const int* const ptr = &num;//constant value,constant address 
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//not possible
        ++*ptr;//not possible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

const char *p = "Hello";   

*p means "Hello"
          ^
          | 
          p

*p++ means "Hello"
             ^
             | 
             p

*++p means "Hello"
            ^
            |     (WHILE THE STATEMENT IS EXECUTED)
            p

*++p means "Hello"
             ^
             |     (AFTER THE STATEMENT IS EXECUTED)
             p

++*p means that you are trying to increment the ASCII value of *p which

   is "Hello"
       ^
       | 
       p

you cannot increment the value 'cause it's a constant so you would get an error

as for your while loop the loop runs until *p++ reaches the end of the string where there is a '\0'(NULL) character.

Now since *p++ skips the first character you would only get your output starting from the second character.

The following code will not output anything because while loop has '\0'

const char *p = "Hello";
    while('\0') 
         printf("%c",*p);

The following code will give you the same output as the next code i.e ello .

const char *p = "Hello";
    while(*++p)
         printf("%c",*p);

...................................

const char *p = "Hello";
    while(*p++)
         printf("%c",*p);

참고URL : https://stackoverflow.com/questions/18481740/pointer-expressions-ptr-ptr-and-ptr

반응형