내가 이렇게하면 실제로 어떻게됩니까?포인터에 형식 지정자 저장
{
char * str = "%d\n";
str++;
str++;
printf(str-2,300);
return 0;
}
직관적으로 화면의 숫자는 300이지만, str에 저장되는 내용을 알고 싶습니다.
편집 : 누군가가 내게 말할 수 있다면 정말 좋을 것입니다. 우리는 언제 이것을 실제로합니까? 감사합니다.
내가 이렇게하면 실제로 어떻게됩니까?포인터에 형식 지정자 저장
{
char * str = "%d\n";
str++;
str++;
printf(str-2,300);
return 0;
}
직관적으로 화면의 숫자는 300이지만, str에 저장되는 내용을 알고 싶습니다.
편집 : 누군가가 내게 말할 수 있다면 정말 좋을 것입니다. 우리는 언제 이것을 실제로합니까? 감사합니다.
str
은 메모리 주소이며, 처음에는 문자열 주소 인 %d\n
의 주소입니다. 이 리터럴은 코드에 있기 때문에 생성됩니다.
str이 문자 \n
을 가리키게하고,이 경우 str - 2
은 %
부호의 주소입니다. 따라서 printf는 형식 문자열 %d\n
을보고 평상시처럼 첫 번째 인수를 형식 문자열 다음에 정수로 인쇄합니다. 사실, printf는 형식 문자열의 기원을 신경 쓰지 않습니다. 직접 작성하거나 하드 코딩 할 수 있는지 여부는 중요하지 않습니다.
일반적으로 그렇게하지 않습니다. 때로는 문자열을 스캔하거나, 문자열에서 어떤 것을 추출하거나, 문자열의 일부 접두사를 건너 뛰기 위해 문자 포인터를 이용해야 할 때가 있습니다.
글자 포인터를 선언하고 있습니다. 이 포인터는 %
(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 출력.
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)
' "% d \ n"'이 유일한 문자열 리터럴입니다 (4 개의 문자 배열입니다). 포인터는 해당 배열 내의 다양한 오프셋을 가리 킵니다. –
출력 할 것인가? 추가 설명이 필요한 'x ++'또는 'x-2'에 대한 것이 있습니까? –
이것은 내 테스트 중 하나에서 나온 것입니다. 나는'str = % d' 부분을 추론 할 수 없었다. – user3797829
왜? '++ '가 무엇을하는지 알고 있습니까? –