关于C中函数传参的一点理解
一般来说c传值分为传值与传指针,Java里没有指针,因此只有传值,但是Java里传值分为简单变量传值和引用型变量传值,从本质上来说这两者没啥区别。
下面主要说的是传参时对原变量的影响:
最初练习创建单链表时可能会有这样一种写法:
void Creat_link_list(int n,struct node *head){ }
n是单链表节点的个数,head被初始化为null,调用该函数后可能会有人直接对head进行各种操作,比如遍历,排序。但此时head依然为null,函数内的一列操作只是head副本的操作,当函数调用结束后这个副本也就被系统释放了,对此这里一般有两种改法:
(1):
struct node *Creat_link_list(int n,struct node *head){
..........
..........
return head;
}
可以直接将函数里的head返回,这是一种非常重要的方法,特别是在递归代码中,这种写法很常见
(2):
void Creat_link_list(int n,struct node * &head){ }
采用引用传参,c++里采用的一种传参方式,形参与实参共用一个内存单元,对形参进行操作,实参自然也受到影响,一般来说这是一种很好也可以用来偷懒的方法(o(╯□╰)o)。
接下来大家可以看看严书里关于二叉排序树的删除操作:
特别是删除的关健操作:
void Delete(BiNode *&p){
if(p->rchild==NULL){
struct BiNode *q;
q=p;
p=p->lchild;
free(q);
}
else if(p->lchild==NULL)
{
struct BiNode *q;
q=p;
p=p->rchild;
free(q);
}
else{
struct BiNode *q,*s;
q=p;
s=p->lchild;
while(s->rchild){
q=s;
s=s->rchild;
}
p->data=s->data;
if(q!=p)
q->rchild=s->lchild;
else
q->lchild=s->lchild;
free(s);
}
}
删除核心代码:
q=p;
p=p->rchild;
free(q);
这与平时对单链表的删除操作明显有区别,没有找到前驱节点,而直接将指向当前节点的指针指向下一个节点,这种写法一般来说是错误的,但因为这里采用的引用传参,保证了删除操作的正确性。
比如删除单链表中所有偶数节点的操作:
void Delete_even(struct node *&head){
struct node *q,*tmp;
tmp=head;
while(tmp->next){
if(tmp->next->res%2==0)
{
q=tmp->next;
tmp->next=q->next;
free(q);
}
else
tmp=tmp->next;
}
}
依然是先找先找前驱节点。
这里给出一种不找到前驱节点的方法,依然是采用引用传参和递归。
void DeleteNode(struct node* &p){
struct node *q;
q=p;
p=p->next;
free(q);
} void DeleteBFS(struct node * &p,int key){
if(p->data==key){
DeleteNode(p);
return ;
}
else
DeleteBFS(p->next,key);
}
总的来说,遇到指针时,一般来说需要考虑的问题就是改变指针的指向或者是改变指针所指向的内容(o(╯□╰)o)。
关于C中函数传参的一点理解的更多相关文章
- js中函数传参的情况
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 验证python中函数传参是引用传递
定义: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...
- [js]js中函数传参判断
1,通过|| function fun(x,y){ x=x||0; y=y||1; alert(x+y); } fun(); 2.通过undefined对比 function fun(x,y){ if ...
- python中给函数传参是传值还是传引用
首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...
- C语言 指针在函数传参中的使用
int add(int a, int b) //函数传参的时候使用了int整型数据,本身是数值类型.实际调用该函数时,实参将自己拷贝一份,并将拷贝传递给形参进行运算.实参自己实际是不参与运算的.所 ...
- 在Java中动态传参调用Python脚本
最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称 ...
- C#篇(三)——函数传参之引用类型和值类型
首先应该认清楚在C#中只有两种类型: 1.引用类型(任何称为"类"的类型) 2.值类型(结构或枚举) 先来认识一下引用类型和值类型的区别: 函数传参之引用类型: 1.先来一个简单的 ...
- python函数传参是传值还是传引用?
首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...
- [Java]_函数传参的疑惑与思考
问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. void dfs(TreeNode node , int sum , ArrayList& ...
随机推荐
- Matlab——plot polyfit polyval
p=polyfit(x,y,m) 其中, x, y为已知数据点向量, 分别表示横,纵坐标, m为拟合多项式的次数, 结果返回m次拟合多项式系数, 从高次到低次存放在向量p中. y0=polyval(p ...
- [kafka] 001_kafka起步
一.简介 Kafka is a distributed, partitioned, replicated commit log service. It provides the functionali ...
- C++ 拷贝构造函数之const关键字
class Complex { public: //拷贝构造函数1 Complex(const Complex &c); //拷贝构造函数2 Complex(Complex &c); ...
- 《FPGA全程进阶---实战演练》第八章之程序架构格式说明
首先在书写程序时必须有的部分,就是模块module部分,整体的架构如图8.1所示. 图8.1 程序整体架构 首先要声明模块名,在module后面加上模块名,这里最好以所建立模块要实现的功能去命名此模块 ...
- linux下硬盘的分区:
提到硬盘的分区,以前就是很乱,有什么主分区/扩展分区/逻辑分区等;它们有什么区别呢?现在简单的了解一下: 由于在MBR的主引导记录中的分区表里面最多只能记录4个分区记录,这个不够用啊,为了解决这个问题 ...
- Json转换工具类(基于google的Gson和阿里的fastjson)
在项目之中我们经常会涉及到字符串和各种对象的转换,为此特地整理了一下常用的转换方法 一.基于com.google.code.gson封装的json转换工具类 1. 在pom.xml文件里面引入gson ...
- e859. 将键盘事件和字符串对应
The KeyStroke.toString() method does not return a string that can be parsed by KeyStroke.getKeyStrok ...
- python3两个字典的合并
两个字典的合并其实很简单,直接用dict的update即可,代码如下: # /usr/bin/python3 # -*- encoding: utf-8 -*- ", "" ...
- 使用Camera功能 AREA的理解
转至 http://blog.csdn.net/think_soft/article/details/7998478 使用Camera功能 大多数的Camera功能都是使用Camera.Paramet ...
- 使用appledoc 生成技术API文档具体解释
一. 首先安装 appledoc 第一步:使用终端命令进行下载安装 git clone git://github.com/tomaz/appledoc.git cd ./appledoc sudo s ...