2011-03-24 3 views
2
#include <stdio.h> 

int main(void) 
{ 
    int x = 99; 
    int *pt1; 

    pt1 = &x; 

    printf("Value at p1: %d\n", *pt1); 
    printf("Address of p1 (with %%p): %p\n", pt1); 
    printf("Address of p1 (with %%d): %d\n", pt1); 

    return 0; 
} 

%p 대신 %d 인 프린터 포인터 값의 단점/위험 요소는 무엇입니까?포인터 값 인쇄

+0

"올바른"답변을 선택하는 것이 좋습니다. – DevSolar

답변

5

% d는 정수를 표시합니다. 포인터의 크기가 정수의 크기와 같을 필요는 없습니다.

+1

64 비트 시스템 (예 : Windows 7 64 비트 또는 Linux amd64)의 경우 int 크기는 포인터의 크기가 64 비트 인 경우에도 스타일 32 비트입니다. – BenjaminB

+3

크기가 같지 않고 캐스팅하지 않으면 정의되지 않은 동작 인 printf에 대한 VA_ARGS에 대해 거짓말을합니다! – Flexo

+1

@awoodland, 정확하게 UB 일뿐만 아니라 스택이 엉망이되어 버리기 때문에'% d '다음에 오는 다른 형식 지정자가 있으면 잘못 될 것입니다. –

2

시스템 포인터의 크기가 int과 같지 않은 경우, 무한대의 나사가 발생할 수 있습니다. 만약 그들이 같은 크기가된다면 아마 안전 할 것입니다. 언어 표준에 관한 한, 포인터를 전달하고 그것을 정수로 취급하는 것은 컴퓨터에 불을 지피거나, 상사에게 이메일을 보내거나, 악마를 코 밖으로 날려 버리는 것을 허용합니다. 아마도 그러한 일을하지는 않을 것이지만 오해의 소지가있는 값이나 어떤 것을 인쇄 할 수 있습니다.

하지 마십시오. 주소를 정수로 취급해야하는 경우가 아니면 %p을 사용하십시오 (참고 : 아마도 그렇지 않을 수도 있습니다). 이 경우 은 실제로 인수를 전달하는 메커니즘을 남용하지 않도록 정수 유형으로 캐스팅합니다.

0

위험과 부작용에 대해서는 잘 모르지만 % d 표기법을 사용하면 (12 대 0x000012와 같은) 포인터의 형식이 손실됩니다.

4
  • 를 sizeof (INT의 *)는

  • 라이브러리 구현 포인터 값이 다른, 더 적절한 표현을 자유롭게 사용할 수있다 (예를 들어 16 진수)를 sizeof (INT)와 동일 할 필요는 없다.

  • % p는 단순히 "해야 할 일"입니다. % d를 사용하면 정수 지정자를 잘못 사용하는 반면 포인터는 표준에 사용해야한다고 표시됩니다.

상상 누군가가 코드를 refactors, 다소 이상이-열정적으로 죄송합니다 ... 모든 "% ld 개"와 "긴"모든 "% d 개"와 "INT"를 교환 때 발생.

+0

감사합니다. 그것은 나에게서 게으른 생각이었고, 우리 아키텍처에 실제로 sizeof (int *) == sizeof (int)가있어서 운이 좋았습니다. 자동 16 진수 표기법이 좋습니다. – abishell

+0

웃긴다. 나를 위해 제 3의 총알 포인트는 항상 가장 강한 주장이었다. ;-) – DevSolar

0

다른 답변에서 지적한 위험 외에도 일부 컴파일러 (예 : 포맷 문자열 경고가 켜져있는 gcc)는 (int)을 가리키는 포인터를 전달하고 있다는 경고를 생성합니다.