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, 8
ponieważ ł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, a
zostaje 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.