参数中,值传递、指针传递、引用传递的区别

值传递:
形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参),赋值完毕后实参就和形参没有任何联系。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。

#include<stdio.h>    //值传递示例
void swap(int a,int b)
{   //拷贝临时变量 
	int temp=a; 
	a=b;
	b=temp;
};  //函数调用后a和b的值进没有达到交换目的 
int main()
{ 
	int a=1, b=2;
	swap(a,b);
	printf("a=%d,b=%d", a, b);
    //输出结果a=1,b=2,a和b的值没有改变
	return 0;
}

指针传递:
形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。为什么说传地址也是一种传值呢?因为传地址是把实参地址的拷贝传递给形参。还是一句话,传地址就是把实参的地址复制给形参,复制完毕后实参的地址和形参的地址没有任何联系。那么在函数内改变指针指向,并不能影响函数外的指针实例。但是在函数里改变指针所指向的变量的值时,主函数实参指针所指向的变量的值会改变。

#include<stdio.h>    //指针传递示例
void swap(int *a,int *b)
{     //int *是一个整体,表明变量类型是指针
    int temp=*a;
    *a=*b;
    *b=temp;
}
int main(){
   int x=1, y=2;
   swap(&x,&y);
   printf("x=%d,y=%d",x, y);
   //输出x=2,y=1, x和y的值改变了
}

引用传递:
&表示引用实参,即代表形参是实参的一个别名。操作引用变量就是操作实参变量。这是C++语法写法,标准C是不支持这种写法的。

在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

#include<stdio.h>    //引用传递示例
void swap(int &a,int &b)
{   
	int temp=a; 
	a=b;
	b=temp;
};  //函数调用后a和b的值进行了交换 
int main()
{ 
	int a=1, b=2;
	swap(a,b);
	printf("a=%d,b=%d", a, b);
    //输出a=2,b=1, a和b的值改变了 
	return 0;
}

引用和指针的区别:

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用初始化后不能改变指向。使用时,引用更加安全,指针更加灵活。

  作者:wxquare  来源:知乎

  1. 初始化。引用必须初始化,且初始化之后不能呢改变;指针可以不必初始化,且指针可以改变所指的对象
  2. 空值。指针可以指向空值,不存在指向空值的引用。当引用或者指针作为参数传递的时候,拿到一个引用的时候,是不需要判断引用是否为空的,而拿到一个指针的时候,我们则需要判断它是否为空。这点经常在判断函数参数是否有效的时候使用。
  3. 引用和指针指向一个对象时,引用的创建和销毁不会调用类的拷贝构造函数和析构函数。delete一个指针会调用该对象的析构函数,注意防止二次析构。
  4. 引用和指针与const。存在常量指针和常量引用指针,表示指向的对象是常量,不能通过指针或者常量修改常量;存在指针常量,不存在引用常量,因为引用本身不能修改指向的特性和与指针常量的特性相同,不需要引用常量。
  5. 函数参数传递时使用指针或者引用的效果是相同的,都是简洁操作主调函数中的相关变量,当时引用会更加的安全,因为指针一些修改指向,将不能影响主调函数中的相关变量。所以参数传递时尽可能使用引用。
  6. sizeof引用的时候是对象的大小,sizeof指针是指针本身的大小。
  7. 引用和指针的实现是相同的,“引用只是一个别名,不会占内存空间”的说法是错误的,实际上引用也会再用内存空间。

猜你喜欢

转载自blog.csdn.net/weixin_42467709/article/details/81093423
今日推荐