Por que const char * não precisa de um ponteiro para um endereço de memória?

18

Essa pode ser uma pergunta simples, mas por que um const char * não precisa de um endereço de memória para apontar?

Exemplo:

const char* a = "Anthony";

e não:

const char *a = // Address to const char

como quaisquer outros tipos fazem?

Weidelix
fonte
8
O que faz você pensar que literais de string não têm endereços de memória?
user207421 18/04
2
Acordado. Eu não esperaria que alguém que fizesse essa pergunta soubesse que existem categorias de valor , muito menos que eles tenham nomes.
user4581301 18/04
13
Por favor, não faça perguntas marcadas com C e C ++. Como podemos observar, as respostas agora são específicas para C ++ e os comentários descarrilam novamente sobre as diferenças entre os dois idiomas. Existem tantas diferenças até agora que é difícil fazer uma pergunta que realmente tenha a mesma resposta válida para os dois idiomas. Decida qual idioma você deseja usar antes de perguntar, por favor.
larkey 18/04

Respostas:

26

Você pode imaginar esta declaração

const char* a = "Anthony";

da seguinte maneira

const char string_literal[] = "Anthony";

const char *a = string_literal;

Ou seja, o compilador cria uma matriz de caracteres com a duração do armazenamento estático que armazena a cadeia "Anthony"e o endereço do primeiro caractere da matriz (devido à conversão implícita de designadores de matriz em ponteiros para seus primeiros caracteres) é atribuído ao ponteiro a.

Aqui está um programa demonstrativo que mostra que literais de seqüência de caracteres são matrizes de caracteres.

#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;
}

A saída do programa é

The size of the referenced array is 8
Anthony

O tamanho da literal da string (da matriz que armazena a literal da string) é igual 8porque a string inclui também o caractere zero final ' \0'.

No programa demonstrativo a expressão

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

pode ser substituído apenas pela expressão

sizeof( r )
Vlad de Moscou
fonte
5

por que um const char não precisa de um endereço de memória para apontar? *

Faz.

Um literal de string C como

"Anthony"

está deteriorado para o endereço da sua 1 st personagem. Como, BTW; qualquer matriz em C faz.

alk
fonte
Mais especificamente, é do tipo const char[8](em C ++, pode estar char [8]em C, não tenho certeza) e, como todas as matrizes internas, ao usá-lo como um valor que decai para um ponteiro para seu primeiro elemento.
Nikos C.
@NikosC .: Obrigado por me lembrar do verbo mágico mais importante neste contexto! ;)
alk
Obrigado pela resposta! Fiquei me perguntando de onde isso tira a memória.
Weidelix
11
Não posso falar em C, mas tenho certeza de que o C ++ não especifica onde um literal de picada deve ser armazenado. Apenas fui cavar. Se houver uma regra, ela será enterrada em algum lugar estranho e distante de qualquer menção a "string literal".
user4581301 18/04
2
@NikosC. char [8]em C: c-faq.com/ansi/strlitnotconst.html
David Ranieri
1

Ele precisa de um endereço de memória e possui um endereço de memória. No seu exemplo, é simplesmente o endereço de memória do início da string. É o mesmo com qualquer outra variável de matriz inicializada em tempo de compilação, por exemplo "int array [] = {0, 1, 2, 3};".

Se você usasse um editor binário para examinar o executável, veria a string "Anthony" lá. Se você colocar a linha "printf (" a está em% p \ n ", (void *) a);))" no seu programa, compile e execute, você verá o endereço.

jamesqf
fonte
0

"Por que const char*não precisa de um ponteiro para um endereço de memória?"

De fato, ele precisa de um endereço de memória para apontar.

const char* asignifica aé um ponteiro para uma string literal ou constante de caractere.

Um ponteiro sempre exige um endereço para apontar, pois é da natureza de um ponteiro apontar para um objeto específico na memória. Então, ae qualquer outro ponteiro para const chartambém.

Uma literal de string como "Hi My Name is Alfred!"por uma atribuição como:

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

decai para um ponteiro para o endereço do primeiro elemento da string literal.

Por sua vez, aé atribuído pelo endereço do primeiro elemento da cadeia de caracteres literal "Hi My Name is Alfred!"que pode ser armazenado em qualquer lugar da memória, dependendo do ambiente de execução.

Não está no poder de um programador em que um literal de cadeia de caracteres esteja exatamente armazenado. Sua tarefa é apenas atribuir e manipular o respectivo ponteiro adequadamente.

RobertS suporta Monica Cellio
fonte