【问题标题】:error : invalid type argument of unary '*' (have 'int')错误:一元'*'的无效类型参数(有'int')
【发布时间】:2018-01-20 17:05:12
【问题描述】:

1.这是使用指针添加两个矩阵的程序的一部分。

2.我收到错误error : invalid type argument of unary '*' (have 'int')

3.这里AB是初始化的二维数组,c1r1不是。矩阵Ac2r2的列和行分别为否。矩阵B的列和行。

main() {
    int i, j, A[10][10], B[10][10], r1, r2, c1, c2;

    //Inputting Matrix A
    printf("\nFOR SET A ");
    printf("\n\nEnter number of rows : ");
    scanf("%d", &r1);
    printf("\n\nEnter Number of Columns :");
    scanf("%d", &c1);
    printf("\n\nEnter Elements of matrix A :\n\n");
    for (i = 0; i < r1; i++) {
       for (j = 0; j < c1; j++) {
           scanf("%d", (*(A + i) + j));
       }
    }

    //Inputting Matrix A
    printf("\n\nFOR SET B:");
    printf("\n\nEnter number of rows : ");
    scanf("%d", &r2);
    printf("\n\nEnter Number of Columns :");
    scanf("%d", &c2);
    printf("\n\nEnter Elements of matrix B :\n\n");
    for (i = 0; i < r2; i++) {
       for (j = 0; j < c2; j++) {
           scanf(" %d", (*(B + i) + j));
       }
    }

     //Displaying matrix A
     printf("\n\nMatrix A is :\n\n");
     for (i = 0; i < r1; i++) {
         for (j = 0; j < c1; j++) {
              printf(" %d ", *(*(A + i) + j));
         }
         printf("\n\n");
     }

     //Displaying matrix B
     printf("\n\nMatrix B is :\n\n");
     for (i = 0; i < r2; i++) {
         for (j = 0; j < c2; j++) {
              printf(" %d ", *(*(B + i) + j));
         }
         printf("\n\n");
     }

     //Calling the Addition function
     add(A, r1, c1, B, r2, c2);
 }

 void add(int **A, int r1, int c1, int **B, int r2, int c2) {
     if (r1 == r2 && c1 == c2) {
         int i, j;
         printf("\n\nThe Addition of matrix A and B is :\n\n");
         for (i = 0; i < r1; i++) {
             for (j = 0; j < c1; j++) {
                 printf(" %d ", ((*(*(A + i) + j)) + (*(*(B + i) + j))));
             }
             printf("\n\n");
         }
    } else
        printf("\n\nMatrices are not of same order !!!");
}

【问题讨论】:

  • 问问自己*(A+i) 的类型是什么。数组语法更易于阅读,请改用它。
  • 看起来你取消引用了这么多,以至于你试图取消引用一个 int 为什么你不使用 A[i][j] 这也算作取消引用,否则这看起来很混乱我的建议,但你可以保持你的风格
  • 我的大学作业要使用指针进行加法。

标签: c arrays pointers matrix


【解决方案1】:

无论您实际输入了多少元素,您的数组都以固定 大小声明。您的函数必须知道这一点,它至少知道一行中的元素数量,因此它可以正确计算到下一行的偏移量。在您的情况下,请使用以下原型:

void add(int (*A)[10], int r1, int c1, int (*B)[10], int r2, int c2)

【讨论】:

  • @NiRajWagh 只是提到这一点并不明显,直到您编辑问题以显示声明。请参阅chqrlie's answer 了解一些重要的数组相关知识:)
【解决方案2】:

您的函数未正确计算元素的偏移量。

您可以这样更正代码:

void add(int *A, int r1, int c1, int *B, int r2, int c2) { 
    if (r1 == r2 && c1 == c2) {
        int i, j;
        printf("\n\nThe Addition of matrix A and B is :\n\n");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c1; j++) {
                printf(" %d ", A[i * c1 + j] + B[i * c2 + j]);
                // if you must use the less readable pointer syntax
                // use this strictly equivalent form instead:
                //printf(" %d ", *(A + i * c1 + j) + *(B + i * c2 + j));
            }
            printf("\n");
        }
        printf("\n");
    } else {
        printf("Matrices are not of same order !!!\n\n");
    }
}

函数可以这样调用:

int mat1[3][4] = { ... };
int mat2[3][4] = { ... };

add(&mat1[0][0], 3, 4, &mat2[0][0], 3, 4);

请注意,由于您只处理具有完全相同几何形状的矩阵,因此您可以通过这种方式进一步简化主循环:

    int i, j, k = 0;
    printf("\n\nThe Addition of matrix A and B is :\n\n");
    for (i = 0; i < r1; i++) {
        for (j = 0; j < c1; j++, k++) {
            printf(" %d ", A[k] + B[k]);
            k++;
        }
        printf("\n");
    }
    printf("\n");

正如 Felix Palmen 评论的那样,C99 引入了可变长度数组和将它们作为函数参数传递的语法:

void add(int r1, int c1, int (*A)[c1], int r2, int c2, int (*B)[c2]) { 
    if (r1 == r2 && c1 == c2) {
        int i, j;
        printf("\n\nThe Addition of matrix A and B is :\n\n");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c1; j++) {
                printf(" %d ", A[i][j] + B[i][j]);
                // if you must use the less readable pointer syntax
                // use this strictly equivalent form instead:
                //printf(" %d ", *(*(A + i) + j) + *(*(B + i) + j));
            }
            printf("\n");
        }
        printf("\n");
    } else {
        printf("Matrices are not of same order !!!\n\n");
    }
}

函数可以这样调用:

int mat1[3][4] = { ... };
int mat2[3][4] = { ... };

add(3, 4, mat1, 3, 4, mat2);

但是请注意,一些主流 C 编译器不支持此功能,并且在最新版本的标准 (C11) 中已成为可选功能。

编辑:您的情况实际上非常不同:您的矩阵具有 10x10 的固定大小,并且您想要处理 2D 子矩阵。你的函数应该是这样的:

void add(int A[][10], int r1, int c1, int B[][10], int r2, int c2) { 
    if (r1 == r2 && c1 == c2) {
        int i, j;
        printf("\n\nThe Addition of matrix A and B is :\n\n");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c1; j++) {
                printf(" %d ", A[i][j] + B[i][j]);
                // if you must use the less readable pointer syntax
                // use this strictly equivalent form instead:
                //printf(" %d ", *(*(A + i) + j) + *(*(B + i) + j));
            }
            printf("\n");
        }
        printf("\n");
    } else {
        printf("Matrices are not of same order !!!\n\n");
    }
}

函数可以这样调用:

add(mat1, 3, 4, mat2, 3, 4);

最后,您的原型void add(int **A, int r1, int c1, int **B, int r2, int c2) 不正确,因为ABint 数组的数组,而不是int 数组的指针数组。

还要注意add 的原型应该出现在调用它的代码之前。不带参数的 main 的原型是 int main(void),您的语法已过时,自 C99 起不再受支持。

【讨论】:

  • 虽然这行得通,但严格来说 UB 是否可以越界访问数组mat1[0]mat2[0]
  • 我必须使用指针方法,因为我有这个作为我的大学作业
  • 如果您对 VLA 感到满意,替代方案将是 add(size_t r1, size_t c1, int (*A)[c1], /* ... */) 之类的签名...
  • @NiRajWagh x[n]*(x+n) 是写同一件事的两种方式,总是。所以没关系。
  • @FelixPalmen:严格来说不就是UB吗?对于更高级的读者来说,这是一个有趣的问题。破解这个密码需要一个非常恶毒的系统。
【解决方案3】:

你有一个数组数组。这意味着你应该使用

void add(int **A,int r1,int c1,int **B,int r2,int c2)

作为函数原型。 你也可以显示整个代码吗?

编辑:(完整代码)

int** mat_add(int** A, int **B, int r1, int c1, int r2, int c2){
int** C, i, j;
C =(int **)calloc(r1*c1, sizeof(int*));

for(i=0;i <r1;i++)
    C[i] = (int *)calloc(c1, sizeof(int));

for(i = 0;i < r1; i++)
    for(j = 0; j < c1; j++)
        C[i][j] = A[i][j] + B[i][j];
return C;
}
void print_arr(int** C, int r, int c){
    int i,j;
    for (i=0;i<r;i++){
        for(j=0;j<c;j++)
            printf("%d\t", C[i][j]);
        printf("\n");
    }
}

int main(){
    int **A, **B, r1, r2, c1, c2;
    int i;
    scanf("%d%d%d%d", &r1, &r2, &c1, &c2);
    A = (int**)calloc(r1*c1, sizeof(int*)); //used for allocating memory for pointers
    B = (int**)calloc(r2*c2, sizeof(int*));

    for(i=0;i <r1;i++)
        A[i] = (int *)calloc(c1, sizeof(int)); //used for allocating memory for each row of integers having size of length of column
    for(i=0;i <r2;i++)
        B[i] = (int *)calloc(c2, sizeof(int));

    //take matrices as input from the user here
    //...

    if(r1==r2 && c1==c2){
        int ** C = mat_add(A, B, r1, c1, r2, c2);
        print_arr(C, r1, c1);
    }
    else
        printf("MATRICES MUST BE OF SAME SIZE!");
    return 0;
}

【讨论】:

  • 是的,当然。但完整的代码在评论框中是不可接受的。我应该在哪里发布它
  • 你为什么不编辑你的问题并添加完整的代码?
  • 这个答案是错误的。即使在最初的修订版中,问题是使用了 2D-Arrays,而不是指针数组。
  • 查看我的编辑。您可以使用这种技术来实现二维数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多