【问题标题】:Passing argument makes a pointer without cast?传递参数使指针没有强制转换?
【发布时间】:2017-03-29 18:23:36
【问题描述】:

我在编译代码时遇到问题。 我不断收到这些错误。

“C: 194 警告传递 'matrix_column_subtract' 的参数 3 使指针从整数而不进行强制转换”

"C: 12 注意:预期为 'double**' 但参数类型为 'int'

“C: 194 错误函数'matrix_column_subtract'的参数太少

我想我知道发生了什么我正在调用 matrix_column_multiply 是一个 void,我需要将它称为我认为的指针指针,我不知道如何更改它。如果有人对我如何编译它有一些想法,将不胜感激!

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

#define DEBUG 0
#define MAX_ITER 10000

double *eigen (int n, double **A);
void qr_decomp (int n, double **A, double **Q, double **R);

void matrix_copy_column(double **msrc, int col1, double **mdst,int col2, int rows);
void matrix_column_subtract(double **m1, int c1, double **m2, int c2, int rows);
void matrix_column_multiply(double **m, int c, double k, int rows);


int main() {

    int i, n = 126;
    double *eig, **Am;
    FILE *BinInp, *TxtOut;

    /* Input Code: Reads bv, Am in binary form from CGrad.bin */
    if ( (BinInp = fopen("CGrad.bin","r")) == NULL ) {
        fprintf(stderr, "Cannot open matrix binary file INPUT... exiting\n");
        exit(-1);
    }

    Am = (double**)malloc (n*sizeof(double*));
    Am[0] = (double*)malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        Am[i] = Am[0] + i*n;
    }
    for (i = 0; i < n; i++) {
        if (i==0) { /* Read one extra line that is discarded (bv is still in bin       file) */
            if (!fread(Am[i], sizeof(double), n, BinInp)) {
                fprintf(stderr, "Cannot read row Am[%03d] of matrix...      exiting\n", i+1);
                exit(1);
            }
        }
        if (!fread(Am[i], sizeof(double), n, BinInp)) {
            fprintf(stderr, "Cannot read row Am[%03d] of matrix... exiting\n",  i+1);
            exit(1);
        }
    }

    if (fclose(BinInp) == EOF) {
        fprintf(stderr, "Cannot close matrix binary file INPUT... exiting\n");
        exit(-1);
    }

    /* COMPUTE EIGENVALUES HERE USING FUNCTIONS. RETURN EIGENVALUES (AS 1D    VECTOR) TO eig. */
    if (DEBUG) printf ("Calling eigen\n");
    eig = eigen (n, Am);

    /* Output Code: Writes eig in text form to Eigs.txt */

    if ( (TxtOut = fopen("Eigs.txt", "w")) == NULL ) {
        fprintf(stderr, "Cannot open matrix text file OUTPUT... exiting\n");
        exit(-1);
    }
    for (i = 0; i < n; i++) {
        fprintf (TxtOut, "%18.14e ", eig[i]);
    }

    if (fclose(TxtOut) == EOF) {
        fprintf(stderr, "Cannot close matrix text file INPUT... exiting\n");
        exit(-1);
    }

    return 0;
}

double* eigen (int n, double **Acur)
{
    double err = 1, eps = 1e-2;
    double ndenom, nnumer, temp;
    double *eig, **Anex, **Qsub, **Rsub;
    int i, j, k, iters = 1;

    /* Malloc memory for the three matricies */
    Anex = malloc (n*sizeof(double*));
    Anex[0] = malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        Anex[i] = Anex[0] + i*n;
    }
    Qsub = malloc (n*sizeof(double*));
    Qsub[0] = malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        Qsub[i] = Qsub[0] + i*n;
    }
    Rsub = malloc (n*sizeof(double*));
    Rsub[0] = malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        Rsub[i] = Rsub[0] + i*n;
    }

    /* Malloc memory for the return eig vector */
    eig  = malloc (n*sizeof(double));
    for (i = 0; i < n; i++) {
        eig[i] = 0;
    }

    /* Enter main iteration loop for eigenvalues */
    while (err > eps && iters < MAX_ITER) {

        /* QR Decompose Acur then find next iterate value in Anex */
        qr_decomp (n, Acur, Qsub, Rsub);
        // FIND NEXT ITERATE VALUE, PUT IN Anex.

        /* Determine relative error change, reset "old" iterate value. */
        ndenom = 0;
        nnumer = 0;
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                temp = Anex[i][j]-Acur[i][j];
                ndenom += temp*temp;
                nnumer += Anex[i][j]*Anex[i][j];

                Acur[i][j] = Anex[i][j];
            }
        }
        err = sqrt(ndenom)/sqrt(nnumer);

        /* Increment the iteration count and report error */
        if (iters % 25 == 0) {
            printf ("Error at end of iteration %05d = %14.10f %%\n", iters,   100*err);
        }
        ++iters;
    }
    printf ("Error at end of iteration %05d = %14.10f\nCONVERGED.\n", iters-1, err);

    if (iters == MAX_ITER) {
        printf ("WARNING: MAX_ITER iterations reached!...\n");
    }

    /* Copy diagonal entries of Acur into eig for return to main */
    for (i=0; i<n; i++) {
        eig[i] = Acur[i][i];
    }
    return eig;
}

void qr_decomp (int n, double **Adec, double **myQ, double **myR) 
{
    int i, j, k; /* Loop Variables: this is all you should need! */
    double **T, **S;
    double r;

    T = malloc (n*sizeof(double*));
    T[0] = malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        T[i] = T[0] + i*n;
    }

    S = malloc (n*sizeof(double*));
    S[0] = malloc (n*n*sizeof(double));
    for (i = 1; i < n; ++i) {
        S[i] = S[0] + i*n;
    }

    /* Main loop for decomposition */
    for (i=0; i<n; i++) {
        /* Column i of Q is initially column i of A */

        matrix_copy_column(Adec,i,myQ,i,n);

        /* For j < i-1, Perform the dot product between the j row of Q and the
        i row of A to determine the R(j,i) value, then insure the Q i column
        is orthogonal to all other Q columns by subtracting existing Q columns
        from it. */

        for (j = 0; j < i; j++) {

            //r[j,i] = Qj^T * Ui
            matrix_copy_column(myQ,j,T,0,n);
            matrix_copy_column(Adec,i,S,0,n);

            for (k=0; k<n; k++) {
                r += T[k][0] * S[k][0];
            }
            /* Determine the R diagonal as the magnitude of the Q column, then
            normalize the Q column (make it a unit vector). */

            //Qi = Ui

            myR[j][i] = r;

            // Something wrong here.
            // There is one parameter missing, as matrix_column_subtract needs 5 parameters and
            // only 4 are given.
            // Also, matrix_column_multiply is defined as returning a void, whereas the   3rd parameter
            // of matrix_column_subtract should be a double **

            matrix_column_subtract(myQ,i,matrix_column_multiply(T,0,r,n),j);

        }
    }
}


/* Copies a matrix column from msrc at column col1 to mdst at column col2 */
void matrix_copy_column(double **msrc, int col1, double **mdst,int col2, int rows) {
    int i = 0;
    for (i=0; i<rows; i++) {
        mdst[i][col2] = msrc[i][col1];
    }
}

/* Subtracts m2's column c2 from m1's column c1 */
void matrix_column_subtract(double **m1, int c1, double **m2, int c2, int rows) {
    int i = 0;
    for (i=0; i<rows; i++) {
        m1[i][c1] -= m2[i][c2];
    }
    /*return m1;*/
}

void matrix_column_multiply(double **m, int c, double k, int rows) {
    int i = 0;
    for (i=0; i<rows; i++) {
        m[i][c] *= k;
    }
    /*return m;*/
}

【问题讨论】:

  • 注意:像double ** 这样的东西不是矩阵(又名二维数组),也不能指向一个。指针不是数组。而且我们没有调试服务。阅读How to Ask 并提供minimal reproducible example。通过一些诊断向我们扔一堵代码墙并不是这里的工作方式。
  • 我试图弄清楚那些 for 循环在 qr_decomp 开头的作用。 T 有空间存放n double * 的列表,而T[0] 有空间存放n*n 数字,但T[i] = T[0] + i*n; 在做什么?这是在T[0] 中分配一个二维数组,然后T 的其余部分指向T[0] 中的行吗?为什么?这是一种允许T[x][y] 工作而只需分配两个内存块的技术吗?

标签: c


【解决方案1】:

这里有问题。

matrix_column_subtract(myQ,i,matrix_column_multiply(T,0,r,n),j);

相关的函数签名是:

void matrix_column_subtract(double **m1, int c1, double **m2, int c2, int rows);
void matrix_column_multiply(double **m, int c, double k, int rows);

请注意,matrix_column_multiply 返回 void,但您将其传递为 double **。我猜编译器正在拼命让它工作并返回某种垃圾整数。

这些函数返回 void,因为它们直接在相关矩阵上工作。 matrix_column_multiply 更改为 mmatrix_column_subtract 更改为 m1

要使其工作,请在T 上调用matrix_column_multiply,然后将T(现在由乘法修改)传递给matrix_column_subtract

matrix_column_multiply(T, 0, r, n);
matrix_column_subtract(myQ, i, T, j, ...rows...);

您仍然缺少第五个参数rows。我猜那是n,与其他所有matrix_column_blah 调用中的行相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多