//bind 函数定义
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//函数调用
bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
& 符号用于定义引用类型的变量。引用是一个别名,可以让变量被多个名称引用。引用类型的变量在函数调用时可以直接传递原始变量的地址,避免了变量复制的开销,并且能够让函数直接修改原始变量的值。
当进行指针传递的时候,
形参(函数定义的时候)是指针变量。
实参(函数调用的时候)是一个变量的地址或者是指针变量。
调用函数的时候,形参指向实参的地址。
指针传递中,函数体内可以通过形参指针 改变实参地址空间的内容。
若采用指针传递的方式,我们在函数定义和函数声明时使用 * 来修饰形参,表示这个变量是指针类型。
在进行函数调用时,使用 & 来修饰实参,表示是将该变量的地址作为参数传入函数。
引用传递可以看成在值传递的基础上,在函数定义和声明的形参变量前加一个 <font color = red face >& ,其它的使用和值传递完全相同,因此也看出引用传递更加方便(在函数调用时,直接给变量就行,和值传递一样,不需要任何修饰符)。
值传递
形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入,不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。
引用传递
形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
指针传递
形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作
class ConveyPoint{
public:
void convey1(int num);
void convey2(int &num);
void convey3(int *num);
};
void ConveyPoint::convey1(int num) {
cout<<"值传递--函数操作地址 "<< &num <<endl;
num++;
}
void ConveyPoint::convey2(int &num) {
cout<<"引用传递--函数操作地址 "<< &num <<endl;
num++;
}
void ConveyPoint::convey3(int *num) {
cout<<"指针传递--函数操作地址 "<< num <<endl;
*num = *num+1;
}
ConveyPoint cp;
int n = 10;
cp.convey1(n);
cout<<"after change1() num="<<n<<endl;
cp.convey2(n);
cout<<"after change2() num="<<n<<endl;
cp.convey3(&n);
cout<<"after change3() num="<<n<<endl;
函数内部修改参数并且希望改动影响调用者。对比指针/引用传递可以将改变由形参“传给”实参(实际上就是直接在实参的内存上修改,不像值传递将实参的值拷贝到另外的内存地址中才修改)。
另外一种用法是:当一个函数实际需要返回多个值,而只能显式返回一个值时,可以将另外需要返回的变量以指针/引用传递给函数,这样在函数内部修改并且返回后,调用者可以拿到被修改过后的变量,相当于一个隐式的返回值传递。
参考文章
[1] https://blog.csdn.net/qq_34201858/article/details/104161539 C++函数参数中&和*的意义
[2] https://www.cnblogs.com/yanlingyin/archive/2011/12/07/2278961.html C++ 值传递、指针传递、引用传递详解