函数字传送值 复制代码 代码如下,你在你的房子做怎么着事都不会耳熟能详到小编

澳门新浦京8455com 2

传引用:类似于C语言的指针了,感觉差不多。打个比方,我有一橦房子,我给你一把钥匙,我们二个都可以进入这个房子,你在房子做什么都会影响到我。

哈哈,会用只是初级阶段,要了解原理是什么,这样才能更好去运用,费话不多说
传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用
:真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值
说明:
传值:根copy是一样的。打个比方,我有一橦房子,我给你建筑材料,你建了一个根我的房子一模一样的房子,你在你的房子做什么事都不会影响到我,我在我的房子里做什么事也不会影响到你,彼此独立。
传引用:让我想起了上大学时学习C语言的指针了,感觉差不多。打个比方,我有一橦房子,我给你一把钥匙,我们二个都可以进入这个房子,你在房子做什么都会影响到我。
一,php实例 1,传值 复制代码
代码如下: 2,传引用 复制代码 代码如下:
3,函数传值 复制代码 代码如下: ‘;
//显示为$param1==1 echo ‘
$param2==’.$param2.’
‘; //显示为$param2== 因为$param2是局部变量,所以不能影响全局 echo ‘
$param3==’.$param3.’
‘; //显示为$param3== 因为add方法没有返回值,所以$param3为空 ?>
4,函数传引用 复制代码 代码如下: ‘;
//显示为$param1==1 没对变量1进行操作 $param3=add;
//调用方法add,并将变量1的引用传给变量2 echo ‘
$param1==’.$param1.’
‘; //显示为$param1==3
调用变量过程中,$param2的改变影响变量1,虽然没有return echo ‘
$param2==’.$param2.’
澳门新浦京8455com,’; //显示为$param2== 因为$param2局部变量,所以不能影响全局 echo ‘
$param3==’.$param3.’
‘; //显示为$param3== 如果把方法里面的return注释去掉的话就为$param3==3
?> 5,函数传引用2 复制代码 代码如下:
‘; //显示为$param3==2 echo ‘
$param4==’.$param4.’
‘; //显示为$param4==2 echo ‘
$param1==’.$param1.’
‘; //显示为$param1==2 调用变量过程中,$param2的改变影响变量1 $param3++;
/*下面显示为$param1==3,这是因为$param2和$param1引用到同一个地方, *
返回值前面加了地址符号还是一个引用$param3=&add; *
这样$param3,$param2和$param1引用到同一个地方,当$param3++;时, *
$param1会被改变*/ echo ‘
$param1==’.$param1.’
‘; $param4++; /*
下面显示为$param1==3,这里为什么是3而不是4呢,这是因为返回值前面没有 *
地址符号,它不是一个引用所以当$param4改变时不会影响$param1*/ echo ‘
$param1==’.$param1.’
‘; ?>
哈哈,不过我觉得传引用会好一点,耗的资源少。上面测试没有明显的差距,可能是因为测试数据不够大造成的,如果有更大数据来测试,我想会有明显的不同。

函数传指针与引用

           
由于在今天编程的时候遇到一个小小的问题,这个问是虽然小,但是闲扰了我一整天的时间——注意,是一整天!

  废话不多说,先给出一段代码

    

// 二叉树的建立.cpp : 定义控制台应用程序的入口点。//#include <iostream>using namespace std;//定义二叉排序树的节点typedef struct Node{   int data;   struct Node * lchild;//左孩子   struct Node * rchild;//右孩子}Node,* PNode;PNode T=NULL;//二叉排序树的根节点//中序遍历二叉树void MidSequence(PNode t){   if(t!=NULL)   {      MidSequence(t->lchild);    cout<<t->data<<" ";    MidSequence(t->rchild);   }}//往二叉排序树中插入一个新节点(递归实现)void  CreateBSortTree2(PNode & t,int data){  if(t==NULL)  {     //建立一个新节点     PNode p=(PNode)malloc(sizeof(Node));      p->data=data;      p->lchild=NULL;      p->rchild=NULL;    t=p;   return;  }  else if(t->data>data)     CreateBSortTree2(t->lchild,data);  else     CreateBSortTree2(t->rchild,data);}void insertNode(Node *root,int value){ if(root==NULL){         Node *node=(Node*)malloc(sizeof( Node));      node->data=value;       node->lchild=NULL;      node->rchild=NULL;      root=node;       return ;     }   if(root->data>value){      insertNode(root->lchild,value);   }   if(root->data<value){      insertNode(root->rchild,value);   }}//测试int main(){   int a[]={0,5,8,4,2,3,10};   int len=sizeof(a)/sizeof(int);    for(int i=0;i<len;i++)   {     //CreateBSortTree2(T,a[i]);     insertNode(T,a[i]);    }   std::cout<<T->rchild->data;     MidSequence(T); system("PAUSE");  return 0;}

上面代码的意思是写了两个二叉树插入的代码,一个是我写的:

void insertNode(Node *root,int value){  if(root==NULL){         Node *node=(Node*)malloc(sizeof( Node));      node->data=value;       node->lchild=NULL;      node->rchild=NULL;      root=node;       return ;     }   if(root->data>value){      insertNode(root->lchild,value);   }   if(root->data<value){      insertNode(root->rchild,value);   }}

上面这部分的代码是存在一定的问题的。不能按期望的结果把value值插入到二叉树中。

//往二叉排序树中插入一个新节点(递归实现)void  CreateBSortTree2(PNode & t,int data){  if(t==NULL)  {   //建立一个新节点     PNode p=(PNode)malloc(sizeof(Node));      p->data=data;      p->lchild=NULL;      p->rchild=NULL;    t=p;   return;  }  else if(t->data>data)     CreateBSortTree2(t->lchild,data);  else     CreateBSortTree2(t->rchild,data);}

而上面的程序按预期的结果运行了。其实比较上面两段代码,我们可以发现,两段代码除了

void  CreateBSortTree2(PNode & t,int data)

void insertNode(Node* root,int value)

红色的部分外,其它的一模一样的。于是我们会问了,为什么会这样子?我们传的不是指针吗,只要是指针,不管在哪里

都可以改变原来的值吗?

嗯,是的,确实可以改变原来的值,因为它把原来值的地址传给你了嘛。。注意,这里传指针也就是将地址按值传过了,

你要知道C语言里面传值是坑人的复制一份的策诺。嗯。。。你确实可以改变函数外面的那个值,但关键是你得使用一个

解引用(*)的操作
也就是说,你得结合那个解引用的操作才行啊,,其它都是扯淡。

#include<iostream>void foo(int *a){ int b=10;  std::cout<<"b的值  "<<b<<std::endl;    //a=&b;     *a=b; } int main(){   int a=3;   foo(&a);     std::cout<<"a的值  "<<a<<std::endl;  }

澳门新浦京8455com 1

但是如果程序变成这样:、

#include<iostream>void foo(int *a){    int b=10;  std::cout<<"b的值            "<<b<<std::endl;      a=&b;      // *a=b; } int main(){  int a=3;   std::cout<<"函数运行前a的值  "<<a<<std::endl; foo(&a);     std::cout<<"函数运行后a的值  "<<a<<std::endl;  }

澳门新浦京8455com 2

看到没有,这里a的值可是没有半点改变呢。但是在函数里面我们可是改变了它的地址啊。。。

void foo(int *a){

int b=10;

std::cout<<"b的值 "<<b<<std::endl;

a=&b;

// *a=b;

}

这里传入叁数的时候,确实是将a的地址变成了b的地址。

但是前面说过,传指针其实就是将地址传值嘛。

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(这里是在说实参指针本身的地址值不会变)

我们还是回到前面的问题,那为什么人家的代码可以呢?

//往二叉排序树中插入一个新节点(递归实现)void  CreateBSortTree2(PNode & t,int data){  if(t==NULL)  {      //建立一个新节点     PNode p=(PNode)malloc(sizeof(Node));      p->data=data;      p->lchild=NULL;      p->rchild=NULL;    t=p;   return;  }  else if(t->data>data)     CreateBSortTree2(t->lchild,data);  else     CreateBSortTree2(t->rchild,data);}

因为它传的是引用:

而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。

被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操

作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

来源: <>

 

来自为知笔记(Wiz)

以上就是本次介绍的全部相关知识点,感谢大家的学习和对脚本之家的支持。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图