すいません。 似たような題も多かったのですが、初心者のため、わかりませんでした。
質問させてください。
ポインタのポインタを引数にもった関数を作りたいのですが、まったくわかりません。
(ポインタであれば、何とかできたのですが…)
例を作ってみました。下記で、dd[2][2]にtest2関数から値を得るとします。
?1と?2、?3に何を入れたらよいでしょうか?
(?1で得られる値は何でもかまいません。)
きわめて抽象的で、申し訳ないのですが、どうぞよろしくお願い致します。
void test2(double **d1)
{
?1
}
void C_testDlg::OnBnClickedButton1()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
double dd[2][2];
?2
test2(?3);
CString cs;
cs.format("%g", dd[1][2])
::AfxmessageBox(cs);
}
No.5
- 回答日時:
関数の実引数が2次元配列のときと、(1次元配列へのポインタの)1次元配列のときとで、仮引数のポインタが指すアドレスの使い方が違います。
いずれにせよ、ポインタを配列型にキャストすることはできませんので、個別の配列要素を参照するには、先頭要素からのオフセットを与えてやることになります
質問文の場合、実引数は2次元配列なので、仮引数のポインタの値は配列の先頭要素のアドレスです。
そこで、
?1
double *d2=(double*)d1;
for ( int i=0; i<2; i++ )
for ( int j=0; j<2; j++ )
*(d2+2*i+j)=1.0; // 2は、実引数配列の列の要素数
?2
何も書かなくてよい
?3
(double**)dd
私なら、このような場合、関数を
void test2( void* d1 ) {
double* d2=(double*)d1;
for ( int i=0; i<2; i++ )
for ( int j=0; j<2; j++ )
*(d2+2*i+j)=1.0; // 2は、実引数配列の列の要素数
}
とします。こうするとこの関数を引用するときは、キャストが不要になって、
test2(dd);
でよいことになります。
なお、実引数が(1次元配列へのポインタの)1次元配列のときは、仮引数d1をそのまま使って、
?1
for ( int i=0; i<2; i++ )
for ( int j=0; j<2; j++ )
*(*(d1+i)+j)=1.0;
とします。
この回答への補足
すいません。 いろいろ考えているうちに、説明を間違えていました。 今回の重要な部分は引数でして、
?3の test2(double **d1)が、変更できない部分でした。
ですので、?3のキャストができません。
これが主題で、後の部分は私がこうでないかと考えた部分です。
知りたいのは、test2の関数内です。
double dd[2][2]は相手方が、このような感じでデータを用意するのかな?と想像した部分です。
test2の関数内、またはdouble dd[2][2];をどうすればよいでしょうか?
説明が間違えており、本当に申し訳ありません。
どうぞよろしくお願い致します。
No.4ベストアンサー
- 回答日時:
これなんか違いがわかりやすいと思います。
「ポインタのポインタ」と「二次元配列」とは構造が違うので、dd[2][2]では無理です。
このddをあえて使うなら
double *ddp[2] ;
と「ポインタのポインタ」と対応している「ポインタの配列」を使って
ddp[0] = &(dd[0][0]) ;
ddp[1] = &(dd[1][0]) ;
ddp[2] = &(dd[2][0]) ;
test3(ddp) ;
とかですね。
この回答への補足
ありがとうございます。
下記で動作しました。
void test2(double **d1)
{
*d1[0]=1.1;
*d1[1]=1.2;
}
void Cpp_testDlg::OnBnClickedButton1()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
double dd[2][2];
double *ddp[2] ;
ddp[0] = &(dd[0][0]) ;
ddp[1] = &(dd[0][1]) ;
test2(ddp) ;
CString cs;
cs.Format("%g", dd[0][1]);
::AfxMessageBox(cs);
}
記載頂いたリンク先を見つけていたのですが、重要度がわかって
いませんでした。 2ページ目が重要かと見直しています。
ところで、
>「ポインタのポインタ」と「二次元配列」とは構造が違うので、dd[2][2]では無理です。
>このddをあえて使うなら
このddをあえて使わなかった場合、メインは、どのような形でデータを持つのが
自然でしょうか?
何度も申し訳ありません。 どうぞよろしくお願い致します。
解決しました。 kmeeさんのコードを流用させて頂いたので、ベストアンサーに
させて頂きます。
2次元配列にこだわっていたのは、実は**charが主題だったからです。
下記で解決しました。
皆様、本当にありがとうございました。
void test2(char **d1)
{
strcpy(d1[0], "ba0");
strcpy(d1[1], "ba1");
strcpy(d1[2], "ba2");
}
void Cpp_test1Dlg::OnBnClickedButton1()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
char *dd[100];
for(int i=0; i<100; i++)
{
dd[i]=new char[20];
}
test2(dd);
CString cs;
cs=dd[2];
::AfxMessageBox(cs);
for(int i=0; i<100; i++)
{
delete dd[i];
}
}
No.3
- 回答日時:
仮引数を変えられないなら, 「ポインタの配列」か「ポインタのポインタ」だね.
つまり
double d1[2][2];
とはできない.
この回答への補足
double d1[2][2];ではなく、メインをどのような形でデータを持つのが
よいでしょうか?
何度も申し訳ありません。 どうぞよろしくお願い致します
No.2
- 回答日時:
もちろん
void test2(double d[2][2])
でもいいですよ.
この回答への補足
すいません。 いろいろ考えているうちに、説明を間違えていました。 今回の重要な部分は引数でして、
?3の test2(double **d1)が、変更できない部分でした。
これが主題で、後の部分は私がこうでないかと考えた部分です。
知りたいのは、test2の関数内で、double dd[2][2]は
相手方が、このような感じでデータを用意するのかな?と想像した部分です。
test2の関数内をどうすればよいでしょうか? 説明が間違えており、申し訳ありません。
どうぞよろしくお願い致します。
No.1
- 回答日時:
?2 は、あなたのしたいように 変数dd を初期化してもらうとして、
問題は、関数 test2 の書き方です。
> void test2(double **d1)
という書き方では、2次元配列は上手く渡せません。
正しくは、
void test2(double (*d1)[2])
もしくは、
void test2(double d1[][2])
とする必要があります。
これさえ分かれば、例えば関数は次のように書けるはずです。
(サンプル)
void test2(double (*d1)[2])
{
d1[0][0] = 1;
d1[0][1] = 2;
d1[1][0] = 3;
d1[1][1] = 4;
}
また、?3 の呼び出しの部分も
test2(dd);
で行けるはずです。
なお、
> cs.format("%g", dd[1][2])
この文は、間違っています。
([2] では、dd の領域の外を指定しています)
この回答への補足
すいません。 いろいろ考えているうちに、説明を間違えていました。 今回の重要な部分は引数でして、
?3の test2(double **d1)が、変更できない部分でした。
これが主題で、後の部分は私がこうでないかと考えた部分です。
知りたいのは、test2の関数内です。
double dd[2][2]は相手方が、このような感じでデータを用意するのかな?と想像した部分です。
test2の関数内をどうすればよいでしょうか? 説明が間違えており、本当に申し訳ありません。
どうぞよろしくお願い致します。
お探しの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言語 ポインタ 配列 2 2022/06/02 17:29
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- C言語・C++・C# C言語 配列とポインタについて 2 2022/06/02 11:53
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
fopne で失敗する原因
-
メモリのアドレスからの値の取...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
エラーの意味
-
参照型で受け取った引数をポイ...
-
【VC++2005(CLR)】マルチスレッ...
-
TCHAR文字列内の検索について
-
セグメントエラー
-
ポインタのアドレス範囲
-
【なぜポインタを使うのか】
-
C言語のプログラムをJavaに...
-
ポインタ変数の利用方法
-
コンストラクタでnewを失敗した...
-
クイックソートの比較交換回数...
-
ポインタのミスでOS壊れるの...
-
デバイスハンドルとは?
-
#define NULL ((void *)0) の弊害
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
ExcelVBAでのkernel32(64bit)
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
ハンドルはポインタか
-
連結リスト 要素の入れ替え
-
C言語でのconstを返す関数
-
Cで作成したDLL関数をVBから呼...
-
NULLとブランクの違い
-
エラーの意味
-
ハンドル、アドレス、ポインタ...
-
DLL<->VB間での受け渡し(文字...
-
【C言語】戻り値が構造体の関数
おすすめ情報