双指针函数参数什么时候需要加 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}
- 双指针函数参数什么时候需要加 const,什么时候不能加?
- getElementsByClassName什么时候加[0];
- angularjs里 什么时候加{{}} 什么时候不用?
- javascript调用函数时什么时候加括号,什么时候不用加括号
- scala的无参函数什么时候加括号,什么时候不加括号
- 什么时候需要虚析构函数
- 什么时候需要虚析构函数
- 什么时候需要虚析构函数
- 什么时候需要些析构函数
- 在函数前面什么时候该加static修饰
- 什么时候需要删除由函数返回的指针
- 函数在什么时候需要“引用”类型的参数
- matlab命令中什么时候加分号
- 函数入口参数加const的问题
- 什么时候不能使用箭头函数
- 什么时候在虚函数(接口)前面加“On”前缀表示事件?
- c++如下定义类函数后加冒号是什么意思 什么时候这么用
- 函数后加const
- AnimationListener
- 黑客教父透泄密危机:2012年爆发更大安全事故
- rvct3.1和ads1.2编译器兼容问题
- Hadoop集群安装 (5) 配置job queue_conf/mapred-queues.xml
- 展讯2012年产品、市场及业绩分析
- 双指针函数参数什么时候需要加 const,什么时候不能加?
- JSP操作MySQL基础
- Python中的 new-style class 及其实例详解
- 值得关注的开源Web应用项目
- 块设备体系结构分析
- Linux内存管理之slab机制(初始化)
- ZOJ2229 POJ1922 HDU1445 Ride to School
- 广东出入境444万用户信息被盗 公安厅证实漏洞
- scsi总线的初始化