C++中函数传参:指针与引用的区别及数组传参相关问题
嘿,咱们一个个来拆解你的问题,都是C++里指针和引用的经典坑点,搞懂了能少踩好多雷!
问题1:
function(char *something) 和 function(char &something) 的区别 这俩本质是指针和引用的差异,核心区别体现在这几个方面:
- 本质与绑定规则:
char *something是一个独立的指针变量,它存储的是某个char变量的内存地址。你可以随时修改这个指针的指向(比如让它转而指向另一个char),而且它可以被赋值为nullptr,也就是不指向任何有效内存。char &something是某个char变量的别名,它和原变量共享同一块内存空间。一旦绑定到某个变量后,就再也不能切换指向其他变量,而且引用必须初始化——你不能声明一个不绑定任何变量的空引用。
- 语法使用差异:
- 用指针时,要访问它指向的变量必须用解引用操作符
*,比如*something = 'a';;如果要修改指针本身的指向,直接赋值就行:something = &anotherChar;。 - 用引用时,直接操作引用名就等同于操作原变量,比如
something = 'a';,不需要额外的解引用步骤。
- 用指针时,要访问它指向的变量必须用解引用操作符
- 调用方式不同:
- 调用指针版本的函数,你需要传入一个char的地址,比如
function(&myChar);,或者直接传一个char*类型的变量。 - 调用引用版本的函数,直接传char变量本身即可:
function(myChar);,编译器会自动帮你完成引用绑定。
- 调用指针版本的函数,你需要传入一个char的地址,比如
问题2:字符数组传参的指针vs引用,以及同名参数的问题
先纠正一个小误区:你写的someFunction(char &arrayToManipulate) {}其实不是传数组引用的正确写法——这个参数是单个char的引用,而非数组的引用。数组的引用必须指定大小,正确写法是someFunction(char (&arrayToManipulate)[50]) {},这样编译器才会识别这是一个大小为50的char数组的引用。
两种传参方式的区别
- 指针传参(
char *arrayToManipulate):- 当你把数组名传给指针参数时,数组会自动退化为指向首元素的指针。这意味着函数内部无法直接获取数组的真实大小(用
sizeof(arrayToManipulate)得到的是指针本身的大小,不是数组的字节数)。 - 你可以在函数里修改指针的指向(比如
arrayToManipulate += 5;让它指向数组的第6个元素),但这种修改不会影响外部的数组名(因为数组名是常量指针,本身不可修改)。 - 优点是灵活,能接受任意大小的char数组,甚至是动态分配的char*内存。
- 当你把数组名传给指针参数时,数组会自动退化为指向首元素的指针。这意味着函数内部无法直接获取数组的真实大小(用
- 数组引用传参(
char (&arrayToManipulate)[50]):- 这种方式不会让数组退化,函数内部可以通过
sizeof(arrayToManipulate)直接获取数组的真实大小(也就是50*sizeof(char))。 - 你不能修改这个引用的“指向”(数组本身是固定大小的,引用绑定后也无法切换),但可以自由修改数组里的元素。
- 缺点是不够灵活,这个函数只能接受大小为50的char数组,其他大小的数组传进去会直接编译报错。
- 这种方式不会让数组退化,函数内部可以通过
同名参数的问题
当函数的形参和外部的数组同名时(比如你说的someFunction(char &arrayOfChars) {}),语法上完全没问题,但会存在作用域屏蔽的情况:
函数内部访问arrayOfChars时,会优先使用形参(函数的局部作用域),外部的同名数组会被暂时“隐藏”。举个例子:
char arrayOfChars[50] = "hello"; void someFunction(char (&arrayOfChars)[50]) { // 这里的arrayOfChars是外部数组的引用,修改它就是修改原数组 arrayOfChars[0] = 'H'; // 如果在这里定义同名局部变量,会进一步屏蔽形参 // char arrayOfChars = 'x'; 此时访问的是这个局部char变量 }
虽然不会报错,但逻辑上很容易混淆,不小心就会写出不符合预期的代码,所以一般不推荐用同名的形参。
内容的提问来源于stack exchange,提问作者aName




