[C言語]行列の掛け算を行う関数[コード付き]

今回は行列の掛け算を実装します。
毎度毎度掛け算のコードを書くのがだるいなあと思って関数化してみました。
一番下に全体のコードもあるので参考にどうぞ



コードの実装

とりあえず行列についてですね。
行列は2次元配列に格納して表現します
(ex 2×3行列なら、int G[2][3]で定義する)

それを関数に渡して計算って感じで行くことにします



計算の関数

行列の掛け算のやり方については省略です。
わからんければググってください。
まあ簡単なイメージ図は

まあfor文を3重にして書こうかなって感じですね。
共通する部分(上の図ならy)のループが一番内側に来るようにすれば良いですね。

void multi(int x, int y, int z, int A[x][y], int B[y][z], int C[x][z]){
    
    for(int i=0; i<x; i++){
        for(int j=0; j<z; j++){
            for(int k=0; k<y; k++){
                C[i][j] += (A[i][k] + B[k][j]);
            }
        }
    }
}

仮引数はそれぞれの添字と計算する2つの行列が格納されている配列、
そして計算結果の行列を格納する配列です

ループの中は見ての通り
配列の添字を間違えないように気を付けました。


行列を配列に格納する関数

void cre(int x, int y, int A[x][y]){
    int s;
    
    for(int i=0; i<x; i++){
        for(int j=0; j<y; j++){
            printf("%d行%d列の要素を入力してください:,",i+1,j+1);
            scanf("%d",&s);
            
            A[i][j] = s;
        }
    }
}

配列とその行数、列数を受け取って要素を入力させる関数です。
わかりやすいようにprintfではi+1,j+1としました。


配列の中身をすべて0にする関数

計算を行う関数のforループの内側では

C[i][j] += (A[i][k] + B[k][j]);

このように結果を格納する配列にどんどん足していってます。
なのでC[i][j]は0でないといけません(つまり要素がすべて0)
そもそも何も要素を入れないと不定値のままなので計算がおかしくなりますね。

よって要素をすべて0にする関数を作ります。

void cre_0(int x, int y, int A[x][y]){
    for(int i=0; i<x; i++){
          for(int j=0; j<x; j++){
              A[i][j] = 0;
          }
      }
}

見てのとおりですね。



全体のコード

#include <stdio.h>

void multi(int x, int y, int z, int A[x][y], int B[y][z], int C[x][z]){
    
    for(int i=0; i<x; i++){
        for(int j=0; j<z; j++){
            for(int k=0; k<y; k++){
                C[i][j] += (A[i][k] + B[k][j]);
            }
        }
    }
}

void show(int x, int z, int c[x][z]){
    for(int i=0; i<x; i++){
        for(int j=0; j<z; j++){
            printf("%d ",c[i][j]);
        }
        printf("\n");
    }
}

void cre(int x, int y, int A[x][y]){
    int s;
    
    for(int i=0; i<x; i++){
        for(int j=0; j<y; j++){
            printf("%d行%d列の要素を入力してください:,",i+1,j+1);
            scanf("%d",&s);
            
            A[i][j] = s;
        }
    }
}

void cre_0(int x, int y, int A[x][y]){
    for(int i=0; i<x; i++){
          for(int j=0; j<x; j++){
              A[i][j] = 0;
          }
      }
}



int main(void) {
    int xA,xB,yA,yB;
    int t=0;
    
    do{
        printf("行列Aの行数は?");
        scanf("%d",&xA);
        printf("行列Aの列数は?");
        scanf("%d",&yA);
        printf("行列Bの行数は?");
        scanf("%d",&xB);
        printf("行列Bの列数は?");
        scanf("%d",&yB);
        
        if(yA == xB){
            t = 1;
        }else{
            printf("これでは計算できません\n");
        }
        
    }while(t == 0);
    
    int A[xA][yA];
    printf("行列Aの\n");
    cre(xA, yA, A);
    
    int B[xB][yB];
    printf("行列Bの\n");
    cre(xB, yB, B);
    
    int C[xA][yB];
    cre_0(xA, yB, C);
    
    
    multi(xA, yA, yB, A, B, C);
    show(xA, yB, C);
}

全体のコードです。
showは中身表示用です。

ちょっとコードが長くなりましたね。
mainのところはもう少し関数化して綺麗にできたかも…


てことで今回はここまで

ではまた〜

syumokuzame

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする