要想了解参数传递,首先得了解参数变量,参数变量常见的表示实现有int & x、int* x、int x、int** x等。
1、int& x表示:int&表示引用类型,x表示引用变量名,引用类型不会开辟新的地址空间,只是传递参数的别名。
2、int* x表示: int*表示整数指针类型,x表示指针变量名,指针类型会开辟新的地址空间,x存储新开辟的地址空间,*x表示新开辟的地址空间存储的值。
3、int x表示:int表示整数类型,x表示整型变量名,整数类型会开辟新的地址空间,x存储整数值,&x表示存储整数值的地址空间。
4、int ** x表示:int**表示整数二级指针,x表示指针表量名。指针类型会开辟新的地址空间,x存储一级指针的地址空间,*x表示一级指针,存储二级指针的地址空间,
**x表示二级指针,存储整数值。
参数传递包括地址传递和值传递,地址传递又包括引用传递和指针传递。通过下面的例子来看看他们的区别:
void funy(int& x)
{
std::cout<<" funy1=地址:"<<&x<<";地址存的值:"<<x<<std::endl;
x = 3;
std::cout<<" funy2=地址:"<<&x<<";地址存的值:"<<x<<std::endl;
int *y = &x;
*y = 8;
std::cout<<" funy3=地址:"<<y<<";地址存的值:"<<*y<<std::endl;
}
void funp (int* x)
{
std::cout<<" funp1=地址:"<<x<<";地址存的值:"<<*x<<std::endl;
*x = 3;
std::cout<<" funp2=地址:"<<x<<";地址存的值:"<<*x<<std::endl;
std::cout<<" funp3=地址:"<<&x<<";地址存的值:"<<x<<std::endl;
}
void funv (int x)
{
std::cout<<" funv1=地址:"<<&x<<";地址存的值:"<<x<<std::endl;
x = 8;
std::cout<<" funv2=地址:"<<&x<<";地址存的值:"<<x<<std::endl;
}
int main(int argc, char** argv)
{
// 引用传递
int x1 = 1;
std::cout<<"\nfuny=地址:"<<&x1<<";地址存的值:"<<x1<<std::endl;
funy(x1);
std::cout<<"funy=地址:"<<&x1<<";地址存的值:"<<x1<<std::endl;
// 指针传递
int x2 = 2;
std::cout<<"\nfunp=地址:"<<&x2<<";地址存的值:"<<x2<<std::endl;
funp(&x2);
std::cout<<"funp=地址:"<<&x2<<";地址存的值:"<<x2<<std::endl;
// 值传递
int x3 = 3;
std::cout<<"\nfunv=地址:"<<&x3<<";地址存的值:"<<x3<<std::endl;
funv(x3);
std::cout<<"funv=地址:"<<&x3<<";地址存的值:"<<x3<<std::endl;
}
运行结果:
funy=地址:0x7fff5fbfe5ac;地址存的值:1
funy1=地址:0x7fff5fbfe5ac;地址存的值:1
funy2=地址:0x7fff5fbfe5ac;地址存的值:3
funy3=地址:0x7fff5fbfe5ac;地址存的值:8
funy=地址:0x7fff5fbfe5ac;地址存的值:8
funp=地址:0x7fff5fbfe5a8;地址存的值:2
funp1=地址:0x7fff5fbfe5a8;地址存的值:2
funp2=地址:0x7fff5fbfe5a8;地址存的值:3
funp3=地址:0x7fff5fbfdab8;地址存的值:0x7fff5fbfe5a8
funp=地址:0x7fff5fbfe5a8;地址存的值:3
funv=地址:0x7fff5fbfe5a4;地址存的值:3
funv1=地址:0x7fff5fbfdacc;地址存的值:3
funv2=地址:0x7fff5fbfdacc;地址存的值:8
funv=地址:0x7fff5fbfe5a4;地址存的值:3
通过结果,我们可以看到:
1、*加变量,此变量必须存储的是地址,则得到此地址存储的值;
2、&加变量,则得到存放此变量的地址。
3、变量x1和函数funy里参数x是同一个地址,因此改变x的值,x1的值也发生变化。参数x,前面的int&类型,表明x是一个引用类型,不会开辟新地址空间,只是变量x1的别名,就是说x和x1是同一个变量。这就是引用传递。
4、变量x2和和函数funp里参数x不是同一个地址,x2的地址是0x7fff5fbfe5a8,x的地址是0x7fff5fbfdab8,变量x存储的值是x2的地址,可通过*x去改变变量x2地址存储的值。x2和x是两个不同变量。这就是指针传递。
5、变量x3和函数funv里参数x不是同一个地址,参数传递时,只是将变量x3存储的值赋值给变量x,通过变量x,无法得到变量x3的地址,也就无法改变变量x3的值。x3和x是两个不同变量。这就是值传递。
6、可以看到引用传递和指针传递,有些类似的作用;但它们各有优点,引用传递不会生成新的变量,节省空间,但是不能传NULL,而指针传递会产生新的变量,但可以传NULL。