Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
  • ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ポインタの初歩でお聞きしたいです。)

ポインタの初歩で学びたい!関数で戻り値を複数返す方法とは?

このQ&Aのポイント
  • ポインタを使った変数のアドレス代入や値の代入について説明してくれませんか?
  • 関数で戻り値を1つしか返せないため、複数の値を返す方法について勉強中です。
  • ポインタはデスクトップのショートカットアイコンのようなもので、使い方がわかりにくいと感じています。

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

じゃあ、仮想的にアドレスを割り振って考えて見ましょう。 int year,month,week,days; はこうなります。 0x1000 year[不定] 0x1004 month[不定] 0x1008 week[不定] 0x100C days[不定] 並びは、アドレス 変数名[値]です。 あくまで仮想アドレスですので実際には違いますよ。 初期値は不定ですが困るので仮に値を入れておきましょう。 year = 2000; mouth = 1; これで 0x1000 year[2000] 0x1004 month[1] となりました。 で、関数呼び出しです。 getYearMonth(&year,&month); &year,&monthで変数のアドレスである0x1000と0x1004がgetYearMonth関数に渡されます。 じゃあ関数側です。 getYearMonth(int *py,int *pm) int *py,int *pmで変数が宣言されて呼び元からの値が入ります。 0x2000 py[0x1000] 0x2004 pm[0x1004] となります。 で scanf("%d %d",py,pm); ですが、pyの中身の0x1000、pmの中身の0x1004がscanf関数に渡されます。 すると scanf("%d %d",&year,&month); の場合、&yearだとyearのアドレス0x1000ですからpyと同じですね。monthも同様です。 整理すると式中の&は変数のアドレスを意味します。&yaerは変数のアドレス0x1000です。 式中の*はアドレスの指す変数そのものですので、*pyは変数そのものです。この例でscanf直前の状態だと2000と言う値です。 宣言中の*はポインタ変数であることを宣言します。int *py;など。

ForceFeed
質問者

補足

>int *py,int *pmで変数が宣言されて呼び元からの値が入ります。 >0x2000 ←ここの所 py[0x1000] >0x2004←ここの所  pm[0x1004] *pyも*pmもyearやmonthの宣言と同じように、アドレスを入れる箱が作られて'*'がなくなるとpy,pmがyearとmonthのアドレスにかわるんですね。

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

まず第一に「scanfにはポインタ(アドレス)を渡す」ってのが1つ。 例えば int main() { int year,month,week,days;       : scanf("%d %d",&year,&month); ←scanfにはポインタ(アドレス)を渡す       : return 0; } って書かないといけないって事は理解出来てるよね? んじゃ int main() { int year,month,week,days; int *py,*pm; py = &year; pm = &month       : scanf("%d %d",py,pm); ←scanfにはポインタ(アドレス)を渡す       : return 0; } は? 『「py」と「&year」は同じもの』だよね?代入してんだから同じじゃなきゃ困る。 だったら「py」って書く代わりに「&year」って書いても同じ。それに従って書き替えたら int main() { int year,month,week,days; int *py,*pm; py = &year; pm = &month       : scanf("%d %d",&year,&month); ←scanfにはポインタ(アドレス)を渡す       : return 0; } って感じで、最初のに戻ってしまう。 ここまでは判ってると思う。 んじゃ、scanfに無理矢理に「&」を付けた引数を書いたらどうなるだろう? 『「*py」と「year」は同じ物』って事は判ると思う。 『「*py」と「year」は同じ物』なら、両方に「&」を付けても同じ物のはずだから『「&*py」と「&year」は同じ物』になる。 つまり scanf("%d %d",&year,&month); ←scanfにはポインタ(アドレス)を渡す って書く代わりに scanf("%d %d",&*py,&*pm); ←scanfにはポインタ(アドレス)を渡す って書ける事になる。 なので scanf("%d %d",py,pm); ←scanfにはポインタ(アドレス)を渡す scanf("%d %d",&year,&month); ←scanfにはポインタ(アドレス)を渡す scanf("%d %d",&*py,&*pm); ←scanfにはポインタ(アドレス)を渡す は、全部同じ事をするって事。 つまり >scanf("%d %d",py,pm); //*ここがちょっとわからないところです* って書いてあるのは ≫scanf("%d %d",&*py,&*pm); //*ここがちょっとわからないところです* って書いてあるのと同じな訳。 とゆわけで ≫scanf("%d %d",&(*py),&(*pm)); //*ここがちょっとわからないところです* ≫if((*pm>=1)&&(*pm<=12)){ //1から12月まででそれ以外の数字なら の「*py」を「♪」に、「*pm」を「△」に置き換えれば ≫scanf("%d %d",&♪,&△); //*ここがちょっとわからないところです* ≫if((△>=1)&&(△<=12)){ //1から12月まででそれ以外の数字なら になる。これを「♪」を「year」に、「△」を「month」に置き換え直すと ≫scanf("%d %d",&year,&month); //*ここがちょっとわからないところです* ≫if((month>=1)&&(month<=12)){ //1から12月まででそれ以外の数字なら に戻る。これだと「いつもの見慣れたパターン」だよね?scanfに「&」ちゃんと付けて呼んでる形になったよね。 「&の有る無し」「*の有る無し」で悩んだら『「*pm」を「♪」に置き換える』みたいに「単純化」してみると良い。 以下、まとめ。 重要なのは 「*は、ポインタ変数の中身」 と 「&は、何かのポインタ」 の2つ。 例えれば 「*は『箱の中身』」 と 「&は『中身の箱』」 って感じ。 なので「py」を「箱」と考えれば「&*py」は「【箱の中身】の箱」なので、結局は「単なる箱」って事だから「py」とだけ書いたのと同じになる。 つまり「py」イコール「&*py」って事。 &と*は「互いに、逆の事をする」ので「&*ほげほげ」って感じで2つ繋げると「ほげほげ」だけ、になっちゃう。 あとは「関数の引数にした時はどうなるのか?」だけど、これも『「♪」に置き換え式』で考えればOK。

ForceFeed
質問者

お礼

遅ればせながらでわありますが、その節はありがとうございました。 おかげで、ポインタは自分なりに消化できるようになりました。

ForceFeed
質問者

補足

お二人の説明でscanf()関数で普通の変数に'&'を入れるところが、ポインタ変数の場合はなぜ'&'無しなのか、よくわかりました。 「*は『箱の中身』」と「&は『中身の箱』」はイメージとして わかりやすかったです。

すると、全ての回答が全文表示されます。

関連するQ&A