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

すいません。 似たような題も多かったのですが、初心者のため、わかりませんでした。
質問させてください。 


ポインタのポインタを引数にもった関数を作りたいのですが、まったくわかりません。
(ポインタであれば、何とかできたのですが…)


例を作ってみました。下記で、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);
}

A 回答 (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];をどうすればよいでしょうか?
 説明が間違えており、本当に申し訳ありません。

どうぞよろしくお願い致します。

補足日時:2012/03/22 11:58
    • good
    • 0

http://news.mynavi.jp/articles/2008/04/18/pointe …
これなんか違いがわかりやすいと思います。

「ポインタのポインタ」と「二次元配列」とは構造が違うので、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をあえて使わなかった場合、メインは、どのような形でデータを持つのが
自然でしょうか? 

何度も申し訳ありません。 どうぞよろしくお願い致します。

補足日時:2012/03/22 10:07
    • good
    • 0
この回答へのお礼

解決しました。 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];
}

}

お礼日時:2012/03/23 11:24

仮引数を変えられないなら, 「ポインタの配列」か「ポインタのポインタ」だね.



つまり
double d1[2][2];
とはできない.

この回答への補足

double d1[2][2];ではなく、メインをどのような形でデータを持つのが
よいでしょうか?

何度も申し訳ありません。 どうぞよろしくお願い致します

補足日時:2012/03/22 10:10
    • good
    • 0

もちろん


void test2(double d[2][2])
でもいいですよ.

この回答への補足

すいません。 いろいろ考えているうちに、説明を間違えていました。 今回の重要な部分は引数でして、

?3の test2(double **d1)が、変更できない部分でした。

これが主題で、後の部分は私がこうでないかと考えた部分です。


知りたいのは、test2の関数内で、double dd[2][2]は
相手方が、このような感じでデータを用意するのかな?と想像した部分です。

test2の関数内をどうすればよいでしょうか? 説明が間違えており、申し訳ありません。

どうぞよろしくお願い致します。

補足日時:2012/03/22 00:14
    • good
    • 0

?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の関数内をどうすればよいでしょうか? 説明が間違えており、本当に申し訳ありません。

どうぞよろしくお願い致します。

補足日時:2012/03/22 00:16
    • good
    • 0

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