将非常量值传递给C中采用常量参数的函数的正确方法是什么

将非常量值传递给C中采用常量参数的函数的正确方法是什么,c,arrays,function,pointers,constants,C,Arrays,Function,Pointers,Constants,我制作了一个函数,用于打印一组数组以进行测试。因为我不想修改函数本身的任何内容,所以我认为最好为函数定义一个常量值和常量指针 void test_print(const char*** const array); /*Some code*/ void test_print(const char*** const command_array){ int j=0; while(command_array[j]!=NULL){ int k=0; w

我制作了一个函数,用于打印一组数组以进行测试。因为我不想修改函数本身的任何内容,所以我认为最好为函数定义一个常量值和常量指针

void test_print(const char*** const array);

/*Some code*/


void test_print(const char*** const command_array){
    int j=0;
    while(command_array[j]!=NULL){
        int k=0;
        while(command_array[j][k]!=NULL){
            printf("%s and %d\n",(command_array[j][k]),j);
            ++k;
        }
        ++j;
    }
}
但是,如果我不通过如下方式强制转换数组来调用函数:

test_print((const char*** const)command_array);
然后我得到一个错误:

invalid conversion from 'char***' to 'const char***'

所以我的问题是:我是在做正确的事情,还是有其他的方法来实现这种转换?是否说此强制转换只会使数组在函数中保持常量?

将命令数组强制转换为
常量字符***常量实际上并不安全

考虑以下代码:

void test_print(const char*** const command_array) { // command_array is a constant pointer to a non-constant pointer to a non-constant pointer to a constant char // we can easily change one of the non-constant levels **command_array = "Hello"; } void fail() { char command[6] = "hello"; char *level1 = command; char **level2 = &level1; char ***level3 = &level2; ***level3 = 'j'; // valid; now command holds "jello" test_print((const char*** const)level3); ***level3 = 'z'; // segfault! } 无效测试打印(常量字符***常量命令数组) { //命令数组是指向非常量指针的常量指针,指向常量字符的非常量指针 //我们可以很容易地改变其中一个非恒定的水平 **命令\u array=“Hello”; } 无效失败() { char命令[6]=“你好”; char*level1=命令; 字符**level2=&level1; 字符***level3=&level2; ***level3='j';//有效;现在命令保存“jello” 测试打印((常量字符***常量)级别3); ***level3='z';//segfault! } 我相信(这意味着我还没有测试过)const char*const*const*const
是安全的,尽管仍然没有隐式转换


最后一个
常量
也是不必要的-
常量字符*常量*常量*
常量字符*常量*常量
在这里要小心。编译器可能会为“const”字段生成细微不同的目标代码


“const”也是告诉优化器值永远不会改变的一种方式。抛出某些可能改变的东西可能会误导编译器,产生不可预知的结果,尤其是当你是多线程环境时。

它可以在C++中隐式转换(到<代码> char const * const *const */COD>),但不是在C.,我认为这是C标准的疏忽。所以函数定义应该是这样的:test_print(const char*const*const*const*command_数组)?不,在最后一件事上有一个额外的
const*
,你能解释一下为什么:const char*const*const*与const char*const*const*const*相同吗?对我来说,在第一种情况下,某些东西必须是非常量的……这是有区别的,但调用方看不到它——请看,编译器并不认为常量对象永远不会更改,只是不允许代码更改它。