intへのポインタ型
①でintへのポインタ型で変数pを定義する。
②でint型の変数xに20をいれる。
③変数pにxのアドレスをいれる。
④変数pの値を出力する
p と*pの明確な違いが分かりません。
どうやって理解すればいいでしょうか?
int main() { int* p ; ① int x=20; ② p = &x; ③ printf("%d", *p); ④ return 0; } コード
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
int* p;
という書き方が良くないです。int *p;
と書いた方が良い。これは「*pがintである」という宣言です。
p
がポインタで、*p
がint(pがポイントしているメモリに入っている整数値)です。
補足:
1行目に書いたのは、空白をどこに入れるかの問題では無く、宣言文がどういう意味を持っているかという話です。
〇「pがintである」
×「pはintである」・・・・「int*
」という構文はありません
x = -y;
を、x =- y;
と書いて、「=-
は符号反転して代入する演算子である」と主張すると変ですよね。空白の位置を変えても意味は変わらないし、今のCには=-
という構文は無いし。
「int*
はintへのポインタを宣言する記法だ」はそれと同じくらい変です。
投稿2015/09/02 12:00
編集2015/09/02 14:33総合スコア84555
0
p : pに格納されているメモリ上のアドレスを示す
*p: pに格納されているメモリ上のアドレスに格納されている値を示す
あなたが 東京都千代田区1-1-1に住んでいるとすると
p→東京都千代田区 1-1-1
*p→あなた
という感じです
投稿2015/09/02 11:50
編集2015/09/02 11:56総合スコア243
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
以下の関係を知るには、コンピュータのメモリの扱いを知ることが不可欠だと思います。
p = *p
メモリは基本的に一次元の配列と同じです。
番地(アドレス)という形で、記憶領域(メモリ)は並んでいる順番に区画されています。
区画ごとの記憶容量は、基本的に1バイトです。
0x00番地からのメモリ内容が以下のようになっているとします。
(0x00 〜 0x07 の8バイトのメモリ内容を16進数表記しています。メモリ内容がすべて 0xFF になっているのは説明用だからです。実際はこの限りではありません。)
0x00: FF FF FF FF FF FF FF FF
0x08: FF FF FF FF FF FF FF FF
0x10: FF FF FF FF FF FF FF FF
仮にchar配列で 0x00番地からデータを定義した場合を考えます。
例1)
C
1char cNum[] = {0,1,2,3,4}; 2//配置されるデータ: 3//0x00: 00 01 02 03 04 FF FF FF
例2)
C
1char cNum[] = "01234"; 2//配置されるデータ: 3//0x00: 30 31 32 33 34 00 FF FF
例1の場合は、char配列に数値を格納しています。
{}の括りで配列に数値を収めた場合は、指定した値がそのまま配置されます。
ですので、0x00番地から5バイトの領域に 0x00〜0x04 が配置されます。
例2の場合は、char配列に文字列を格納しています。
文字列の場合は文字列データの最後に終端文字(0x0)が付されるので、実際のデータは {'0','1','2','3','4',0} と同じ意味を持つ記述になります。
従って、配置データの最後6バイト目に 0x0 がある事が分かります。(配置データは、文字列の表記より1バイト大きい。)
int型の場合は、コンピュータによってデータ幅が異なります。
最近のIntelCPUだと32bit幅が標準なので4バイトです。
(またIntel系のCPUはリトルエンディアンなので、メモリへは下位バイトから順に配置される点に注意。)
例3)
C
1int num[] = {0,1,2,3,4}; 2//配置されるデータ: 3//0x00: 00 00 00 00 01 00 00 00 4//0x08: 02 00 00 00 03 00 00 00 5//0x10: 04 00 00 00 FF FF FF FF
例4)
C
1int num = 0x1234_5678; 2//配置されるデータ: 3//0x00: 78 56 34 12 FF FF FF FF
p = *p についてもう一度考えますが、説明の都合、変数と変数のポインタを別々の変数定義にしてみます。
C
1int num1; 2int num2; 3int *pNum;
ここで num1 = 1; を行うと、メモリにはint値:0x0000_0001(32bit幅の数値:1)がセットされます。
0x??: 10 00 00 00 ..
仮に配置されるアドレスが 0x38 だった場合、pNum = # を実行すると pNum の値は 0x38になります。
(最近のCPUは32bitや64bit幅でのアドレス管理なので、実際にはもっと大きな数値が収まる。)
num2 = 0x10; を行うと、メモリにはint値:0x0000_0010(32bit幅の数値:0x10)がセットされます。
ここでnum2の配置されるアドレスが 0x3C だった場合、pNum = &num2; を実行すると pNum の値は 0x3Cになります。
この時のメモリの内容は以下の通りです。
0x38: 01 00 00 00
0x3C: 10 00 00 00
そして、この時 p = *p になる関係はどの変数になるかといえば、num2 = *pNum です。
pNum = 0x3C ですから、ポインタ:pNum のメモリにセットされた値は 0x10(=num2) です。
pNum = &num2; 直前だったらどうか。
pNum = 0x38 なので、num1 = *pNum です。pNumの指すアドレスの中身は 1(=num1)です。
具体的にメモリの配置をイメージする方が、多少は理解しやすいのではないかと思います。(何度も言いますが、動きを頭の中だけでトレースするのは大変なのでデバッガの利用がオススメです。)
違いですが、変数が値と1:1の関係であるのに対して、ポインタは1:nがあり得るところですかね。
プログラム中で利用する場合に変数の割り当て領域を覚えておくだけのものなので、別の変数にもなるワイルドカードみたいな扱いができます。
ちょっと違う視点で考えると、ポインタは「いろいろな種類の部品を取り付ける万能ジョイントの基本パーツ」です。型キャスト機能と併用すると異なるタイプの型も扱えるので、事実上なんでもポインタ経由で扱えるようになります。(それ故に闇の部分も濃いイメージが強いですが…)
その性質をどう利用するのか。という視点で見ると、いろいろ便利な実装が存在しますし、正直C言語にポインタがなかったら何ができるんだろう…というくらい、無いと幅が狭まってしまう機能です。
このあたりはC言語でいろいろプログラムを書いてみると有難味がわかってくるところだと思いますので、いっぱい実装を書くことが必要だと思います。
投稿2015/09/03 08:42
退会済みユーザー
総合スコア0
0
int *p はイント型ポインタです。
p = とすると p これに対して値を入れる、(アドレスが格納される)
*p = とすると *は覗き穴と覚えるとpの中身を見るてイメージですね。 *pは pの指すアドレスの中身です。
例文ですと
p = &x // p → x pはxを指す
print(*p) // は覗き穴だと考えてください p→x を指してるので p → x = 20 となっております
// pの中身は 覗き穴()p *p = 20
p → x
*p ||
↘ ||
20
図にするとこんな感じですね。
投稿2015/09/03 01:01
総合スコア1021
0
④変数pの値を出力する
printf("%d", *p);
よく見て下さい。本当に変数pの値を出力するなら、
printf("%d", p);
であるはずです。
ここでの*
は間接演算子で、
*p
と書けば、pの値(メモリ番地)に格納されている値を返します。
つまり④は
変数pが指す先の値(=*p)を出力する
です。
過去にも似たような質問があり、
ベストアンサーがとても分かりやすい説明だったので
参考にして下さい。
Cは紛らわしいことに*
の意味が3つあります。
1.乗算a * b;
2.ポインタ型の宣言int* x;
,int *x;
3.間接参照c = *p;
宣言ですが
int* x
と書けば、x
がintのポインタ型と言う意図を表わせ、
int *x
と書けば、*x
がint型と言う意図を表せます。
処理は一緒なので、しっくり来る方を使うといいです。
投稿2015/09/02 14:03
編集2015/09/02 15:10総合スコア13521
0
①でintへのポインタ型で変数pを定義する。
の文で「intへのポインタ型」が 「int*」で「変数」が「p」だと理解されているようですので、使い分ける時には
p : データが入っている入れ物を指す
*p : 入れ物の中に入っているデータを指す
とイメージしてみてはどうでしょうか。本来ならアドレスをからめて覚える方が正確に理解できると思いますが、とにかくイメージでもなんでも使い分けられるようにしていけば、だんだん理解できると思います。
ちなみに上記のイメージは私が仕事でC言語を最初に使ったときに先輩から教えてもらったものです。
投稿2015/09/02 12:00
編集2015/09/02 12:01総合スコア3041
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/09/02 23:37
2015/09/03 05:34 編集
2015/09/03 06:21
2015/09/03 09:14
2015/09/03 10:06
2015/09/03 11:25