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

画像の問題なんですけど、
自分なりにソースコード書いたんですけど、なんかうまく行きません。
どなたか教えていただけますでしょうか?



#include <stdio.h>
#include <stdlib.h>

#define N 2
#define M 3


double **dmatrix(int nr1, int nr2, int nl1, int nl2) {

int i, nrow, ncol;
double **a;

nrow = nr2 - nr1 + 1; //行の数
ncol = nl2 - nl1 + 1; //列の数

//行の確保
if ((a = malloc(nrow*sizeof(double *))) == NULL) {
printf("メモリが確保できません(行列a)\n");
exit(1);
}
a = a - nl1; //行をずらす

//列の確保
for(i=nr1; i<=nr2; i++) a[i] = malloc(ncol*sizeof(double));
for(i=nr1; i<=nr2; i++) a[i] =a[i] - nl1; //列をずらす

/*呼び出す際、dmatrix(0,M-1,0,N-1)だとC言語の添字と一致
dmatrix(1,N,1,M)だと添字が1から始まる*/
return (a);
}

void free_dmatrix(double **a, int nr1, int nr2, int nl1, int nl2){
int i;

/*メモリの解放*/
for(i=nr1; i<=nr2; i++) {
free((void*)(a[i]+nl1));
free((void*)(a+nr1));
}
}

double add(double x[][M], double y[][M]) {

double sum[N][M];
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
sum[i][j]= x[i][j] + y[i][j];
}
}

return **sum;
}


int main() {

double **a = dmatrix(1, N, 1, M);
double **b = dmatrix(1, N, 1, M);
double **c = dmatrix(1, N, 1, M);
double **d = dmatrix(1, N, 1, M);
double **sum = dmatrix(1, N, 1, M);
int i, j;

//行列aの要素
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
scanf("%lf",&a[i][j]);
}
}
//行列bの要素
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
scanf("%lf",&b[i][j]);
}
}

//行列cの要素
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
scanf("%lf",&c[i][j]);
}
}
//行列dの要素
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
scanf("%lf",&d[i][j]);
}
}

**sum = add(a,**b);



/*for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
printf("%.0f ",a[i][j]);
}
printf("\n");
}*/

return 0;
}

「画像の問題なんですけど、 自分なりにソー」の質問画像

A 回答 (6件)

「なんかうまく行きません」って, 具体的には何がどうなることをそう呼んでいる?



まあいろいろと明らかにおかしいし, このプログラムでは目に見えないけど論理的にはおかしいところもあるけど.
    • good
    • 0

dmatrixの返すのはポインタの配列で


多次元配列じゃ無い。しかも行と列の添字の範囲を
0オリジン以外に変えられる工夫が入ってる。

だから、addが返す行列もdmatrixで作らないといけないのに
あっさり無視してるし
それをdmatrixが作った行列であるかのようにアクセスしてる。

これでは動くわけがないです。
    • good
    • 0

突っ込みどころが多すぎて全てを指摘することができない。



あえて二つ指摘しておく。

1.ポインタと配列の違いが全く分かっていない。
main()関数の中でa[i][j]というものが出てくる。
aの宣言ではdouble **a;と宣言している。
aはポインタのポインタであって配列ではない。
たとえaが示す先がNxMの2次元配列であろうとコンパイラはそのようには解釈しない。a[i][j]としてもそれがどこをさすのかわからない。
a[i][j]を使いたいのであれば
double a[N][M];
と宣言しないといけない。

重要なことだから重ねて言うと
double **a;
と宣言してaにNxMの大きさの配列の先頭アドレスを代入してもコンパイラはaがNxMの配列とは見なさい、ということである。
そのためa[i][j]としてもコンパイラはそのアドレスを特定することができない。配列でNxMの配列であればi*M+j+1番目のアドレスであるとみなせるが、aはただのポインタのポインタにすぎないためNやMと結び付けられないのだ。

2.add()関数の戻り値
add()関数の戻り値は単なるdouble型の値です。
return **sum;
とすればsumが示す配列の値全てが戻されるとでも思っているのですか?
上の文で戻ってくる値はsum[0][0]の値だけですよ。
    • good
    • 0

いや、double **a を a[i][j] とアクセスするのは


待ったく問題ないのですよ。 → No.3

add の正しい実装

double add(double **x, double **y) {

double ** sum = dmatrix(1, N, 1, M);
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++){
sum[i][j]= x[i][j] + y[i][j];
}
}

return sum;
}
    • good
    • 0

add の返す型を double としているのに, (double ** である) sum を返すのは「正しい」とはいいにくい気がします>#4.



本気でやるなら add に「大きさ」も渡さないとダメだと思うんだよね. そして, それが「違う」ときにどうするのかとか, いろいろ頭痛のいたい問題を解決する必要もある, と.

あとこの dmatrix はおそらく移植性に問題がある. つまり「どんな環境でも必ず (思った通りに) 動作する」とはいいきれないはず.
    • good
    • 0

No.4です。



>double add(double **x, double **y) {

訂正。直し忘れました。返すのは行列なので
double** add(double **x, double **y) {
    • good
    • 0

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