Const char * neden bellek adresinin imlecine ihtiyaç duymaz?


18

Bu basit bir soru olabilir, ancak bir const char * işaret etmek için neden bir bellek adresine ihtiyaç duymaz?

Misal:

const char* a = "Anthony";

ve yok:

const char *a = // Address to const char

diğer tipler gibi?


8
Dize değişmezlerinin bellek adresleri olmadığını düşünmenizi sağlayan şey nedir?
user207421

2
Kabul. Bu soruyu soran kimsenin , isim kategorileri olsa bile , değer kategorilerinin var olduğunu bile bilmesini beklemem .
user4581301

13
Lütfen C ve C ++ ile etiketlenmiş sorular sormayın. Gözlemleyebildiğimiz gibi, cevaplar şimdi C ++ 'ya özeldir ve yorumlar her iki dil arasındaki farklar hakkında tekrar rayından çıkar. Şimdiye kadar o kadar çok fark var ki, her iki dil için de aynı geçerli cevaba sahip bir soru sormak zor. Lütfen sormadan önce hangi dili kullanmak istediğinize karar verin.
larkey

Yanıtlar:


26

Bu beyanı hayal edebilirsiniz

const char* a = "Anthony";

aşağıdaki yol

const char string_literal[] = "Anthony";

const char *a = string_literal;

Yani derleyici, dizeyi saklayan statik depolama süresine sahip bir dizi karakter oluşturur ve dizinin "Anthony"ilk karakterinin adresini (dizi belirleyicilerinin işaretçileri ilk karakterlerine örtük olarak dönüştürmesi nedeniyle) işaretçiye atanır a.

Dize değişmezlerinin karakter dizileri olduğunu gösteren örnek bir program.

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

Program çıktısı

The size of the referenced array is 8
Anthony

Dize değişmezinin (dize değişmezini saklayan dizinin) boyutu eşittir, 8çünkü dize ayrıca sonlanan sıfır karakterini içerir '\0' .

Gösterici programda ifade

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

sadece ifade yerine kullanılabilir

sizeof( r )

5

Bir const char neden işaret etmek için bir bellek adresine ihtiyaç duymuyor? *

Öyle.

C-string değişmez

"Anthony"

onun 1 adresine çürümüş olan st karakteri. BTW gibi; C'deki herhangi bir dizi yapar.


Daha spesifik olarak, türdür const char[8](C ++ 'da char [8], C'de olabilir , emin değilim) ve tüm yerleşik diziler gibi, değer olarak kullanıldığında ilk öğesinin işaretçisine bozulur.
Nikos

@NikosC .: Bu bağlamdaki en önemli sihirli fiili hatırlattığın için teşekkürler! ;)
alk

Cevap için teşekkürler! Hafızayı nereden aldığını merak ediyordum.
Weidelix

1
C için konuşamıyor, ancak C ++ bir sokma değişmezi saklanması gereken yerde belirtmez eminim. Sadece kazmaya gittim. Bir kural varsa, tuhaf bir yere gömülü ve "string literal" ifadelerinden uzak duruyor.
user4581301

2
@NikosC. char [8]C dilinde
David Ranieri

1

Bir bellek adresine ihtiyaç duyar ve bir bellek adresine sahiptir. Örneğinizde, dizenin başlangıcının bellek adresidir. Derleme zamanında başlatılan diğer herhangi bir dizi değişkeni ile aynıdır, örneğin "int dizi [] = {0, 1, 2, 3};".

Yürütülebilir dosyaya bakmak için bir ikili düzenleyici kullandıysanız, orada "Anthony" dizesini görürsünüz. "Printf (" a% p \ n ", (void *) a);" programınızda, derleyin ve çalıştırın, adresi göreceksiniz.


0

"Neden const char*bir bellek adresinin göstergesine gerek yok?"

Aslında, O does işaret edecek bir bellek adresi lazım.

const char* aanlamına gelir abir dizgi değişmezi veya karakter sabitine bir işaretçi.

İşaretçi her zaman işaret etmesi gereken bir adres gerektirir, çünkü bellekteki belirli bir nesneyi işaret eden işaretçinin doğasıdır. Yani, ave diğer işaretçi içinconst char yapar.

"Hi My Name is Alfred!"Ödev gibi bir dize hazır bilgisi :

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

dize değişmezinin ilk öğesinin adresinin göstergesine bozunur.

Sırayla anlamına gelir, a"Hi My Name is Alfred!" yürütme ortamına bağlı olarak bellekte herhangi bir yerde saklanabilen dize hazır bilgisinin ilk öğesinin adresi tarafından atanır .

Bir dizgi hazır bilgisinin tam olarak depolandığı bir programcının kudretinde değildir. Ödeviniz yalnızca ilgili işaretçiyi uygun şekilde atamak ve işlemek içindir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.