C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。
short int *motion_data(void)
{
short int data1[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};
short int data2[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};
short int *po_data[2];
po_data[0] = data1[0];
po_data[1] = data2[0];
return *po_data;
}
No.6ベストアンサー
- 回答日時:
>元の配列の値を参照する方法を教えてください。
下のようにすると「元の配列の値を参照」できました。
(BorlandC++5.5.1)
No.3 さんの言われるように、
>関数を抜けると変数自体無くなってしまいます
「中身自体」は、その番地をいじくらない限り、「ずっと」残っていてくれればいいんだけど・・。
やっぱ、static かな。
#include <stdio.h>
short **motion_data( void )
{
short data1[ 5 ][ 7 ] = {
{ 100, 101, 102, 103, 104, 105, 106 },
{ 110, 111, 112, 113, 114, 115, 116 },
{ 120, 121, 122, 123, 124, 125, 126 },
{ 130, 131, 132, 133, 134, 135, 136 },
{ 140, 141, 142, 143, 144, 145, 146 }
};
short data2[ 5 ][ 7 ] = {
{ 200, 201, 202, 203, 204, 205, 206 },
{ 210, 211, 212, 213, 214, 215, 216 },
{ 220, 221, 222, 223, 224, 225, 226 },
{ 230, 231, 232, 233, 234, 235, 236 },
{ 240, 241, 242, 243, 244, 245, 246 }
};
short *po_data[ 2 ];
po_data[ 0 ] = &data1[ 0 ][ 0 ]; // もち = data1[ 0 ]; でも
po_data[ 1 ] = &data2[ 0 ][ 0 ];
return( &po_data[ 0 ] );
}
void main( void )
{
short **po_data, *p1, *p2;
po_data = motion_data();
p1 = po_data[ 0 ] + 13; // 任意の「元の配列の値を参照」
p2 = po_data[ 1 ] + 34; // 〃
printf( "%d\n", *p1 );
printf( "%d\n", *p2 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.7
- 回答日時:
厳密に言うと
「while (po_data < po_data+35)」
が無限ループになるとは限りません>#4. 関数 motion_data が返す値 (つまり最初の po_data の値) については「po_data」と「po_data+35」のどちらも有効なアドレス値であることが保証されますが, その後 po_data をインクリメントすると po_data+35 が元のオブジェクトから外れてしまうため, 有効なアドレス値ではなくなるとともに po_data と比較不能になります. したがってこの比較が未定義動作となりますから, 無限ループになるかもしれないしどこかで止まるかもしれません.
ついでにいうと static にする以外で逃げる方法は (本質的に) ありません>#6. そのプログラムは「たまたま」動いているだけだと思われます (printf の呼び出しで壊れても文句は言えない).
御指導ありがとうございます。
「while (po_data < po_data+35)」が暴走する理由が分り、またひとつ勉強になりました。
No.5
- 回答日時:
No.4に追記
>一つだけ
>>while(po_data < po_data + 35)
おそらくやりたいことを推測すると、参照処理自体間違いだけど、ここの「po_data + 35」が
>short int data1[5][7] = {
>short int data2[5][7] = {
>po_data[0] = data1[0];
>po_data[1] = data2[0];
に関連する、data2[]を参照することを考えているのなら大間違い。
変数を連続で定義したからと言って、必ずしも連続したメモリに割り当てられるとは限らない。
手元の環境いくつかで確認したら、メモリに連続して配置されているものはなかった。
No.4
- 回答日時:
No.1です。
>*po_pwm_s = *po_data;
>の一行を
>*po_pwm_s = **po_data;
>と書いてみたのですが、コンパイル時にエラーが出て上手くいきません。どうかご教授願います。
(以下略)
コンパイル通らないソース提示されてもどうしようもないんだけど……
とりあえず、コンパイルが通らないmain()と質問の関数見る限り、
ソースがどうこうという以前に、
short a;
short *p;
p = &a;
での、
・aの内容
・&aの内容
・pの内容
・*pの内容
がどういった値が入っているのかを理解する方が先だと思う。
質問文には、
>上手く参照できずに困っています。
No.1の返答で、
>質問に書いた*motion_data(void)の変数もstaticにしましたが上手くできませんでした。
とあるけど、何がうまくできないの? No.3氏の方法でNo.2氏が回答してる参照問題は解決してるよ。
それぞれの変数に入っている値をprintf()で出力するとかで確認してる?
一つだけ
>while(po_data < po_data + 35)
だと、無限ループで暴走する。
ご教授ありがとうございます。
質問・補足の表現が不適切で申し訳ありませんでした。
言い訳となってしまいますが、質問のコード内の変数にstaticが必要なのは、#3さんの御指摘で理解していたのですが、main()でポインタ先の参照がよく分らなかったのです。
御指摘の通りprintf()で出力を見ながら、ポインタについて再勉強してみます。
No.3
- 回答日時:
data1,data2,po_data共にauto変数なので、
関数を抜けると変数自体無くなってしまいます
ですから、以下のようにすれば大丈夫
static short int data1 ...略
static short int data2 ...略
static int* po_data[2]...略
このようにstaticを変数につければ、関数を抜けても存在します
No.1
- 回答日時:
>上手く参照できずに困っています。
とりあえず、*motion_data(void)を呼びタしているmain関数についてもすべて記述してください。
この回答への補足
*motion_data(void)を呼び出しているmain関数を記述します。
質問に書いた*motion_data(void)の変数もstaticにしましたが上手くできませんでした。ポインタのポインタ先を参照するのだからと
*po_pwm_s = *po_data;
の一行を
*po_pwm_s = **po_data;
と書いてみたのですが、コンパイル時にエラーが出て上手くいきません。どうかご教授願います。
void main(void)
{
short int *po_data;
po_data = motion_data();
while(po_data < po_data + 35)
{
*po_pwm_s = *po_data;
po_data++;
}
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSVでアップロードしたデータの...
-
Resource id #3 と表示されま...
-
csvの内容を行単位で削除したい
-
CSVファイルの最終行のデー...
-
C言語でCSVファイルの行数を読...
-
ヒアドキュメントの中のfor文
-
Call to a member function on ...
-
別ファイルの構造体の値を読み...
-
配列をファイルに書き込む方法
-
外部ファイルの出力
-
PHPでCSVの一部の行を編集したい
-
CSVの列上下で照合し、一致した...
-
PHPで地域名のみ変更(つづき)
-
readdirで文字化け
-
複数行のデータのPOST処理に関して
-
特定部分を書き換え、他は現状...
-
携帯絵文字の掲示板について
-
pythonのファイルの並びでの読...
-
String だと「 ByRef引数の型が...
-
file_existsでファイル名の部分...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Resource id #3 と表示されま...
-
別ファイルの構造体の値を読み...
-
CSVファイルの最終行のデー...
-
stdClass Objectを連想配列のよ...
-
複数行のデータのPOST処理に関して
-
CSVでアップロードしたデータの...
-
自動で番号を振りたい
-
C言語でCSVファイルの行数を読...
-
ヒアドキュメントの中のfor文
-
FortranのOPEN文
-
行数が30万件ほどあるCSVから、...
-
バイナリファイルの内容を、そ...
-
消費者物価指数
-
エラーメッセージ(無効な間接...
-
rubyで複数列のデータを一行に...
-
CSVデータの行数カウントをした...
-
csvの内容を行単位で削除したい
-
VBAでcsvファイルもシートもあ...
-
preg_splitがうまくいかないの...
-
文字列の文字一文字ずつを解析...
おすすめ情報