2014-07-20 3 views
-1

내가 이렇게하면 실제로 어떻게됩니까?포인터에 형식 지정자 저장

{ 
    char * str = "%d\n"; 
    str++; 
    str++; 
    printf(str-2,300); 
    return 0; 
} 

직관적으로 화면의 숫자는 300이지만, str에 저장되는 내용을 알고 싶습니다.

편집 : 누군가가 내게 말할 수 있다면 정말 좋을 것입니다. 우리는 언제 이것을 실제로합니까? 감사합니다.

+1

출력 할 것인가? 추가 설명이 필요한 'x ++'또는 'x-2'에 대한 것이 있습니까? –

+0

이것은 내 테스트 중 하나에서 나온 것입니다. 나는'str = % d' 부분을 추론 할 수 없었다. – user3797829

+1

왜? '++ '가 무엇을하는지 알고 있습니까? –

답변

3

str은 메모리 주소이며, 처음에는 문자열 주소 인 %d\n의 주소입니다. 이 리터럴은 코드에 있기 때문에 생성됩니다.

str이 문자 \n을 가리키게하고,이 경우 str - 2% 부호의 주소입니다. 따라서 printf는 형식 문자열 %d\n을보고 평상시처럼 첫 번째 인수를 형식 문자열 다음에 정수로 인쇄합니다. 사실, printf는 형식 문자열의 기원을 신경 쓰지 않습니다. 직접 작성하거나 하드 코딩 할 수 있는지 여부는 중요하지 않습니다.

일반적으로 그렇게하지 않습니다. 때로는 문자열을 스캔하거나, 문자열에서 어떤 것을 추출하거나, 문자열의 일부 접두사를 건너 뛰기 위해 문자 포인터를 이용해야 할 때가 있습니다.

2

글자 포인터를 선언하고 있습니다. 이 포인터는 % (1 바이트) d (1 바이트) \n (UNIX에서는 1 바이트, Windows에서는 2 바이트) 및 \0 문자열을 끝내는 null 종결 바이트를 쓸 위치에서 RAM 주소를 보유합니다.

포인터 값 (첫 번째 바이트의 주소)을 2 씩 증가시킨 다음 2 씩 감소시킵니다. 그래서 기본적으로 당신은 아무것도하지 않습니다. 따라서 printf()src-2을 호출하면 %d\n을 가리키고 널 종단 바이트는 정확히 %d\n을 전달합니다. 그래서 하루가 끝날 때 당신이하는 일은 다음과 같습니다 :

printf("%d\n", 300); 따라서 300 출력.

2

str은 스택의 포인터입니다. 처음에는 문자열 리터럴 "%d\n" (이것은 아마도 컴파일러가 프로그램의 읽기 전용 섹션에 저장하는)의 시작을 가리 킵니다 (즉, 주소를 보유하고 있습니다).

예를 들어 문자열 리터럴 ("$d\n")이 0x5000에 저장되어 있다고 가정 해 봅시다. 그래서 0x5002이 \n (개행)과 0x5003에서가 (널 종료 문자)

str 처음 잡고 \0이다, 0x5000에서 바이트 0x5001에서 바이트 d이다 %이다 (UTF-8 또는 ASCII 가정) 주소는 0x5000입니다. str++은 0x5001로 증가합니다. 즉, 문자열 "d\n"을 가리 킵니다. 즉, 문자열 리터럴 "%d\n"에있는 한 문자를 가리 킵니다. 마찬가지로 str++은 다시 0x5002로 이동합니다. 즉, "\n" 문자열, 두 번째 문자는 "%d\n" 문자열 리터럴로 이동합니다. 이들 모두는 여전히 0x5003에 널 문자 (문자열이 끝나는 시점을 C가 어떻게 알 수 있는지)로 끝납니다.

printf 호출의 형식은 첫 번째 인수로 string입니다.이 시점에서 str은 0x5002를 보유하고 있으므로 호출은 '0x5002 - 2 = 0x5000에서 시작하는 형식 문자열 사용'을 말합니다.이 문자열은 우리가 시작한 문자열과 동일합니다.

따라서는

printf("%d\n",300) 

를 호출하는 것과 동일하고 스스로를 추론하지 못하도록 무엇 (300)

+1

' "% d \ n"'이 유일한 문자열 리터럴입니다 (4 개의 문자 배열입니다). 포인터는 해당 배열 내의 다양한 오프셋을 가리 킵니다. –