双指针函数参数什么时候需要加 const,什么时候不能加?

来源:互联网 发布:淘宝买家秀福利网站 编辑:程序博客网 时间:2024/05/21 12:49

我的理解是:如果函数的目的是修改输入参数代表的指针的值,则加 const 更安全;如果函数的目的是为了修改输入字符数组的内容,就不能加 const。

测试代码:

#include <stdio.h>#include <string.h> void parameter_no_qualifier_const_is_to_modify_chararray_contents(char** p_array);void test__parameter_no_qualifier_const_is_to_modify_chararray_contents(); void parameter_with_qualifier_const_is_to_modify_pointer_value(const char** pp);void test__parameter_with_qualifier_const_is_to_modify_pointer_value(); int main(){    test__parameter_no_qualifier_const_is_to_modify_chararray_contents();     test__parameter_with_qualifier_const_is_to_modify_pointer_value();     return 0;  } void parameter_no_qualifier_const_is_to_modify_chararray_contents(char** p_array){    // 如果函数参数形式为 const char** p_array,则下面紧跟的行会编译出错:    //   error C2440: “初始化”: 无法从“const char *”转换为“char *”    char* array = *p_array;    *array++ = 'c';    *array++ = 'h';    *array++ = 'i';    *array++ = 'j';    *array++ = 'k';    *array = '\0';     // 或,以下面的方式改变数组各元素的值。     // 如果函数参数形式为 const char** p_array,则下面 4 行都会编译出错:    //     error C3892: “p_array”: 不能给常量赋值    // (*p_array)[0] = 'c';    // (*p_array)[1] = 'h';    // (*p_array)[2] = 'i';    // (*p_array)[3] = 'j';    // (*p_array)[4] = 'k';    // (*p_array)[5] = '\0';     // (*p_array)++;} void test__parameter_no_qualifier_const_is_to_modify_chararray_contents(){    char array[10] = {'a', 'e', 'f', '\0', 'x', 'y', 'z', '\0'};    printf("%s\r\n", array); // aef     char* p_array = array;    parameter_no_qualifier_const_is_to_modify_chararray_contents(&p_array);    printf("%s\r\n\r\n", array); // chijk} void parameter_with_qualifier_const_is_to_modify_pointer_value(const char** pp){    // pp 的类型是 const char**,即 char const**,非常量。因函数参数是按值传递,所以内部修改不影响原值。    // *pp 的类型是 const char*,即 char const*,非常量。函数内部可间接修改之。    // **pp 的类型是 const char,即 char const,常量。编译器禁止修改其值。     (*pp)++;    // **pp = 'Q'; // error C3892: “pp”: 不能给常量赋值} void test__parameter_with_qualifier_const_is_to_modify_pointer_value(){    char* p = "AXY";      printf("%s\r\n", p); // AXY     // error C2664: “parameter_use_qualifier_const_is_to_modify_pointer_value”: 不能将参数 1 从“char **”转换为“const char **”    // parameter_with_qualifier_const_is_to_modify_pointer_value(&p);     // 可编译通过的 C 风格强制类型转换    parameter_with_qualifier_const_is_to_modify_pointer_value((const char**)&p);    printf("%s\r\n\r\n", p); // XY      char* p2 = "axy";      printf("%s\r\n", p2); // axy     // 等价且正确的 C++ 风格强制类型转换是用:const_cast    parameter_with_qualifier_const_is_to_modify_pointer_value(const_cast<const char**>(&p2));    printf("%s\r\n\r\n", p2); // xy      // char* p3 = "axy";    // error C2440: “static_cast”: 无法从“char **”转换为“const char **”      // parameter_with_qualifier_const_is_to_modify_pointer_value(static_cast<const char**>(&p3));      // char* p4 = "axy";      // error C2680: “const char **”: dynamic_cast 的目标类型无效    // parameter_with_qualifier_const_is_to_modify_pointer_value(dynamic_cast<const char**>(&p4));      // char* p5 = "axy";    // error C2440: “reinterpret_cast”: 无法从“char **”转换为“const char **”    // parameter_with_qualifier_const_is_to_modify_pointer_value(reinterpret_cast<const char**>(&p5));      // 如果是 char ()[],而不是 char*。那么,。。。     char p6[] = "DXY";      printf("%s\r\n", p6); // DXY     // error C2664: “parameter_with_qualifier_const_is_to_modify_pointer_value”: 不能将参数 1 从“char (*)[4]”转换为“const char **”    // parameter_with_qualifier_const_is_to_modify_pointer_value(&p6);     // 输入参数是数组情况下,还想修改指针的值,向上面那样就不行了(数组名的值是不能被修改的)。    // 可编译通过的 C 风格强制类型转换    parameter_with_qualifier_const_is_to_modify_pointer_value((const char**)(&p6));    printf("%s\r\n\r\n", p6); // EXY (?因为:'E' = 'D' + 1)      // 正确的做法是:    char* p6_ = p6;    printf("%s\r\n", p6_); // EXY      parameter_with_qualifier_const_is_to_modify_pointer_value((const char**)(&p6_));    printf("%s\r\n\r\n", p6_); // XY        // char p7[] = "dxy";    // error C2440: “const_cast”: 无法从“char (*)[4]”转换为“const char **”    // parameter_with_qualifier_const_is_to_modify_pointer_value(const_cast<const char**>(&p7));      // char p8[] = "dxy";    // error C2440: “static_cast”: 无法从“char (*)[4]”转换为“const char **”    // parameter_with_qualifier_const_is_to_modify_pointer_value(static_cast<const char**>(&p8));      // char p9[] = "dxy";    // error C2680: “const char **”: dynamic_cast 的目标类型无效    // parameter_with_qualifier_const_is_to_modify_pointer_value(dynamic_cast<const char**>(&p9));      char p10[] = "dxy";      printf("%s\n", p10); // dxy     // 可编译通过但错误的 C++ 风格强制类型转换是用:reinterpret_cast    parameter_with_qualifier_const_is_to_modify_pointer_value(reinterpret_cast<const char**>(&p10));    printf("%s\n\n", p10); // exy (?因为:'e' = 'd' + 1)      char* p10_ = p10;      printf("%s\n", p10_); // exy    parameter_with_qualifier_const_is_to_modify_pointer_value(const_cast<const char**>(&p10_));    printf("%s\n\n", p10_); // xy}

原创粉丝点击