C 如何将非常量动态多维数组传递给需要常量多维数组的函数?
我在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,…
我的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