アプリ版:「スタンプのみでお礼する」機能のリリースについて

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;
}

A 回答 (7件)

>元の配列の値を参照する方法を教えてください。



 下のようにすると「元の配列の値を参照」できました。
  (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 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 0
この回答へのお礼

御指導ありがとうございます。ポインタ配列のポインタが配列表現できることは初めて知ったので勉強になりました。

お礼日時:2008/12/11 12:22

厳密に言うと


「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 の呼び出しで壊れても文句は言えない).
    • good
    • 0
この回答へのお礼

御指導ありがとうございます。
「while (po_data < po_data+35)」が暴走する理由が分り、またひとつ勉強になりました。

お礼日時:2008/12/11 12:18

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[]を参照することを考えているのなら大間違い。
変数を連続で定義したからと言って、必ずしも連続したメモリに割り当てられるとは限らない。
手元の環境いくつかで確認したら、メモリに連続して配置されているものはなかった。
    • good
    • 0

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)
だと、無限ループで暴走する。
    • good
    • 0
この回答へのお礼

ご教授ありがとうございます。
質問・補足の表現が不適切で申し訳ありませんでした。
言い訳となってしまいますが、質問のコード内の変数にstaticが必要なのは、#3さんの御指摘で理解していたのですが、main()でポインタ先の参照がよく分らなかったのです。
御指摘の通りprintf()で出力を見ながら、ポインタについて再勉強してみます。

お礼日時:2008/12/11 12:35

data1,data2,po_data共にauto変数なので、


関数を抜けると変数自体無くなってしまいます

ですから、以下のようにすれば大丈夫
static short int data1 ...略
static short int data2 ...略
static int* po_data[2]...略

このようにstaticを変数につければ、関数を抜けても存在します
    • good
    • 0

そりゃダメだろ.


int *foo(void)
{
int x = 4;
return &x;
}
がダメなのと同レベル.
    • good
    • 0

>上手く参照できずに困っています。


とりあえず、*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++;
}
}

補足日時:2008/12/10 08:08
    • good
    • 0

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