1

次の 3 つの例の理解を深めたいと思っています。

これは、次のコード例に対する私の質問です。

  • 元。1. 例は理にかなっています。int a が格納されているアドレスを出力します。
  • 元。2. あまり意味がありません。char自体がcharを指しているからだと思いますか?
  • 元。3.私を混乱させます。出力では、最初の char 出力は常に char に格納されている on です。しかし、追加文字とは何ですか? &a を char ポインターに保存した後にそれらが表示されるのはなぜですか?

最後に、char 変数が保存されているメモリ位置のアドレスを出力するにはどうすればよいですか?

元。1

main(void) 
{
  int a = 1;
  cout << &a;
}

メモリアドレス ex を出力します。0x7fff4241b7b4

例 2。

main(void) 
{
  char a = 'a';
  cout << &a;
}

文字 a を出力します。元。a

元。3.

main(void) 
{
  char a = 'a';
  char *b = &a;
  cout << &a;
}

出力a��:��

4

2 に答える 2

6

operator<<(const void*)最初のポインターは、ポインター値を出力する と一致します。operator<<(const char*)null で終わる文字列を出力する2 番目と 3 番目の一致。

charaはスタック上の値であるため、最初のバイトの後のバイトが null であるかどうかはまったく定義されていません。幸いなことに、中間のケースでは null バイトが続きますが、3 番目のケースでは、次のいくつかのバイトは null バイトではなく、 UTF-8 文字が壊れます。ポインターを設定しているという事実は、プログラムの実行には影響しませんが、スタック フレームの設定は異なります。たとえば、GCC はmovb $97, -9(%rbp)アセンブラー オペコードを発行して、バイトをスタックに設定し、char をアライメントされていないアドレスに配置します。私のコンピューターのスタックレイアウトはこれです(64ビット)

| x | x | x | x | x | x | a | b | b | b | b | b | b | b | b |
                                                            ^
                                                           RPB

したがってa、スタック上にあり、その後に直接 b ポインター値が続きます。私のマシンで実行しているときに表示されるガベージは、このポインター値から来ています。実際、ex 3を次のように変更すると

#include <iostream>

int main(void) 
{
    char a = 'a';
    long b = 0x68676665646362l;
    std::cout << &a;
}

出力が得られます

abcdefgh

もちろん、これは未定義の動作の例です。別のコンパイラを使用してコンパイルし、別のプラットフォームで実行すると、プログラムは標準に従ってクラッシュしたり、ハムレットの完全なテキストを出力したり、自己認識を達成したりできます。

于 2013-08-18T15:21:09.187 に答える
2

2 番目と 3 番目の例では、ポインターを string として出力します。ただし、実際のデータは文字列ターミネータのない単一の文字であるため、出力演算子がターミネータの検索で実際のデータを超えて出力し続けるため、未定義の動作が発生します。

実際のポインターを出力したい場合は、ポインターをキャストする必要があります。

std::cout << static_cast<void*>(&a) << '\n';
于 2013-08-18T15:18:03.467 に答える