プロが教えるわが家の防犯対策術!

C言語プログラミング
ポインタと関数についてよくわかりません。

void func(int *pvalue);
int main(void)
{
int value = 10;
printf("&value = %p\n",&value); func(&value); /* アドレスを渡す */ printf("value = %d\n",value);
return 0;
}
void func(int *pvalue)
{
printf("pvalue = %p\n",pvalue);
*pvalue = 100; /* 通常変数モードに切り替えて代入 */

return;
}
まずfunc関数にvalueのアドレスを送り
int *pvalueで受けとります。
ここでの*pvalueは数字ですか?アドレスですか?
func関数ないの(printf)pvalueはアドレスですか?数字ですか?
%pを%dに変えたら値が入るのでしょうか?

%pについてもわからなくなってしまいました。
最期の*pvalueは変数という見方でしょうか?

頭がこんがらがって来ました。
教えてください。(見分け方笑)

A 回答 (3件)

> ここでの*pvalueは数字ですか?アドレスですか?



呼び出し側は&valueと変数valueのアドレスを渡しています。
したがって受ける側のpvalueで受け取るのはmail関数内で定義される変数valueのアドレスです。
ただし、アドレスも数値と言えば数値です。動作しているプログラム空間内の位置を示す値ですから。


> func関数ないの(printf)pvalueはアドレスですか?数字ですか?

一度受け取った変数の内容は代入を粉わない限り変化しません。
よって受け取った値のままで、それはmail関数内で定義される変数valueのアドレスです。


> %pを%dに変えたら値が入るのでしょうか?

それは値が入るかどうかではなく%pや%dの意味するところは何か・・・ということです。


> 最期の*pvalueは変数という見方でしょうか?

mail関数内で定義される変数valueに値をセットしています。
参考まで。
    • good
    • 1

ポインタの導入部分はかなりデリケート...


理解してもらえるように書けるかは自信はありませんが頑張ってみます

>ここでの*pvalueは数字ですか?アドレスですか?
まず根本的な部分から説明します
ポインタ変数というのはアドレスを記憶するための変数です。
それ以上でも、それ以下でもありません
渡されたアドレスを記憶するもの、それをしっかりと理解してください

ポインタの宣言方法は
int *pvalue;
とこのように書きますね
個人的にはこの時点で誤解を招くと思っています

実はアスタリスクの位置は
int* pvalue;
とこのように書いても問題ありません
私はこちらの書き方が好きです。
「int型のポインタ変数」の「pvalue」を宣言します
というのが分かりやすいと思います

void func(int *pvalue)
というのはfunc関数で使用する「pvalue」という「int型のポインタ変数(仮引数)」を定義しています
ということで、数字かアドレスかと言われれば、アドレスですということになります。
なぜかというと最初に言ったとおり、ポインタ変数はアドレスを記憶するための変数です
それ以外のものは入れることができません

>func関数ないの(printf)pvalueはアドレスですか?数字ですか?
つまり、この答えも1つです。
アドレスです。ポインタ変数はアドレs(ry

しかし
*pvalue = 100;
という記述がありますね
「は?数字も入れられるじゃねえか!殺すぞ!」
という声が聞こえてきます。殺さないで

この式はpvalueに100を入れているワケじゃありません
pvalueの頭に*がついていますね
これはポインタ変数の宣言の時に使った*とは別物なんです
宣言のときの*はポインタ変数を宣言しますよという印みたいなものです

*pvalue = 100のときの*は「間接参照演算子」と呼ばれるものです
意味としてはポインタが指し示すアドレスにアクセスを行うものだと思ってください
pvalueには関数を宣言する際にvalueのアドレスを渡していますよね
value「これ、僕が居る場所ね」→pvalue「おっけー☆」
見たいな感じで居場所を教えてあげています、これがアドレス
pvalue君はvalue君の居場所を覚えている状態です

で、この「間接参照演算子」というのを使うと
pvalue君が覚えている場所に直接ワープできるものだと思ってください
*pvalue = 100とやればvalue君に直接100を渡すことができるし
x = *pvalueとやればvalue君から直接教えてもらうこともできます


長くなりましたが、とりあえずここまで書きました
多分、あまり分かりやすくかけていないので
分からないことが有りましたら補足などで教えてください....
    • good
    • 1
この回答へのお礼

いえいえ
とてもわかりやすかったです!!
ポインタって結構初心者が躓きやすい場所と聞きました。
もし他にも注意点、躓きポイントがあったら教えてもらえると嬉しいです。(漠然としててスイマセン)

お礼日時:2018/12/28 00:01

>もし他にも注意点、躓きポイントがあったら教えてもらえると嬉しいです


難しいですね
結局ポインタの感覚を理解できるかどうかの問題なので
確かにポインタはつまずきやすいのですが
ここがつまずくよ!!というのは個人的にはないんじゃないかなと思ってます

何でポインタが難しいかって
いきなりアドレスの概念が出てくるからだと思います
正直C言語を学ぶ上で最初にやるであろう、変数についての部分から
アドレスについて言及すれば大分違うと思うのですよね

先の回答で
int *pvalueは分かりにくい!
int* pvalueの方が好きだ!と言いましたが
実はint *pvalueと書くのにもちゃんと理由がありまして

int* a, b;
とこのように書きますとintのポインタ変数が2つ宣言されているように見えますが
実はbの方はただのint型です。
一行で2つのポインタ変数を宣言したい場合
int *a, *b;
と書く必要があります。
それを踏まえると変数名の方に*をつけるのもありっちゃありなんです
もはやC言語のポインタ構文は分かりづらいので、存在そのものがややこしいのです

まぁ、一行で複数の変数を宣言するかどうかは
軽く論争が起きそうな話題ではありますけど
私は好きではないので一行に1つの変数宣言をするようにしています

http://pg-kura.hatenablog.com/entry/20120611/133 …
個人的にはここの説明がとても分かりやすいのでおすすめです
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!