const char *에 메모리 주소에 대한 포인터가 필요하지 않은 이유는 무엇입니까?


18

이것은 간단한 질문 일 수 있지만 const char *는 왜 메모리 주소가 필요하지 않습니까?

예:

const char* a = "Anthony";

그리고 아닙니다 :

const char *a = // Address to const char

다른 유형과 마찬가지로?


8
문자열 리터럴에 메모리 주소가 없다고 생각하는 이유는 무엇입니까?
user207421

2
동의했다. 나는이 질문을 하는 사람이 이름을 가지고 있음은 물론 가치 범주 가 존재한다는 것을 알기를 기대하지 않을 것 입니다.
user4581301

13
C 및 C ++ 태그가 지정된 질문은하지 마십시오. 우리가 볼 수 있듯이, 답변은 이제 C ++에 국한되며 주석은 두 언어의 차이점에 대해 다시 탈선합니다. 두 언어에 대해 실제로 동일한 대답을 갖는 질문을하기가 어려워 지금까지 많은 차이가 있습니다. 묻기 전에 사용할 언어를 결정하십시오.
larkey

답변:


26

이 선언을 상상할 수 있습니다

const char* a = "Anthony";

다음과 같은 방법

const char string_literal[] = "Anthony";

const char *a = string_literal;

즉, 컴파일러는 문자열을 저장하는 정적 저장 기간으로 문자 배열을 만들고 배열의 "Anthony"첫 번째 문자 주소 (어레이 지정자가 첫 번째 문자에 대한 포인터를 암시 적으로 변환하기 때문에)가 포인터에 할당됩니다 a.

다음은 문자열 리터럴이 문자 배열임을 보여주는 실증 프로그램입니다.

#include <iostream>
#include <type_traits>

decltype( auto ) f()
{
    return ( "Anthony" );
}

template <size_t N>
void g( const char ( &s )[N] )
{
    std::cout << s << '\n';
}

int main() 
{
    decltype( auto ) r = f();

    std::cout << "The size of the referenced array is "
              << std::extent<std::remove_reference<decltype( r )>::type>::value
              << '\n';

    g( r );

    return 0;
}

프로그램 출력은

The size of the referenced array is 8
Anthony

문자열 리터럴 (문자열 리터럴을 저장하는 배열)의 크기는 문자열 8에 종료하는 0 문자도 포함 하기 때문에 동일합니다 \0'.

실증 프로그램에서 표현

std::extent<std::remove_reference<decltype( r )>::type>::value

식으로 만 대체 될 수있다

sizeof( r )

5

const char 에 메모리 주소가 필요하지 않은 이유는 무엇입니까? *

그렇습니다.

C 문자열 리터럴

"Anthony"

첫 번째 문자 의 주소로 소멸됩니다 . BTW처럼; C의 모든 배열은 않습니다.


더 구체적으로, 그것은 유형 const char[8](C ++에서는 C에있을 수 있음 char [8])이며 모든 내장 배열과 마찬가지로 값으로 사용할 때 첫 번째 요소에 대한 포인터로 부패합니다.
Nikos C.

@NikosC .:이 맥락에서 가장 중요한 마법 동사를 상기시켜 주셔서 감사합니다! ;)
alk

답변 해주셔서 감사합니다! 메모리가 어디서 나오는지 궁금했습니다.
Weidelix

1
C를 말할 수는 없지만 C ++은 스팅 리터럴을 저장할 위치를 지정하지 않을 것이라고 확신합니다. 그냥 파고 갔다. 규칙이 있으면 "문자열 리터럴"에 대한 언급과는 거리가 먼 곳에 묻혀 있습니다.
user4581301


1

메모리 주소가 필요하며 메모리 주소가 있습니다. 귀하의 예에서는 단순히 문자열 시작 부분의 메모리 주소입니다. 컴파일 타임에 초기화되는 다른 배열 변수와 동일합니다 (예 : "int array [] = {0, 1, 2, 3};").

바이너리 편집기를 사용하여 실행 파일을 보면 "Anthony"라는 문자열이 표시됩니다. "printf ("a는 % p \ n ", (void *) a)"; 프로그램에서 컴파일하고 실행하면 주소가 표시됩니다.


0

" const char*메모리 주소에 대한 포인터가 왜 필요 하지 않습니까?"

실제로, 그것을 가리 키기 위해 메모리 주소 필요합니다.

const char* ameans a는 문자열 리터럴 또는 문자 상수에 대한 포인터입니다.

포인터 는 메모리의 특정 객체를 가리키는 포인터의 특성이기 때문에 항상 가리키는 주소가 필요합니다. 따라서 a다른 포인터 const char도 마찬가지입니다.

다음과 같은 "Hi My Name is Alfred!"할당으로 문자열 리터럴 :

const char* a;
a = "Hi My Name is Alfred!";

문자열 리터럴의 첫 번째 요소 주소에 대한 포인터로 감소합니다.

차례로 의미 는 실행 환경에 따라 메모리의 어느 곳에 나 저장 될 수있는 a문자열 리터럴의 첫 번째 요소의 주소에 의해 지정됩니다 "Hi My Name is Alfred!".

문자열 리터럴이 정확하게 저장된 프로그래머에게는 적합하지 않습니다. 귀하의 임무는 각 포인터를 적절하게 할당하고 처리하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.