【问题标题】:Passing matrix as a parameter传递矩阵作为参数
【发布时间】:2016-02-22 08:25:42
【问题描述】:

我是 c 新手,我正在使用 CUDA 编译器。我想声明五个矩阵,从 a[1][1] 到 a[5][5]。用随机值初始化它们。打印这些值。我已经展示了我编写的整个代码。我面临问题

  1. 将矩阵作为参数传递

  2. 初始化一个矩阵(应该是常数)

    #include <stdio.h>
    #include <stdlib.h>
    
    void printMatrix(int **a, int rows, int cols)
    {
        for(int i=0; i<rows; i++){
            for (int j=0; j<cols; j++){
                printf("%d\t", a[i][j] );
            }
            printf("\n");
        }
    }
    
    int main() {
        int N;
    
        for (int n=0; n<=5; n++)
            N = n;
            int a[N][N];
    
            for(int i=0; i<N; i++)
                for (int j=0; j<N; j++){
                    a[i][j] = rand() % 256;
                }
    
            printf("Matrix A\n");
            printMatrix(a, 10, 10);
        }
    }
    

    如果我在顶部定义 N,这可以正常工作。如果我这样做了,我无法使用 for 循环更改 N 值。我该如何纠正。

【问题讨论】:

  • “初始化一个矩阵(应该是常数)”不清楚你的意思。什么应该是不变的?数组数据?数组大小?为什么需要N 变量开头?另外,请发布编译的实际代码。

标签: c arrays function multidimensional-array


【解决方案1】:

对于初学者来说,程序中有一个错字。您在循环语句后省略了左大括号

for (int n=0; n<=5; n++)
                        ^^^^
    N = n;
    int a[N][N];
    //...

应该有

for (int n=0; n<=5; n++) {
                        ^^^^
    N = n;
    int a[N][N];
    //...

数组a 是一个可变长度数组。它的维度可能不等于0。所以变量n必须从1开始,因为它写在赋值中

for (int n=1; n<=5; n++) {
         ^^^^

这个函数调用

printMatrix(a, 10, 10);
               ^^  ^^

没有意义,因为数字 10 与数组没有任何共同点。

以及函数声明

void printMatrix(int **a, int rows, int cols);
                 ^^^^^^^

无效。实参类型和参数类型不匹配,并且没有从一种类型到另一种类型的隐式转换。

程序可能看起来像

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

void printMatrix( size_t rows, size_t cols, int a[][cols] )
{
    for ( size_t i = 0; i < rows; i++ )
    {
        for ( size_t j = 0; j < cols; j++ ) printf( "%3d ", a[i][j] );
        printf( "\n" );
    }
}

int main( void ) 
{
    const size_t N = 5;
    const int UPPER_VALUE = 256;

    srand( ( unsigned int )time( NULL ) );

    for ( size_t n = 1; n <= N; n++ )
    {
        int a[n][n];

        for ( size_t i = 0; i < n; i++ )
        {
            for ( size_t j = 0; j < n; j++ ) a[i][j] = rand() % UPPER_VALUE;
        }

        printf( "Matrix A[%zu][%zu]:\n", n, n );
        printMatrix( n, n, a );
        printf( "\n" );
    }        

    return 0;
}

它的输出可能是

Matrix A[1][1]:
117 

Matrix A[2][2]:
 57 216 
 50 233 

Matrix A[3][3]:
 42 117 215 
177 218  26 
202  81 163 

Matrix A[4][4]:
205 178 157   2 
229 165  93  94 
 91 160  39 205 
 26 242 131  69 

Matrix A[5][5]:
147 248 126 107  42 
103 149 160  62  70 
122  89  17 203 252 
222 125 154 224  98 
 63  61 192 155 222 

如果编译器不支持可变长度数组,那么您必须动态分配数组。例如

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

void printMatrix( int **a, size_t rows, size_t cols )
{
    for ( size_t i = 0; i < rows; i++ )
    {
        for ( size_t j = 0; j < cols; j++ ) printf( "%3d ", a[i][j] );
        printf( "\n" );
    }
}

int main( void ) 
{
    const size_t N = 5;
    const int UPPER_VALUE = 256;

    srand( ( unsigned int )time( NULL ) );

    for ( size_t n = 1; n <= N; n++ )
    {
        int **a = malloc( n * sizeof( int * ) );

        for ( size_t i = 0; i < n; i++ )
        {
            a[i] = malloc( n * sizeof( int ) );
            for ( size_t j = 0; j < n; j++ ) a[i][j] = rand() % UPPER_VALUE;
        }

        printf( "Matrix A[%zu][%zu]:\n", n, n );
        printMatrix( a, n, n );
        printf( "\n" );

        for ( size_t i = 0; i < n; i++ ) free( a[i] );
        free( a );
    }        

    return 0;
}

【讨论】:

  • 有什么理由你会使用int a[][cols] 而不是int a[rows][cols]?在任何一种情况下,数组参数都会衰减为数组指针,但后一种形式可能会提供更好的类型安全性。
  • @Lundin 我以类比 void f( int a[], size_t n ); :) 当然可以像你展示的那样写。:)
  • @Lundin 例如,如果函数一开始只被声明,我用以下方式编写它的声明 void printMatrix( size_t, size_t, int [][*] );
  • 我想这是风格问题。我总是为原型中的参数命名,并确保它们与函数定义相同。
  • @Vlad 来自莫斯科 - 谢谢,因为我使用的是 CUDA C 编译器,所以这不是编译。我在第 5 行得到“不允许使用参数”,在第 23 行得到“表达式必须是常数值”
【解决方案2】:
for (int n=0; n<=5; n++){  /* <--missing { which causes N to be 6 after last iteration */
 //your code
}

main 中的第一个for 循环之后,您错过了{,这就是为什么int a[N][N] 和其他循环不在其主体内(您可能想要“更改值的值 N ")

【讨论】:

    【解决方案3】:

    似乎矩阵的数量是恒定的,所以只需在顶部 #define 即可。在不触及 printMatrix 方法的情况下,您可以拥有如下主体:

    #define N 5
    int main(int argc, char ** argv)
    {
        int **data[N]; // Array of length N of int **, where each int ** will store a matrix.
        for (int i = 0; i < N; i++) {
            int matrixSize = i + 1; // creating the ith matrix
            data[i] = malloc(matrixSize * sizeof *data[i]);
            for (int j = 0; j < matrixSize; j++) {
                data[i][j] = malloc(matrixSize * sizeof *data[i][j]);
                for (int k = 0; k < matrixSize; k++) {
                    data[i][j][k] = rand() % 256;
                }
            }
        }
        // Printing the first one
        printMatrix(data[0], 1, 1);
    
        // don't forget to loop again to free the buffers allocated...
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 2021-11-20
      相关资源
      最近更新 更多