Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将非常量动态多维数组传递给需要常量多维数组的函数?_C_Multidimensional Array_Dynamic_Parameter Passing_Constants - Fatal编程技术网

C 如何将非常量动态多维数组传递给需要常量多维数组的函数?

C 如何将非常量动态多维数组传递给需要常量多维数组的函数?,c,multidimensional-array,dynamic,parameter-passing,constants,C,Multidimensional Array,Dynamic,Parameter Passing,Constants,我在C中编写了以下函数,以打印出动态创建的矩阵,但保证在函数中 无法修改给定的指针 无法修改任何内部指针 无法修改矩阵中的任何数字 我的IDE出现以下错误: Parameter type mismatch: Assigning int** to const int* const* const* discards const qualifier. 如果我删除函数声明中的第一个常量,代码将正常工作。从 void const2dPrinter(constint*const*const mat,…

我在C中编写了以下函数,以打印出动态创建的矩阵,但保证在函数中

  • 无法修改给定的指针
  • 无法修改任何内部指针
  • 无法修改矩阵中的任何数字

  • 我的IDE出现以下错误:

    Parameter type mismatch: Assigning int** to const int* const* const* discards const qualifier. 
    
    如果我删除函数声明中的第一个常量,代码将正常工作。从 void const2dPrinter(constint*const*const mat,…){

    到 无效常量打印机(int*const*const mat,…){

    但是我可以在const2dPrinter中修改矩阵的值,这是我不想做的

    我知道我可以在调用函数时将
    int**
    转换为
    const int*const*const
    ,如下所示,但是我非常困惑,为什么我现在所拥有的不起作用,因为我读到的所有内容都说,应该能够让一个const指针指向一个非const值

    const2dPrinter((const int* const* const) mat, numRows, numCols); //this works 
    
    <>我尝试过一个解决方案,但一直找不到。代码将在没有问题的C++编译器上编译,但是在我的C编译器(GCC)上不能工作。
    如果您能就如何解决我的问题提供任何建议,并解释为什么我现在的方法不起作用,我们将不胜感激。

    您必须编写难看的演员阵容(尽管最后一个
    常量是多余的)C规范中的一个疏忽是,没有将
    T**
    更改为
    T const*const*

    我认为在实践中,由于这个问题,在有指向指针的指针或指向数组的指针的情况下,人们往往最终不使用
    const
    。您可以使用强制转换和/或通用选择器等来解决这个问题。但要支持简单的操作,事情很快就会变得复杂起来



    对于您的特定情况,另一种方法可能是使用一维数组来存储矩阵。(由于需要的分配数量较少,因此在运行时可能会更有效)。

    为了将参数作为常量指针传递给您希望参数为的常量int:

    void const2dprinter (const int* const* mat, const int numrows, const int numcols)
    
    无需强制转换malloc的返回,这是不必要的。请参阅:。您的分配还应使用取消引用的指针,以确保始终获得正确的类型大小,例如

        int **mat = malloc (numrows * sizeof *mat);
        ...
            mat[i] = malloc (numcols * sizeof *mat[i]);
    
    现在就养成好习惯。如果你分配内存,你对分配的任何内存块有两个责任:(1)始终保留指向内存块起始地址的指针,因此,(2)它可以在不再需要时释放。跟踪您分配的内容,然后在丢失指针之前释放内存。只需一个简单的释放函数,例如

    void mat_free (int **mat, const int numrows)
    {
        for (int i = 0; i < numrows; i++)
            free (mat[i]);      /* free rows */
        free (mat);             /* free pointers */
    }
    

    仔细看一下,如果有问题请告诉我。

    谢谢你花时间回答。听说演员阵容是必要的,我很沮丧:(感谢您提供关于在解除防护的指针上使用sizeof以确保我始终分配正确的空间量的提示。在您的回答中,看起来您在调用中使用了强制转换,并且根据@M.M.的回答,这似乎是必要的。强制转换是我希望避免的,但听起来似乎没有办法:(不,强制转换无法在没有警告的情况下编译(您的所有代码都应该在没有警告的情况下干净地编译)。没有强制转换,您将收到警告
    “预期为'const int*const*”,但参数的类型为'int**'
    。(这是一个警告——代码可以工作,但在编译时不会接受代码,除非它没有警告)在gcc/clang上总是使用
    -Wall-Wextra-pedantic
    (最小值)或VS(
    cl.exe
    )使用
    /W3
    (最小值)或您可以使用
    /W4
    ——但您将生成大量与代码无关的警告。
    void const2dprinter (const int* const* mat, const int numrows, const int numcols)
    
        int **mat = malloc (numrows * sizeof *mat);
        ...
            mat[i] = malloc (numcols * sizeof *mat[i]);
    
    void mat_free (int **mat, const int numrows)
    {
        for (int i = 0; i < numrows; i++)
            free (mat[i]);      /* free rows */
        free (mat);             /* free pointers */
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void const2dprinter (const int* const* mat, const int numrows, const int numcols)
    {
        for (int i =0; i < numrows; ++i){
            for(int j =0; j < numcols; ++j)
                printf("%d ", mat[i][j]);
            printf("\n");
        }
    }
    
    void mat_free (int **mat, const int numrows)
    {
        for (int i = 0; i < numrows; i++)
            free (mat[i]);      /* free rows */
        free (mat);             /* free pointers */
    }
    
    int main (void) {
    
        int numrows = 3;
        int numcols = 4;
        int **mat = malloc (numrows * sizeof *mat);
    
        for (int i = 0; i < numrows; ++i) {
            mat[i] = malloc (numcols * sizeof *mat[i]);
            for (int j = 0; j < numcols; ++j)
                mat[i][j] = (i +1) * (j+1);
        }
        const2dprinter ((int const * const *)mat, numrows, numcols);
        mat_free (mat, numrows);
    }
    
    $. /bin/mat_const_int_2d
    1 2 3 4
    2 4 6 8
    3 6 9 12