C 为什么我能';t传递类型为'的参数;字符*常量*';对于预期为';常量字符*常量*';正如它所说';谁的论点?

C 为什么我能';t传递类型为'的参数;字符*常量*';对于预期为';常量字符*常量*';正如它所说';谁的论点?,c,C,我正在编写一个函数,使用fork和execv替换项目中的system()和popen()。 我发现,尽管execv不会更改命令数组的内容,但它将其第二个参数声明为char*const argv[],这实际上可以更改char*的内容。因此,我决定像这样声明我的函数:int execute\u cmd(const char*const cmd[])这样,指向char的指针都是const,而指向const的内容都是const(很抱歉,我知道这个状态很混乱,但我尝试了) 然而,当我这样称呼它时: voi

我正在编写一个函数,使用fork和execv替换项目中的system()和popen()。
我发现,尽管execv不会更改命令数组的内容,但它将其第二个参数声明为char*const argv[],这实际上可以更改char*的内容。因此,我决定像这样声明我的函数:
int execute\u cmd(const char*const cmd[])
这样,指向char的指针都是const,而指向const的内容都是const(很抱歉,我知道这个状态很混乱,但我尝试了) 然而,当我这样称呼它时:

void execute_cmd(const char* const cmd[])
{
    for (int i = 0; cmd[i]; i++)
    {
        printf("%s ", cmd[i]);
    }
}

int main()
{
    char* const cmd[] = {"ls", "-al", 0};
    execute_cmd(cmd);
    return 0;
}
有一个complie错误是这样说的:

test.c:21:警告:从 不兼容的指针类型

test.c:10:注意:应为“const char*const*”,但参数为 键入“char*const*”

我想知道为什么会发生这种情况,因为带有常量的形式参数可以将非常量变量作为其实际参数,例如:

void printInt(const int);
//which can call like this
int a=10;
printInt(a);
我认为用非常量变量初始化常量变量是很常见的,那么为什么这个函数可以工作,而我的execute_cmd()却不能呢?我是否错过了与常量有关的重要内容? 我搜索过“char*const*和const char*const*”和“const formal argument with non-const actual parameter”这样的东西,但还没有得到非常有用的东西,如果有人能给我一个关于这个问题的正确关键工作的想法,我将不胜感激。 我不是以英语为母语的人,所以如果有语法问题,请原谅我

我想知道为什么会发生这种情况,因为带有
const
的形式参数可以将非const变量作为它的实际参数

这更像是“具有
const
的形式参数可以将非
const
变量作为其实际参数。”

类似于“指向常量字符的常量指针数组”

是“指向字符的常量指针数组”

注意数组元素的类型不同:
constchar*
char*
相比

简单代码也有同样的问题:“应为'char*',但参数的类型为'const char*'”


此外,
cmd
数组元素的类型应为
const char*
,以防止写入字符串文字


尝试
char*const cmd[]={“ls”,“al”,0}
“实际上可以更改char*”的内容-->代码不应该尝试更改
“ls”
,等等@chux是的,它是
char*const cmd[]
,我写错了。您混淆了顶级
const
,例如
const int
,在指向的对象上使用
常量
,例如
char const*
。相对于指针星号的位置至关重要。正确的做法是,不能将一个表示不会修改指向对象的指针传递给一个声明自己使用可能会修改的指针的函数。剩下的只是如何解决坏的
const
-API或C本身的正确性的问题。@chux告诉post最小化代码可能会导致问题。而真正的gcc的消息“简单代码有同样的问题”代码示例是离题的。OP清楚地意识到不能将常量分配给非常量;问题是关于相反的方向。我认为你答案的第二部分是迄今为止最好的建议:如果可能的话,让一切都保持稳定。
void foo(char *bob);
const char *alice = "Alice";

// Bad, as `foo()` needs to be able to write `*bob`, yet alice point to `const` data.
foo(alice);  
    // char* const cmd[] = {"ls", "-al", 0};
    const char* const cmd[] = {"ls", "-al", 0};