2014-11-25 1 views
2

문제의 이해, 다음 명령문은 평가 될 것입니다 방법 갖는 : * 적용한 후에는 값을 제공하기 때문위해 포인터

++*++ptr and *ptr++++ 

내 이해 당 첫째 날 좌변 필요한 줄 것이다 ++ 연산자에는 사용할 수 없습니다. 그러나 결과는 정반대입니다. 설명 해주십시오.

두 번째 문장에서 오류가 발생합니다. batch3.c : 6 : 21 : 오류 : 증가 값 피연산자로 lvalue가 필요합니다. printf ("% d", * ptr ++++);

답변

1

++ 운영자는 그래서 포인터가 먼저 증가하고 역 참조됩니다

*을 통해 더 높은 우선 순위를 가지고있다.

*p++ 

우선

p++ 

이어서 *p++ 증가되어야하는 가치 있어야만 ++ 들어

. 그러나 아래 표현식은 ++에 대한 lvalue를 제공하지 않습니다. p++은 수정할 수있는 좌변 치가 아닙니다.

*ptr++++; 
+0

Gopi 나는 두 번째 문이 나에게 오류를 제공하는 이유, 내가 설명이 필요 이해 : 좌변이 증가 피연산자로 필요한 의 printf를 ("% d 개", * PTR을 ++++); – Sagrian

1

여기에 무슨 일이 두 표현은 (and<iso646.h>을 정의 참고) 분리 된 점을 고려 :

먼저 하나 ++*++ptr는, ++(*(++ptr))에 해당 모두 접두사로 ++ 및 단항 *는이 같은 precedence 및 assiociativity는 오른쪽에서 왼쪽 모두에 대한 것입니다. 다음을 참조하십시오 example 그림과 같이

#include <stdio.h> 

int main(void) 
{ 
    int a[] = {1, 2}; 
    int *ptr = a; 

    ++(*(++ptr)); 

    printf("%d\n", a[0]); 
    printf("%d\n", a[1]); 

    return 0; 
} 

결과 : ptr++ 표현식은 수정 좌변 아니므로

1 
3 

후자의 표현은, 컴파일 가능한 없습니다. 포스트 픽스 ++은 더 높은 우선 순위를 가지고 있으며, * (간접적 연산자)이며 그것의 연관성은 왼쪽에서 오른쪽입니다.

+0

받아 들일 수 있지만 * (++ ptr) 수정 가능한 lvalue 줄까요? 첫 번째 진술도 나에게 오류를 줘야합니까? – Sagrian

+0

@Sagrian : 실제로'* (++ ptr)'는 그런 lvalue이고,'* ptr'와 똑같을 것입니다. 그것이 어떻게 작동하는지 설명하기위한 예제가 추가되었습니다. –

2

첫째, 일부 standardese :

6.5.2.4 Postfix increment and decrement operators

Constraints

1 The operand of the postfix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.

Semantics

2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. Postfix ++ on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics. 98)
...
6.5.16 Assignment operators
...
3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, 111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

강조 광산.

위 벽의 결과는 ptr++++ptr의 결과가 lvalues가 아님을 나타냅니다. 그러나 두 표현식 모두 포인터 값을 가지므로 단항 * 연산자의 피연산자 일 수 있으며 *ptr++*++ptr의 결과는 일 수 있습니다.

이것은 ++*++ptr가 작동하는 이유입니다. 당신은 *++ptr의 결과를 증가시키고 있습니다. 이것은 lvalue 일 수 있습니다.그러나 *ptr++++*(((ptr)++)++)으로 해석됩니다 (접미어 ++은 단항 문자보다 높은 우선 순위를가집니다) *; ptr++의 결과는 두 번째 ++에 대한 피연산자이지만 ptr++의 결과는 lvalue가 아니므로 컴파일러는 불평합니다. (*ptr++)++으로 작성한 경우 표현식이 유효합니다. 한마디로

:

++*++ptr  - valid, equivalent to ++(*ptr++) 
*++++ptr  - invalid, equivalent to *(++(++ptr)), result of ++ptr is not an lvalue 
++++*ptr  - invalid, equivalent to ++(++(*ptr)), result of ++*ptr is not an lvalue 
*ptr++++  - invalid, equivalent to *((ptr++)++), result pf ptr++ is not an lvalue 
(*ptr)++++ - invalid, equivalent to ((*ptr)++)++, result of (*ptr)++ is not an lvalue 
(*ptr++)++ - valid 
+0

unary'*'_always_ lvalue의 결과가 아닌가? – mafso