ここから本文です

C++の初歩ポインターの宣言について 以下の出力がなぜ違うのかわかりません in...

asc********さん

2019/8/1423:38:09

C++の初歩ポインターの宣言について
以下の出力がなぜ違うのかわかりません

int *p;
cout << p;
cout << &p;

閲覧数:
59
回答数:
4

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

あみやさん

2019/8/1503:31:08

ポインタかどうかはあまり関係ありません。

int a;
cout << a;
cout << &a;

でも同じく内容は異なるはずです。

変数名をそのまま書いた場合、変数の中にあるデータの値を表します。
上のaで有れば、int型なのでaに代入された整数を
元のpで有れば、int型へのポインタなので、pに代入されたメモリアドレスを
どちらも、代入されていない時は不定(何が入っているかわからない)となります。

&を付けた場合は、その変数自体が存在するメモリアドレスになります。
&aであれば、変数aが存在するメモリアドレスを
&pであれば、変数pが存在するメモリアドレスを
どちらも扱いに違いはありません。

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

ikt********さん

2019/8/1509:54:22

ポインター に関する知識がたりないから、って話じゃないのでは。(^_^;)

p と &p は、意味・型 が違います。
既に的確ご回答あるとおり、& はアドレス演算子 なので。


出力内容が異なるのは、また別の話。
おもいっきりカンタンに追えば、
・cout が引数の型を識別し、
・出力する文字列編集形式を変えてる
からです。
ポインタなぞ使わず、やってみればいい。
int n = 1234;
cout << n << endl; // 1234
cout << &n << endl; // 変数nの配置アドレス

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

prwssさん

2019/8/1509:46:33

>以下の出力がなぜ違うのかわかりません

これは『分かる』という部類のものではなく、他人の決めたルールに従うかどうかです

あなたにとって気に入らないルールならば、覚えなくてもよいです

出力が何故違うかといいますと、違うように作ったからでして、そのルールが表出しているのが&や*を付けた時の書き方です

なので、「なぜ違うのか」という質問はこの界隈では全て無意味でして、界隈では「そうなるように誰かがルールを作った」となります

「なぜ」というものがなく、「そう決めたからそうなっている」という堂々巡りのようなものしかありませんので、今回の場合は「出力が違ってくるようにC言語全体のルールを整えた」というのが、もっとも正しいです

プログラミング言語は100%の人工物なので、「なぜ」という問いには向いてないからです

「そのルールはどこかの誰かがそう作った、そう思い付いた」程度でして、「なぜ」と問うこと自体が愚問のジャンルです

そのルールに賛同するか、受け入れるか、納得するか、のどれかしかありえません

プロフィール画像

カテゴリマスター

n2q********さん

2019/8/1509:24:11

【cout << p;】

p の値(誰かの住所)を出力します。


【cout << &p;】

p の住所を出力します。



~出力がなぜ違うのか~

p は誰かの住所を覚える係です。p の値とは、その誰かの住所です。お示しのコード片では p は誰の住所も覚えておらず、p が自動変数であるとすると出鱈目な住所が p の値となっている状態です。この状態で cout に p を出力すると出鱈目な住所が出力されます。

&p は p の住所です。つまり、出鱈目ではない住所。

このように出鱈目な住所と、出鱈目ではない住所が出力される形となり、確率的に言っても両者が違うのが当然となります。


~実験~

#include <iostream>
using namespace std;
int main()
{
int *p;
cout << p << endl;
p = reinterpret_cast<int*>(&p);
cout << p << endl;
cout << &p << endl;
return 0;
}


《出力結果》

CCCCCCCC
005BFA50
005BFA50


《解説》


〔CCCCCCCC の出力について〕

p は未初期化の状態で cout に出力され、p が現在覚えている値、つまり出鱈目な住所を出力します。

これは Visual C++ 2019 でのデバッグ版における事例ですが、出鱈目な住所の代わりに、特定の住所として 0xCCCCCCCC が設定されています。これで未初期化の値を参照したことを検出しようという古くからある Visual C++ の取り組みの一つであり、実際、このプログラムを実行すると、

Run-Time Check Failure #3 - The variable 'p' is being used without being initialized.

といったエラーが報告され、一時的に処理が止まります。上記の出力結果は、この中断に対して [F5] で続行させたものになります。


〔005BFA50 の出力について〕

この実行事例においては p の住所が 0x005BFA50 番地であったことを示しています。

p = reinterpret_cast<int*>(&p);

この処理によって、p の住所を p 自身に覚え込ませています。p の住所は int ** 型であり、p が記憶すべきデータの型である int * と異なります。そこで reinterpret_cast 演算子によって型を合わせています。なお、この部分は C 言語風に p = (int*)&p; と書いても構いません。

p が p 自身の住所を覚えたことにより、cout << p と cout << &p の出力内容は一致することになります。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる