質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

800閲覧

「値を格納する領域」と「ポインタを格納する領域」の区別

Egg-Man

総合スコア38

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/11/05 14:45

編集2021/11/05 14:55

###mallocで領域確保した際、実際メモリ上ではどのような状態になっているのか曖昧です

typedef struct box { int num; struct box*array[5]; }BOX; BOX*data = (BOX*)malloc(sizeof(BOX)); for(int i = 0; i<5; ++i) { data->array[ i ] = (BOX*)malloc(sizeof(BOX)*3); }

この時、
data->array[n][m](n = 0〜4, m = 0〜2)
のように2次元配列の座標として扱えるのか、もしくは
data->array[n]->array[m](n=0〜4、m=0〜2)
のように、ポインタのポインタとして扱えるのかどうか....

###試してみたこと

BOX value; BOX*pointer; //↑の2つを用意して、 data->array[n][m] = value; //① data->array[n]->array[m] = pointer; //② //(n,mはそれぞれ0〜4、0〜2までの任意の数字) //このように2つの場合を想定して、①には値を、②にはポインタを代入してみた

上記の①と②を実行すると、何のエラーもなく正常に動きました。
ただ、それだとdata->arrayは①,②の両方を実現できてしまっているという事になります。
しかし実際のところ、どちらか一方が正しく、もう一方は間違った認識だと思うのですが、どうなのでしょうか(^_^*)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/11/05 15:25

>上記の①と②を実行すると、何のエラーもなく正常に動きました。 それで、そのコードによって具体的にどの様な結果になると予想され、実際にどの様になったのでしょうか。
Egg-Man

2021/11/05 16:15

先述のサイトを拝見させて頂きました。 「配列へのポインタ」と 「ポインタへの配列」とでは、意味が異なるんですね。(°_°) 初知りです(驚) > それで、そのコードによって具体的にどの様な結果になると予想され、実際にどの様になったのでしょうか。 個人的には①が正しいと思っており、②のような data->array[n]->array[m] という、ポインタ先のポインタの領域は存在していない(確保していない)ため、②に関してエラーメッセージがあると予想してました。
jimbe

2021/11/05 16:41

予想と異なり、どう動作したのでしょう。 各変数の値を全て表示するようにして、1 をした場合と 2 をした場合でそれぞれどうなってどう違ったのかを確認する等はしていないのでしょうか。 予想して結果が違ったとそこで手を止めるのではなく、なぜ違うのか、コードとしてどの部分が予想と違う為に結果が違うのかを追ってみては如何でしょう。 想像・予想し、実験・確認して、コード(あるいは考え方、または両方)を直す。 これは単に勉強のためだけでなく、実際に動作するプログラムを作る際のデバッグの作業と同じです。
Egg-Man

2021/11/05 17:09 編集

ご指摘ありがとうございます。 当問題については無事、解決致しましたm(__)m ちなみに、僕が実際に確認した方法としては、mallocでメモリ領域を確保した場合、同じ行番号の列要素のアドレス値は連続的になっているはずなので、①,②どちらかが正しくない認識であれば、正しくない方のアドレス値は連続的になっていないと考え、実際にアドレス値を出力し、比較してみました。 結果は、どちらも行インデックス別の列要素が連続的にメモリ確保されていたので、①,②は共に存在している領域であったことに至りました。
jimbe

2021/11/06 03:45

解決おめでとうございます。 >僕が実際に確認した方法としては、~ そのコードと結果、並びに考察をご質問に書いて頂けると、例えば注目すべき変数・表示の仕方、その読み方が違うなどを確認出来ます。 上で「具体的に」と書きましたのはその意味ででした。
guest

回答1

0

ベストアンサー

C

1int Buffer[100]; //※何らかの領域 2 3//なんかポインタがあって,どこかを指しているとして 4int *p = Buffer; 5 6//この2つは同じ意味.Buffer[5]に100を代入するであろう. 7p[5] = 100; 8*(p+5) = 100;

まずこれは大丈夫かな?

で,あなたが書いているコードにも [n] とか [m] とかがあるので,同じように考えてみればいい.

  • data->array[n] の型はなんであろうか?
  • そこにさらに [m] を書いて data->array[n][m] としたら,それはどこなのだろうか?

[追記]
絵を描いた.

  • 赤い○はポインタ(box* 型).そこから伸びる矢印は指し示し具合を示す.
  • 黒い四角は box 型

を示す.
n=1, m=2 のとき,

  • data->array[n][m] とは,緑で塗った box 型のこと
  • data->array[n]->array[m] とは,紫で塗ったポインタのこと

イメージ説明

投稿2021/11/05 15:31

編集2021/11/05 16:13
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/11/05 15:39

> p+5 これは,「ポインタpが指す場所よりも,int型5つ分の大きさだけ先の場所」を指す.(言葉がいまいちだなー) > data->array[n][m] は,*( data->array[n] + m ) であり, この()の中身は,「ポインタ data->array[n] が指す場所よりも,box型m個分の大きさだけ先の場所」を指す.
fana

2021/11/05 15:41

> data->array[n]->array[m] こっちの記述は全く別だ. 「ポインタ data->array[n] が指す先に box 型の奴がいるとして,そいつのメンバ変数である配列 array のm番目の要素」だ.
Egg-Man

2021/11/05 15:42

> まずこれは大丈夫かな? はい。 あまりこのような書き方は普段しないのですが、一応理解はしてます。 > data->array[n][m] としたら,それはどこなのだろうか? ポインタ配列の要素array[n]が示す先に、array[n][m]というデータ(値)が存在する.... との認識で正しいでしょうか?(^◇^;)
fana

2021/11/05 15:43

記述①と記述②とでは,全く違う場所をいじくっている.
fana

2021/11/05 15:56 編集

int a[5]; を,あえて「int型5個」と言い表すならば… 「box型はメンバ変数として box*型を5個 持っている」と言うことになるね. で,ポインタ data が指す先にあるbox型が持っているそれら5個のポインタは それぞれが,box型が3個並んでいる場所(の先頭) を指し示している. そしたら, > data->array[n][m] とはどこだろうか? 具体的に n=1, m=2 とかで考えてみよう. すなわち data->array[1][2] だ. data->array[1] は前述の通り,box型が3個並んでいる場所(の先頭) を指し示しているポインタだ. data->array[1][2] は,*(data->array[1]+2) であり,これは 【「ポインタ data->array[1] が指す場所よりも,box型2個分の大きさだけ先の場所」にあるbox型】という意味だ.つまり3個並んでるbox型の末尾のやつだ.
Egg-Man

2021/11/05 15:53

> 記述①と記述②とでは,全く違う場所をいじくっている そうです。 しかし、質問の主意は for(int i = 0; i<5; ++i) { data->array[ i ] = (BOX*)malloc(sizeof(BOX)*3); } を実行すると、それは ①と②のどちらを示しているのかを知りたくて(^_^*)
fana

2021/11/05 16:15 編集

億劫がらずに絵でも描いてみたら? (追記で絵を載せた)
Egg-Man

2021/11/05 16:32

> 億劫がらずに絵でも描いてみたら? すいません、自分 今スマホからの操作で画像を挿入できません(>_<) > (追記で絵を載せた) なるほどですっ!!(*゚▽゚*) 凄く意味が理解できました(驚) 僕はてっきり、同絵で言うと data->array[n]->の先にあるのは、黒い四角のbox型が1つだけだと勘違いしてましたw 構造体なので、黒い四角のbox型はn個それぞれにおいてm個あるんですね( ゚д゚) 腑に落ちました。 有難う御座います!!!
fana

2021/11/06 02:17

> すいません、自分 今スマホからの操作で画像を挿入できません(>_<) 他者に絵を示せと言っているのではなくて, 手元でこういう絵を描いてみるなどすれば把握しやすいんじゃないの?っていう話.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問