2014-10-04 3 views
0

변수의 주소를 c로 인쇄하는 동안 unsigned int (형식 문자열로 %u)를 사용한다는 것을 알게되었습니다.
범위는 0에서 65535입니다. 이제 정수는 4 바이트의 메모리를 사용합니다. 즉, 최대 16384 (65536/4) 정수를 저장할 수 있습니다. 배열 int a[20000]을 선언하고 각 요소의 주소를 얻으려면 어떻게 될까요?포인터 변수의 주소를 출력합니다.

#include<stdio.h> 
int main(void) 
{ 
    int a[20000]; 
    for(i=0; i<19999; i++]) 
     printf("%u", &a[i]); 
} 
+0

% x은 어떻습니까? 그것은 16 진수 – Lee

+10

잘못 배웠습니다 : % p – Soren

+0

코드를 참조하십시오. –

답변

1

C의 초기에는 비슷한 유형의 포인터와 int이며, 안전하게 다른 곳으로 캐스팅하고 다시 되돌릴 수 있습니다. 이른시기에 포인터와 int는 모두 16 비트 길이였습니다. int가 32 비트가되는 32 비트 시스템에서는 여전히 유효합니다. 하지만 포인터가 64 비트 길이이고 32 비트 만 지원하기 때문에 64 비트 시스템에서는 false입니다.

그래서 어디 모르는 당신은 C에서 변수의 주소를 인쇄 동안, 우리는 부호없는 INT (U %)를 사용하는 것이 배운 방법하지만, 일반적인 경우는 잘못 때문에 빨리 잊어 . 주소를 인쇄하는 유일한 방법은 %p입니다. 시스템이 자동으로 크기를 16, 32 또는 64 비트로 조정하기 때문입니다.

포인터를 int 또는 반대쪽으로 변환하지 않아도됩니다. 이식성이 높기 때문에 포인터를 int 또는 반대쪽으로 변환하지 않아도됩니다. 그 외 post에서 (C99 표준 변형에 대한) 더 이식 가능한 방법은 #include <stdint.h>이며 intptr_t (및 뒤)에 대한 포인터를 캐스팅하는 것입니다. 이 정수 유형은 포인터의 크기가 보장됩니다.

는, 나는 거의 65536 = 0x10000에 = 2 16, 2 32 = 4294967296. 그래서 당신은 그렇게 멀리 현실에서하지 않았다 잊고, 그리고 나이가 16 비트 시스템에서 당신이 수없는 것이 사실이다 int array[40000] int는 16 비트 길이이고 배열은 사용 가능한 모든 메모리를 모두 소모하기 때문에.

그러나 32 비트 시스템에서는 4GB의 메모리를 주소 지정할 수 있으므로 int array[20000]은 무해합니다.

+0

float i = 4.2; * j; j = & i; 여기에 j의 데이터 형식은 무엇입니까 –

+0

'float i = 4.2; float * j = & i;'여기서'j'는 float ('float *')에 대한 포인터이며,'void *'에 안전하게 캐스팅 할 수 있고'% p' 형식으로 출력 할 수 있습니다. 그래서 당신은 맞습니다'j'는 부유물이 아니지만 int도 길지도 않습니다. 그것은 'float *'이고'* j'는 float입니다. –

-1

실제로 부호없는 정수는 turbo c와 같은 구형 16 비트 컴파일러에서 0에서 65536 사이의 범위를 갖습니다. 이제 모든 시스템은 부호없는 정수 범위가 0에서 4G (기가) 인 32 또는 64 비트 아키텍처를 사용하고 있습니다. 따라서이 코드는 gcc (Linux) 또는 Visual Studio (Windows)와 같은 최신 컴파일러에서 올바르게 작동해야합니다. 이 컴파일러로 전환 해보십시오. 그들은 아주 좋으며 지금은 널리 사용됩니다. 16 비트 컴파일러는 쓸모가 없습니다. 그러한 컴파일러를 사용하지 마십시오. 창문을 사용하고 있다면 코드 블록이나 dev C++는 학습을위한 좋은 프로그래밍 IDE입니다. c.

P. % u를 주소 인쇄에 사용하지 마십시오. 대신 % p를 사용하십시오.

+0

float i = 4.2; * j; j = & i; 여기에 j의 데이터 형식은 무엇입니까 –

+0

j는'float *'입니까? –

+0

아니요 j는 부동 변수의 주소를 저장합니다.그것 자체가 플로트가 아니다. –

1

포인터는 일부 데이터를 찾을 수있는 메모리 주소입니다. sizeof() 연산자를 사용하여 포인터 변수의 크기를 찾을 수 있습니다. 그래서 그것의 크기는 무엇을 가리키는 지에 달려 있지 않습니다. 그러나 메모리 주소가 32 비트 컴파일러의 경우 4이고 64 비트 컴파일러의 경우 8입니다.

우리가 포인터를 선언 한 경우

두 번 J, J의 유형은 배정, 즉 "두 배로 포인터"입니다.

퍼센트의 p는 포인터를 인쇄하기위한 올바른 형식 지정자입니다. % p를 출력 주소

때때로 % u 및 % x (16 진수 형식의 부호없는 정수) 지정자를 사용하여 포인터 변수를 인쇄합니다.그러나 % x 또는 % u 인수에 대한 포인터를 전달하는 것은 정의되지 않은 동작입니다.

그러나 코드 블록과 같은 32 비트 컴파일러에서 작동합니다. 서명되지 않은 int 크기와 포인터가 여기에 동일하기 때문입니다. (양쪽 모두 4 바이트)

int와 포인터가 같은 너비를 갖는다 고 가정하는 것은 허위입니다 .x64에서 실행되는 GCC 64 비트와 MSVC 64 비트의 경우 sizeof (void *) == 8 인 반면 sizeof (unsigned int) == 4. 일부 아키텍처에서는 포인터와 int가 같은 크기, 예를 들어 PDP-11/34a 또는 요즘 대부분의 32 비트 아키텍처에서 발생합니다. 그러나이 아키텍처에 의존하는 코드를 작성하는 것은 현명하지 않습니다. .

당신은 다음과 같이 추가로 2 줄을 추가하고 확인 할 수 :

의 printf을 (를 sizeof (서명 int)를 "서명되지 않은 INT의 크기가 % 루 \ 없음입니다"); 의 printf ("포인터의 크기는 % lu \ n ", sizeof (int *));

비트 운영 체제와 64 비트 GCC의 시스템에서 617,451,515,

,이 (x는 부호없는 정수로 포인터를 캐스트) 각각에게 32 GCC는 64 비트 머신 %에

4, 8을 주어야한다 비트 길이). 포인터의 크기는 8 바이트 (64 비트) 길이입니다. % p로 인쇄하면 전체 포인터가 64 비트 크기로 인쇄됩니다. 그러나 % x로 인쇄 할 때 하위 32 비트 만 인쇄됩니다. 따라서 항상 % p 포인터를 인쇄하는 것이 안전합니다.

관련 문제