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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語 配列とポインタについて 2 2022/06/02 11:53
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TOEFLでadhdすぎて
-
mallocについて
-
あなたは、Excelはどうやって学...
-
ArduinoでMouse関数を使用して...
-
プログラミングについての質問...
-
VisualStudio2022でC言語プログ...
-
C# でソフト開発をした事のある...
-
c言語の問題の説明、各所ごとに
-
プログラムが書けません。
-
C言語をコンパイルするとコンピ...
-
Notepad++の関数リスト表示の変...
-
Linuxでの開発環境構築や設定の...
-
QT(C++)の学習方法について
-
関数ポインタの高速化のメリット
-
ArduinoのジャイロモジュールMP...
-
こんなことてしますか??
-
Stuck
-
gccを行ってもexeファイルが生...
-
c言語
-
License='MIT' ってなんでmitな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数行のデータのPOST処理に関して
-
Resource id #3 と表示されま...
-
別ファイルの構造体の値を読み...
-
PHPでCSVの一部の行を編集したい
-
バイナリファイルの内容を、そ...
-
CSVファイルの最終行のデー...
-
ヒアドキュメントの中のfor文
-
stdClass Objectを連想配列のよ...
-
◆速い、ファイル読み込みは?
-
C言語でCSVファイルの行数を読...
-
phpでCSVファイルの中身を多次...
-
rubyで複数列のデータを一行に...
-
多次元配列の一次元目の最大値...
-
行数が30万件ほどあるCSVから、...
-
配列同士の足し算のループ処理
-
csvの内容を行単位で削除したい
-
FortranのOPEN文
-
CSVデータの行数カウントをした...
-
自動で番号を振りたい
-
While文を使って配列の中身を全...
おすすめ情報