const char *がメモリアドレスへのポインタを必要としないのはなぜですか?


18

これは簡単な質問かもしれませんが、なぜconst char *が指すメモリアドレスを必要としないのですか?

例:

const char* a = "Anthony";

ではなく:

const char *a = // Address to const char

他のタイプと同じように?


8
文字列リテラルにメモリアドレスがないと思うのはなぜですか。
user207421

2
同意した。この質問をして、値のカテゴリが存在することを知っている人がいることは言うまでもありません。名前があることは言うまでもありません。
user4581301

13
CおよびC ++のタグが付いた質問をしないでください。観察できるように、答えはC ++固有になり、コメントは両方の言語の違いについて再び脱線します。現在では多くの違いがあり、実際には両方の言語で同じ有効な答えを持つ質問をすることは困難です。質問する前に、使用する言語を決定してください。
ラーキー

回答:


26

あなたはこの宣言を想像することができます

const char* a = "Anthony";

次の方法

const char string_literal[] = "Anthony";

const char *a = string_literal;

つまり、コンパイラは、文字列を格納する静的格納期間を持つ文字の配列を作成し、配列の"Anthony"最初の文字のアドレス(配列指定子を最初の文字へのポインタに暗黙的に変換するため)をpointerに割り当てます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'です。

実証プログラムでは、表現

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 .:この文脈で最も重要な魔法の動詞を思い出させてくれてありがとう!;)
アルク

答えてくれてありがとう!それはどこからメモリを得るのだろうと思っていました。
Weidelix

1
Cについて話すことはできませんが、C ++が文字列リテラルを格納する必要がある場所を指定していないことは確かです。ちょうど掘りに行った。ルールがある場合、それは「文字列リテラル」の言及から奇妙で遠く離れた場所に埋め込まれます。
user4581301


1

それはメモリアドレスを必要とし、それはメモリアドレスを持っています。あなたの例では、それは単に文字列の先頭のメモリアドレスです。コンパイル時に初期化される他の配列変数と同じです。たとえば、「int array [] = {0、1、2、3};」のようになります。

バイナリエディタを使用して実行可能ファイルを確認すると、そこに「Anthony」という文字列が表示されます。「printf( "a is at%p \ n"、(void *)a);」という行を入れた場合 プログラムで、コンパイルして実行すると、アドレスが表示されます。


0

「なぜconst char*メモリアドレスへのポインタが必要ないのですか?」

実際、ポイントするにはメモリアドレス必要です。

const char* a平均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.