一.值传递:
形参是实参的拷贝,修改形参的值不会改变外部实参的值。从被调用函数的角度来说,值传递是单向的,参数的值只能传入,不能传出。当函数内部需要修改参数的值,但并不希望这个改变影响调用者时,采用值传递。
例
void function(int x)
{
x = 5;
printf("x=%d\n",x); //输出x=5
}
int main(int argc, char *argv[])
{
int a = 3;
function(a); //值传递
printf("a=%d\n",a); //输出a=3 函数调用后 a的值不变
}
通过调试可以发现a和x的内存地址不一样,地址存放的内容一样(&a和&x不同)。
二.指针传递
例
void function(int *x)
{
*x = 5;
printf("x=%d\n",*x); //输出x=5
}
int main(int argc, char *argv[])
{
int a = 3;
function(&a); //值传递
printf("a=%d\n",a); //输出a=5 函数调用后 a的值改变了
}
通过调试发现,a的内存地址和x的值一样(&a和x的值一样 a和*x的值一样),修改x指向的内容,a存放的内容也随之改变。
三.引用传递
例
void function(int &x)
{
x = 5;
printf("x=%d\n",x); //输出x=5
}
int main(int argc, char *argv[])
{
int a = 3;
function(a); //值传递
printf("a=%d\n",a); //输出a=5 函数调用后 a的值改变了
}
通过调试发现,a和x的内存地址一样(&a和&x的内容一样),改变x的值,a的内容也改变了。
指针传递和引用传递一般适于:函数内部修改参数并希望改动影响调用者。对比值传递,指针传递和引用传递可以将改变由形参传递给实参(实际上就是直接在实参的内存上修改,不像值传递将实参的值拷贝到另外的内存地址中才修改)。指针传递和引用传递的另外一种用法是:当一个函数实际吸引返回多个值,而只能显示返回一个值时,可以将另外需要返回的变量以指针或引用的方式传递给函数,这样在函数内部修改并返回后,调用者可以拿到被修改后的变量,也相当于一个隐式的返回值传递吧。
四.指针传递和引用传递的区别
从概念上讲,指针从本质上就是存放变量地址的一个变量,逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向地址存放的内容的改变。而引用是一个别名,它逻辑上是不独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象再起整个生命周期是不能被改变的(自始至终只能依附于同一个变量)。
从函数参数传递方式来说,指针传递和引用传递也有本质上的区别:
指针传递本质上是值传递的方式,它所传递的是一个地址。值传递过程中,被调函数的形参作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进了的实参的值,这个值可以是实参的地址,形成实参的一个副本。值传递的特点是被调用函数的形参的任何操作都是作为局部变量进行,实参指针的地址不会变。
例
void function(int *x)
{
int y = 5;
x = &y; //修改x的内容
*x = 10; //修改x指向的内容
printf("x=%d\n",*x); //输出x=10
}
int main(int argc, char *argv[])
{
int a = 3;
function(&a); //值传递
printf("a=%d\n",a); //输出a=3 函数调用后 a的值不变
}
在被调函数内部,形参改为指向被调函数局部变量的地址,所以修改x的内容不会影响实参的值
在引用传递的过程,被调函数的形参虽然也作为局部变量在栈中开辟的内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正式因为如此,被调函数对形参做的任何操作都影响了形参。
五. char*的传递
例
void function(char* x)
{
x = "bbb";
printf("x=%s\n",x); //输出bbb
}
int main(int argc, char *argv[])
{
char* a = "aaa";
function(a); //这是值传递!
printf("a=%s\n",a); //输出aaa
}
形参x有独立的内存地址,内容是a内容的拷贝,修改形参x的内容不会改变实参a的内容
正确的方法如下
例
void function(char** x)
{
*x = "bbb";
printf("x=%s\n",*x); //输出bbb
}
int main(int argc, char *argv[])
{
char* a = "aaa";
function(&a); //这是值传递!
printf("a=%s\n",a); //输出bbb
}