关于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& ...
随机推荐
- Java设计模式(2)单态模式(Singleton模式)
定义:Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作. 还有,singleton能够被状态化 ...
- C# .NET - Sql Bulk Insert from multiple delimited Textfile using c#.net
SqlBulkCopy.WriteToServer has 4 overloads:SqlBulkCopy.WriteToServer (DataRow[]) Copies all rows f ...
- 遍历QMap引发异常处理
引言 用常规方法遍历QMap,删除满足条件元素时出现“读取位置0xXXX时发生访问冲突”.查看“调用堆栈”指向QMap<int,int>::iterator::operator++()和Q ...
- C++标准转换运算符static_cast
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性. 中文名 暂无 外文名 static_cast 分 类 强制类型转换 类 型 C++ s ...
- soapui-groovy脚本中文乱码及符号乱码、响应乱码解决方案
groovy脚本中文乱码及符号乱码,解决方案: 响应乱码解决方案:
- 根据URL获取参数值得出json结果集,对外给一个接口让别人调用
背景:测试接口的时候,经常都是后端get\post请求直接返回json结果集,很想知道实现方式,虽然心中也大概了解如何实现,但还不如自己来一遍踏实! 先来看一下结果吧: 以下对一个web的get接口进 ...
- Tomcat 的 DefaultServlet
问题描述: 群里有人测试 Spring MVC,没有配置任何Controller,只配置了一个view resolver,指定了前缀后缀. 然后,他问的是 当访问 localhost:8080/tes ...
- 详细的Log4j使用教程
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...
- (转)在SDL工程中让SDL_ttf渲染汉字
有时候在关于SDL的博文中看到一些评论,说SDL对中文的支持不佳,因为当程序涉及中文时总是输出乱码. 照我个人观点,这里面很多都是误解.下面就根据我在windows下使用SDL的情况,说说我的观点. ...
- Java之ReentrantLock公平锁和非公平锁
在Java的ReentrantLock构造函数中提供了两种锁:创建公平锁和非公平锁(默认).代码如下: public ReentrantLock() { sync = new NonfairSync( ...