c - 为什么将main()参数转换为const

时间:2014-10-14 05:21:52

标签: c pointers const

(我是C的初学者,也许我的问题不是很聪明,但在我问之前我确实谷歌了。)

我在git源代码中看到了以下代码:

int main(int argc, char **av) {
    const char **argv = (const char **) av;
    // ... more code ...
}

它将 char ** av 转换为 const char ** argv ,我认为这意味着使参数不可变,但我写了一个程序并发现两者都< strong> argv 和 argv [i] 是可变的。

问题1 :目的是什么&amp;那段代码的优点?

问题2 :const指针的行为是什么?我做谷歌但没有找到一个好的答案。


@Update

我根据答案测试更多,似乎 argv [i] [j] 是不可变的,但 argv argv [i] < / strong>是可变的。

因此指针上的const使原始值不可变,但指针本身仍然是可变的。

因此我猜git代码的主要目的也是为了防止改变原始参数。

测试代码

#include <stdio.h>

int main(int argc, char * av[]) {
    // modify value pointed by a non-const pointer - ok
    av[0][0] = 'h';
    printf("argv[0] = %s\n", av[0]);

    // modify const pointer itself - ok
    const char **argv = (const char **) av;
    argv[0] = "fake";
    printf("argv[0] = %s\n", argv[0]);
    char *arr[] = {"how", "are", "you"};
    argv = (const char **)arr;
    printf("argv[0] = %s\n", argv[0]);


    // modify the value itself which is pointed by a const pointer - bad, an error will be thrown,
    /*
    argv[0][0] = 'x';
    printf("argv[0] = %s\n", argv[0]);
     */

    return 0;
}

目前的代码可以编译&amp;在没有警告或错误的情况下运行,但是如果在结束时取消注释2个注释行,则在编译时会抛出以下错误:

  

错误:分配只读位置'** argv'

2 个答案:

答案 0 :(得分:3)

1)以后使用const指针访问参数确实没有意义,除了确保它们不被更改。

2)const指针的目的是确保它们不会在整个代码中被更改。你可以没有它们,但它有助于避免错误。

答案 1 :(得分:2)

在实践中,它在这里不是很有用(如果编译器是optimizing,生成的代码不会有太大变化。)

但是,argv不可变,因此编译器会将错误视为错误,如

argv[1][0] = '_'; // wrong

无法分配const件事物。因此无法分配const指针,指向const的指针意味着解除引用的指针是无法分配的位置。 (你可以混合使用:const指向const

BTW,main  - 标准C99 - 是一个非常特殊的功能。你不能以任意方式声明它(它几乎总是应该被声明为int main(int, char**)int main(void) ....)并且你可能无法调用它(例如它不能被递归),但这可能是不同的C和C ++。因此声明int main (int, const char**)将是非法的。