2011-02-11 9 views
5

내가 다음 여기에 뭔가를 분명하지만 누락 고려하고,int를 int로 변환 한 후 int로 변환합니다.

int k = 10; 
int *p = &k; 
int i = (int)p; 

위의 생산,

warning: cast from pointer to integer of different size 

와 다음,

int k = 10; 
int *p = &k; 
int i = p; 

가 발생,

warning: initialization makes integer from pointer without a cast 

조금

Converting a pointer into an integer

위의 uintptr_t,

int k = 10; 
int *p = &k; 
int i = (uintptr_t)p; 

위의 경고는 경고없이 작동합니다. 그래서 내 질문은 k는 int이고 p는 k를 가리키는 int 포인터입니다. 왜 내가 역 참조를 얻지 못합니까?

+0

'i'의 가치는 무엇을 기대합니까? –

+0

당신은 어떤 예에서도'p'를 참조하지 않습니다. 질문을 명확히 할 수 있습니까? – nmichaels

답변

9
int k = 10; 
int *p = &k; 
int i = *p; 

마지막 줄의 * 앞에주의하십시오. 가리키는 int를 얻기 위해 포인터를 참조 해제하십시오.

편집 : 나는 uintptr_t에 익숙하지 않지만 int int i = (uintptr_t) p; i에 저장되는 결과는 10이 아닌 k의 메모리 주소입니다. 캐스트는 컴파일러에게 주소를 정수로 변환하도록 알려줍니다 (경고가 없으므로 컴파일러가 알고 있다고 주장하기 때문에). 당신이하고있는 일) 포인터를 역 참조하지 않습니다.

+0

설명해 주셔서 감사합니다.하지만 세 번째 예제에서는 eror가 발생하지 않는 이유는 무엇입니까? –

+1

@Hamza Yerlikaya : 첫째, 귀하의 예제 중 어느 것도 * 오류 *를 발생시키지 않았습니다. 그들은 * 경고 *를 일으켰습니다. 둘째, 경고는 자명하다.'int '의 크기는'int *'의 크기와 다르다. 'uintptr_t'의 크기는'int * '의 크기와 같으므로이 경우 경고가 없습니다. – AnT

3

실제로는 p을 참조 해제하지 않았기 때문에 오류가 발생했으며 방금 입력 했으므로 (해당 유형을 강제 변경 한 경우) int*에서 오류가 발생합니다. 역 참조하려면, 당신은 너무처럼 * 연산자를 사용합니다 : 당신은 포인터를 역 참조하지 않는

int i = *p; 
2

, 당신은 int로 포인터의 주소를 할당되도록.

int i = *p; 

가장 가능성이 높은 것은 무엇입니까?

1

포인터 캐스팅에 int를 사용하고 있는데, 두 개가 동일한 양의 메모리를 더 이상 사용하지 않는다고 보장 할 수 없습니다. 실제로 사람들이 그랬을 때 같은 크기를 사용한다는 보장은 없었지만, 대부분의 플랫폼에서는 어쨌든 일하게되었습니다.

후자의 예제에서 명시 적으로 캐스팅 했으므로 컴파일러는 실수가 아니라고 가정합니다 (또는 왜 입력 했습니까?). 그것이 컴파일러 출력의 차이 때문입니다.당신이 내가 될 것으로 K의 값을 얻기 전, 후 적절한 방법으로 K의 메모리 주소를 저장하지 않은 경우 것을

참고

int i = *p; 
0

이 보이게하는 방법입니다

여기
int k = 10; 
int *p = &k; 
int i = *p; 

내가 그것을

K = 10

쪽을 생각하는 방법이다 = 일부 주소

K = & 일부 주소

* p = 10 설정중인

1

(p 보유 무엇) k의 주소와 동일 i. 주소 값은 부호없는 유형입니다. 따라서 포인터에서 캐스팅 할 때 캐스팅과 부호없는 값을 부호로 취하고 있기 때문에 불평합니다.

또한 포인터는 플랫폼에 따라 다른 크기의 유형이므로 32 비트 포인터는 64보다 작습니다. 따라서 포인터가 8 바이트 부호가없는 경우 서명 된 4 바이트로 캐스팅됩니다.

0

uintptr_t은 중간 캐스트를 int으로하는 유형으로는 의미가 없지만 그대로 사용됩니다. 시스템에 정의되어있는 경우에는 포인터 값을 사용하여로드 할 때 정보를 잃지 않는 부호없는 정수 유형입니다. 따라서 필요한 경우 int 대신 uintprt_t을 완전히 사용하십시오. 그러나 이것은 드문 경우 여야하며, 대부분의 경우 나는 이것이 나쁜 설계의 징후 일 뿐이라고 확신합니다.

어쨌든 int은 처음부터 좋지 않습니다. 포인터 값은 가상 메모리 공간의 한 위치 일 뿐이며 서명 된 값으로 보아도 전혀 이해가되지 않습니다.