关于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& ...
随机推荐
- spring框架中的@Import注解
spring框架中的@Import注解 Spring框架中的@Import注解 在之前的文章中,作者介绍了Spring JavaConfig. 这是除了使用传统的XML文件之外,spring带来的新的 ...
- SpringCloudConfig与SpringCloudEureka 注册中心与配置中心高可用的意义
所有的配置会缓存在本地,远程配置中心DOWN机,不影响本地使用,只是无法重新请求服务端获取配置的更新. 不管是注册中心的高可用,还是配置中心的高可用.本质上都是保证服务能注册上去或者能从配置中心获取配 ...
- Java初始化顺序(静态变量、静态初始化块、实例变量、实例初始化块、构造方法)
1.执行顺序 1.1.一个类中的初始化顺序 类内容(静态变量.静态初始化块) => 实例内容(变量.初始化块.构造器) 1.2.两个具有继承关系类的初始化顺序 父类的(静态变量.静态初始化块)= ...
- Android studio 3+版本apk安装失败问题
studio2.3升级到3.1之后将apk发给别人下载到手机上安装,华为提示安装包无效或与操作系统不兼容,魅族提示apk仅为测试版,要求下载正式版安装. 在网上找了一下,发现是studio3.0之后的 ...
- R语言学习笔记 (入门知识)
R免费使用:统计工具:# 注释,行注释块注释:anything="这是注释的内容"常用R语言编辑器:Rsutdio,Tinn-R,Eclipse+StatET:中文会有乱码帮助:? ...
- [hadoop读书笔记] 第十五章 sqoop1.4.6小实验 - 数据在mysq和hdfs之间的相互转换
P573 从mysql导入数据到hdfs 第一步:在mysql中创建待导入的数据 1.创建数据库并允许所有用户访问该数据库 mysql -h 192.168.200.250 -u root -p CR ...
- 原创:XXX公司-基于SAP的库存管理系统解决方案
XXX公司-基于SAP的库存管理系统 解决方案 版本:V0.3.0 Excel_Cortan 文件状态: [ ] 草稿 [ ] 正式发布 [√] 正在修改 文件标识: 当前版本: V0.3 作 者 ...
- SQL Server 连接远程服务器
最近要用到sqlserver,将本地的数据更新到远端的sqlserver时,希望能够查看远端sqlserver数据变化. 下载Microsoft SQL Server Management Studi ...
- Git -- 远程仓库简介
到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了. 可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Gi ...
- IE8不支持数组的indexOf方法
在IE8下有个js错误,但是在其它浏览器下(Firefox, Chrome, IE9)下面都很正常.后来调试发现原因是在IE8下,js数组没有indexOf方法. 在使用indexOf方法前,执行一下 ...