int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答の考え方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
パクパク
記事: 23
登録日時: 12年前

int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答の考え方

#1

投稿記事 by パクパク » 12年前

いつも回答して頂き、ありがとうございます。

コード:

int count[100][10];
count[44][8] = 99;
上記のコードをポインタ演算を使って書き直すという問題があるのですが、正答が下記でした。

コード:

*((int *)count +(44 * 10) + 8) = 99;
この場合の読み方、考え方の順番をご教示頂けないでしょうか。お願い致します。

<疑問点>
1.最もわからないのが(int *)のアスタリスクを消去するとエラーが、 *のオペランド(演算対象?)はポインターはである必要があります、という点。
2.最前部のアスタリスク
3.

コード:

int *count[100][10];
は必要なのか、という点

non
記事: 1097
登録日時: 14年前

Re: int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答

#2

投稿記事 by non » 12年前

コード:

	int count[100][10];
	count[44][8]=99;					// 1
	*(&count[0][0] +(44 * 10) + 8) = 99;// 2
	*((int *)count +(44 * 10) + 8) = 99;// 3
	int (*b)[10];
	b=count;							// 4
	*((int *)b +(44 * 10) + 7) = 98;
2の行で、&count[0][0]が配列の先頭アドレスを示すことはおわかりですよね。ですから、指定場所の配列に格納
するのは、配列のアドレスを計算し、そのアドレスが指している(ポイントしている)場所に格納するので、一番
先頭に*が必要なのはわかると思います。
それでは、3の行でcountとだけ書くと何かということ。&count[0][0]と同じ値を示すことは、ご存じだと思いますが、
実は中身は同じアドレスでも型が違います。4の代入ができるように、countは配列へのポインタです。
ですから、一次元配列として計算させるために、(int *)でキャストしなくてはいけません。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答

#3

投稿記事 by softya(ソフト屋) » 12年前

多次元配列の場合は、int array[a];と定義された場合においてintがb個並んだものが更にa個あると考えます。
int array[a][c];ならintがc個並んだものが更にb個あり、その塊がさらにa個あると考えるわけです。
計算式はこう考えれば意味がわかると思います。

さて疑問点ですが、

1. countの型はint [][]ですから演算可能なポインタと見なせないのでポインタ演算できません。int [];の型なら出来るんですけどね。
それを強引にint*にキャストして演算しています。

2.ポインタの指すメモリに代入するためです。

3.は意味がわかりませんが、
int *count[100][10];
は10 x 100個のint型ポインタを定義することになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

パクパク
記事: 23
登録日時: 12年前

Re: int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答

#4

投稿記事 by パクパク » 12年前

お二方、返信ありがとうございます。
softya(ソフト屋) さんが書きました:それを強引にint*にキャストして演算しています。
non さんが書きました:実は中身は同じアドレスでも型が違います。4の代入ができるように、countは配列へのポインタです。
ですから、一次元配列として計算させるために、(int *)でキャストしなくてはいけません。
型キャストは勉強したのですが、すっかり(使用すると言う選択肢も含めて)抜け落ちていました。
ありがとうございました。

かずま

Re: int count[100][10]; count[44][8] = 99;をポインタ配列で書き直した場合の正答

#5

投稿記事 by かずま » 12年前

パクパク さんが書きました:

コード:

int count[100][10];
count[44][8] = 99;
上記のコードをポインタ演算を使って書き直すという問題があるのですが、正答が下記でした。

コード:

*((int *)count +(44 * 10) + 8) = 99;
私なら

コード:

*(*(count + 44) + 8) = 99;
を正答にしたいですね。

countの型は int [100][10]ですが、これは演算可能な
ポインタ int (*)[10] と見なせるのでポインタ演算できます。
(count + 44) というポインタ演算の結果、これは count[44] を
指すポインタとなります。
*(count + 44) は count[44] そのもの 、すなわち
count[44][0]~count[44][9] 全体を塊としてみたもの(配列)になります。
count[44] は、int [10] という配列ですが、これは int * とみなせるので
ポインタ演算できます。
count[44] すなわち *(count + 44) は count[44][0] を指すポインタです。
*(count + 44) + 8 は count[44][8] を指すポインタです。
*(*(count + 44) + 8) は、count[44][8] そのものです。

閉鎖

“C言語何でも質問掲示板” へ戻る