Как передать многомерные массивы в качестве аргумента? - PullRequest
1 голос
/ 08 июля 2019
#include <stdio.h>

void input(int* r1, int* r2, int* c1, int* c2,
  int arr1[*r1][*c1], int arr2[*r2][*c2]);
void matrix_multiply(int* r1, int* r2, int* c1, int* c2, 
  int arr1[*r1][*c1], int arr2[*r2][*c2], int result[50][50]);
int ouput_matrix(int*r1 , int* c2, int result[50][50]);

int main(void)
{
    int arr1_out[50][50];
    int arr2_out[50][50];
    int result_out[50][50];

    int a = 0;
    int* r1 = &a;

    int b = 0;
    int* r2 = &b;

    int c = 0;
    int* c1 = &c;

    int d = 0;
    int* c2 = &d;

    input(r1,r2,c1,c2,arr1_out,arr2_out);
    matrix_multiply(r1, r2,c1, c2,arr1_out, arr2_out,result_out);

    output_matrix(r1,c2,result_out);

}

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2])
{
    printf("Enter the no. of rows and columns of first matrix ");
    scanf("%d %d\n",r1,c1);

    printf("Enter the no. of rows and columns of second matrix");
    scanf("%d %d\n",r2,c2);

    while(*c1 != *r2)
    {
        printf("Matrix cannot be multiplied...no. of columns of 1st matrix not equal to no. of rows of 2nd matrix");

        printf("Enter the no. of rows and columns of first matrix ");
        scanf("%d %d\n",r1,c1);

        printf("Enter the no. of rows and columns of second matrix");
        scanf("%d %d\n",r2,c2);
    }

    printf("Enter the elements of matrix 1");
    for(int i = 0;i < *r1;i ++)
        for(int j = 0;j < *c1;j ++)
        {
            printf("Enter element a%d%d",i + 1,j + 1);
            scanf("%d",&arr1[i][j]);
        }


    printf("Enter the elements of matrix 2");
    for(int i = 0;i < *r2;i ++)
        for(int j = 0;j < *c2;j ++)
        {
            printf("Enter element b%d%d",i + 1,j + 1);
            scanf("%d",&arr2[i][j]);
        }
}

void matrix_multiply(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int 
arr2[*r2][*c2],int result[50][50])
{
    for(int i = 0; i < *r1; ++i)
        for(int j = 0; j < *c2; ++j)
        {
            result[i][j] = 0;
        }

    for(int i = 0; i < *r1; ++i)
        for(int j=0; j < *c2; ++j)
            for(int k=0; k < *c1; ++k)
            {
                result[i][j]+=arr1[i][k]*arr2[k][j];
            }
}

int ouput_matrix(int*r1 , int* c2, int result[50][50])
{
    printf("\nOutput Matrix:\n");
    for(int i = 0; i < *r1; ++i)
        for(int j = 0; j < *c2; ++j)
        {
            printf("%d  ", result[i][j]);
            if(j == *c2-1)
                printf("\n\n");
        }
    return 0;
}

Ошибка:

matrix_multi.c:32:53: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:58: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:72: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:77: runtime error: variable length array bound evaluates to non-positive value 0

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Вы определили функции, которые имеют массивы переменной длины в качестве своих параметров.

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2]);
void matrix_multiply(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int 
arr2[*r2][*c2],int result[50][50]);

Но вы передаете нулевые значения в качестве размеров массивов.

int a = 0;
int* r1 = &a;

int b = 0;
int* r2 = &b;

int c = 0;
int* c1 = &c;

int d = 0;
int* c2 = &d;

Массивы переменной длины могут не иметь нулевого размера.

Вы должны хотя бы написать

int a = 50;
int* r1 = &a;

int b = 50;
int* r2 = &b;

int c = 50;
int* c1 = &c;

int d = 50;
int* c2 = &d;

Но в качестве пользовательских спецификаторов в функциях указывается числостроки и столбцы и массивы на самом деле имеют фиксированные размеры, тогда вы должны объявить функции как

void input(int* r1, int* r2, int* c1, int* c2,
  int arr1[][50], int arr2[][50]);
void matrix_multiply(int* r1, int* r2, int* c1, int* c2, 
  int arr1[][50], int arr2[][50], int result[][50]);
0 голосов
/ 08 июля 2019

Рассмотрим отправленную функцию ввода

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2]) {/* */}

Количество строк и столбцов обоих массивов передается как указатели, намерение изменить их значение внутри функции, но они также инициализируются равными нулю за пределамифункции и , используемые для вычисления параметров VLA, фактически двух массивов нулевого размера.Это не может быть сделано.

Жизнеспособным подходом было бы сначала запросить у пользователя размеры, проверить, являются ли они действительными, и только потом объявить массивы и передать их различным функциям.Что-то вроде следующего.

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

typedef int value_t;

int input_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] );
void print_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] );

int ask_matrix_dimensions( const char *msg, int *rows, int *cols );

void multiply_matrices( size_t rows, size_t inner, size_t cols,
                        value_t mat_a[rows][inner], value_t mat_b[inner][cols],
                        value_t mult[rows][cols] );

int main(void)
{
    int ra, ca;
    if ( ask_matrix_dimensions("the first matrix", &ra, &ca) != 2 )
        return EXIT_FAILURE;

    int rb, cb;
    if ( ask_matrix_dimensions("the second matrix", &rb, &cb) != 2 )
        return EXIT_FAILURE;

    if ( ca != rb )
    {
        fputs("Error: Wrong dimensions, the two matrices cannot be multiplied.", stderr);   
        return EXIT_FAILURE;
    }
    value_t mat_a[ra][ca];
    if ( input_matrix("%d", ra, ca, mat_a) == EOF )
        return EXIT_FAILURE;

    value_t mat_b[rb][cb];
    if ( input_matrix("%d", rb, cb, mat_b) == EOF )
        return EXIT_FAILURE;

    puts("\nMatrix a:");
    print_matrix("%3d", ra, ca, mat_a);
    puts("Matrix b:");
    print_matrix("%3d", rb, cb, mat_b);

    value_t mat_c[ra][cb];
    multiply_matrices(ra, ca, cb, mat_a, mat_b, mat_c);
    puts("Matrix b:");
    print_matrix("%4d", ra, cb, mat_c);

    return EXIT_SUCCESS;
}

int input_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] )
{ 
    int ret;
    for(size_t r = 0; r < rows; ++r)
    {
        for(size_t c = 0; c < cols; ++c)
        {
            printf("Enter element (%zu, %zu): ", r + 1, c + 1);
            while ( (ret = scanf(format, &mat[r][c])) != 1 )
            {
                if (ret == EOF)
                {
                    fputs("Error: Unexpected end of input.", stderr);
                    return ret;
                }
                puts("Please enter a valid number.");
                for (int ch = getchar(); ch != EOF  &&  ch != '\n'; ch = getchar());
            }
        }
    }
    return 0;
}

void print_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] )
{
    for (size_t r = 0; r < rows; ++r)
    {
        for (size_t c = 0; c < cols; ++c)
        {
            printf(format, mat[r][c]);
        }
        putchar('\n');
    }
}

int ask_matrix_dimensions( const char *msg, int *rows, int *cols )
{
    printf("Please enter the number of rows and columns of %s: ", msg);
    int ret;
    while ( (ret = scanf("%d%d", rows, cols)) != 2  ||  *rows < 1  ||  *cols < 1)
    {
        if (ret == EOF)
        {
            fputs("Error: Unexpected end of input.", stderr);
            break;
        }
        puts("Please enter two positive numbers.");
        for (int ch = getchar(); ch != EOF  &&  ch != '\n'; ch = getchar());
    }
    return ret;
}

void multiply_matrices( size_t rows, size_t inner, size_t cols,
                        value_t mat_a[rows][inner], value_t mat_b[inner][cols],
                        value_t mult[rows][cols] )
{
    for (size_t i = 0; i < rows; ++i)
    {
        for (size_t j = 0; j < cols; ++j)
        {
            mult[i][j] = mat_a[i][0] * mat_b[0][j];
        }
        for (size_t k = 1; k < inner; ++k)
        {
            for (size_t j = 0; j < cols; ++j)
            {
                mult[i][j] += mat_a[i][k] * mat_b[k][j];
            }   
        }        
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...