To może być proste pytanie, ale dlaczego const char * nie potrzebuje adresu pamięci, aby wskazywać?
Przykład:
const char* a = "Anthony";
i nie:
const char *a = // Address to const char
jak inne typy?
To może być proste pytanie, ale dlaczego const char * nie potrzebuje adresu pamięci, aby wskazywać?
Przykład:
const char* a = "Anthony";
i nie:
const char *a = // Address to const char
jak inne typy?
Odpowiedzi:
Możesz sobie wyobrazić tę deklarację
const char* a = "Anthony";
w następujący sposób
const char string_literal[] = "Anthony";
const char *a = string_literal;
Oznacza to, że kompilator tworzy tablicę znaków o statycznym czasie przechowywania, który przechowuje ciąg "Anthony" a adres pierwszego znaku tablicy (z powodu niejawnej konwersji desygnatorów tablic na wskaźniki na ich pierwsze znaki) jest przypisany do wskaźnika a.
Oto program demonstracyjny, który pokazuje, że literały łańcuchowe są tablicami znaków.
#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;
}
Wyjście programu to
The size of the referenced array is 8
Anthony
Rozmiar literału łańcuchowego (tablicy przechowującej literał łańcuchowy) jest równy, 8ponieważ łańcuch zawiera również kończący znak zero \0'.
W programie demonstracyjnym wyrażenie
std::extent<std::remove_reference<decltype( r )>::type>::value
może być zastąpione tylko wyrażeniem
sizeof( r )
dlaczego const char nie potrzebuje adresu pamięci, aby wskazywać? *
To robi.
Literał C-string jak
"Anthony"
jest zepsute na adres jej 1 st charakteru. Podobnie jak BTW; robi to dowolna tablica w C.
const char[8](w C ++, może nie być char [8]w C, nie jestem pewien) i podobnie jak wszystkie wbudowane tablice, gdy używa go jako wartości, rozpada się na wskaźnik do pierwszego elementu.
char [8]w C: c-faq.com/ansi/strlitnotconst.html
Potrzebuje adresu pamięci i ma adres pamięci. W twoim przykładzie jest to po prostu adres pamięci początku łańcucha. Tak samo jest z każdą inną zmienną tablicową, która została zainicjowana w czasie kompilacji, na przykład „int array [] = {0, 1, 2, 3};”.
Jeśli użyjesz edytora binarnego do sprawdzenia pliku wykonywalnego, zobaczysz tam ciąg „Anthony”. Jeśli wstawisz wiersz „printf („ a jest w% p \ n ”, (void *) a);” w swoim programie, a następnie skompiluj i uruchom go, zobaczysz adres.
„Dlaczego
const char*nie potrzebuje wskaźnika do adresu pamięci?”
W rzeczywistości tak potrzebujesz adresu pamięci do punktu do.
const char* a znaczy a wskaźnik do literału lub stałej znakowej.
Wskaźnik zawsze wymaga adresu do wskazania, ponieważ charakter wskaźnika wskazuje na określony obiekt w pamięci. Więc,a i każdy inny wskaźnik doconst char .
Dosłowny ciąg znaków, taki jak "Hi My Name is Alfred!"przy przypisaniu:
const char* a;
a = "Hi My Name is Alfred!";
rozpada się na wskaźnik do adresu pierwszego elementu literału łańcucha.
Oznacza z kolei, azostaje przypisany przez adres pierwszego elementu literału łańcucha"Hi My Name is Alfred!" który może być przechowywany w dowolnym miejscu w pamięci w zależności od środowiska wykonywania.
To nie jest w mocy programisty, gdzie dosłowny ciąg znaków jest dokładnie przechowywany. Twoim zadaniem jest tylko odpowiednie przypisanie i obsługa odpowiedniego wskaźnika.