当前位置: 首页 > news >正文

网站建设公司网站模版源码网站

网站建设公司网站模版,源码网站,xampp 做网站,wordpress有插件我们都知道,如果想在函数中修改实参的值,那么,你传递给函数的应该是这个值的地址。如果你想修改的是个指针,那么是传递指针的地址(二级指针),还是传递该指针呢? 1. C语言中的函数调…

我们都知道,如果想在函数中修改实参的值,那么,你传递给函数的应该是这个值的地址。如果你想修改的是个指针,那么是传递指针的地址(二级指针),还是传递该指针呢?

1. C语言中的函数调用

讲之前,先弄清楚一些概念:主调函数,被调函数,实参,形参。

void fun(int p)				// p 是形参,是在fun()内使用的形式参数
{p = 12}void fun2(int *parray)				// p 是形参,是在fun()内使用的形式参数
{parray[3] = 5;
}int main(void)
{int num = 0;int array[10] = { 0 };fun(num);				// main()是主调函数,主动调用fun()// fun()是被调函数,被main()调用// num 是实参,是main()传递给fun()的实际参数fun2(array);return 0;
}

C函数的所有参数均以“传值调用”的方式进行传递,这意味着函数将获得参数的一份拷贝,这也就是为什么很多初学者在刚学习函数的,企图修改形参值不成功的原因。(没错,就是我。。。)就是这样一个机制,保证了函数可以随心所欲的修改形参,而不会担心改变了形参的值。

如果实参是个数组名,并在被调函数内部使用间接运算符(*)或者是下标([ ])修改形参的数组元素,那么实际上修改的是实参的元素。被调函数将直接访问主调函数中所传递的数组,并不会对数组进行复制。这个行为叫做”传址调用”。

数组做实参的这种行为似乎和传值调用规则相悖。但并不是这样,首先,地址就是一串数字,只是标记了内存中的某个位置,而指针所存储的就是这串数字。本例中,假设数组array的地址是0x112233,由于数组名是个指针,传递给被调函数的是这个指针的一个拷贝,且根据传值调用,所以被调函数fun2() 的形参 parray 的值也是0x112233,而学过指针都知道,运用数组名的下标运算,可以改变数组中的某个值,所以在被调函数fun2()中,将数组的第四个元素修改了,而实参和形参指向的为同一块地址(均以0x112233开始,长度为10*sizeof(int)),所以数组array内的值就在被调函数中被修改了。

2. 被调函数修改指针所指向的值

让我们重新写一个小例子,添加打印,查看被调函数是如何修改实参的。

void fun(int *p)
{printf("p address:%p\n", p);*p = 12;
}int main(void)
{int num = 2;printf("num address:%p\n", &num);fun(&num);return 0;
}

运行:
在这里插入图片描述
可以看到&num 和 p指向都是num的位置,所以形参p可以在被调函数中修改num的值。

这次换数组试试。

void fun(int *p)
{printf("p address:%p\n", p);p[3] = 12;
}int main(void)
{int array[10] = { 0 };printf("array address:%p\n", array);fun(array);return 0;
}

运行:
在这里插入图片描述
指向地址相同,与上面同理。

3. 被调函数修改指针的值

之前的例子,都是修改指针所指向位置的值,这次我们来修改指针。

void fun(int *p)
{printf("p address:%p\n", p);p = (int *)malloc(sizeof(int));printf("p address:%p\n", p);
}int main(void)
{int *ptmp = NULL;printf("ptmp address:%p\n", ptmp);fun(ptmp);printf("ptmp address:%p\n", ptmp);*ptmp = 15;free(ptmp);return 0;
}

插入断点,开始运行:
在这里插入图片描述

好,接着运行:
在这里插入图片描述
程序在这里挂掉了,分析一下。
根据之前的例子,我们知道被调函数传指针,形参和实参指向同一块内存。本例中,ptmp 初始值为NULL,也就是0x000000,所以刚传入fun()时,p也为NULL。接下来动态分配空间,p指向了一块不为NULL的地址。跳出函数,发现ptmp仍然为NULL,接着间接运算符对NULL进行运算,所以程序宕掉。

那为什么这次没有修改实参的值?其实文章开头给的几个例子,都是通过传递指针,来修改指针所指向空间,我们得到的结论是这种方法是可行的。那么来看这个例子,ptmp 指向NULL,fun()通过拷贝ptmp ,使p也指向NULL,随后malloc分配内存,p选择不指向NULL,转为指向新分配的内存(这个负心的p),虽然p在一顿操作,但是这一切都跟ptmp无关,你又没有改变ptmp的指向,所以ptmp依旧为NULL。
在这里插入图片描述
此外,由于p是局部变量,函数结束他的生命周期就结束了(活该!!!)唯一指向malloc分配内存的指针找不到了,导致没有显式的释放这块内存,造成内存泄漏。
所以得出结论:想在被调函数中修改一级指针的指向(包括malloc新内存或者free已有内存),传入一级指针是不可行的。

那么如何修改指针的值(指向)呢?简单,传二级指针就行了
由于是测试,就没写参数检测了,不过实战的时候参数检测是很重要的

void fun(int **p)
{printf("p address:%p\n", p);printf("*p address:%p\n\n", *p);*p = (int *)malloc(sizeof(int));printf("p address:%p\n", p);printf("*p address:%p\n\n", *p);
}void funfree(int **p)
{printf("p address:%p\n", p);printf("*p address:%p\n\n", *p);free(*p);*p = NULL;printf("p address:%p\n", p);printf("*p address:%p\n\n", *p);
}int main(void)
{int *ptmp = NULL;printf("ptmp address:%p\n", ptmp);printf("&ptmp address:%p\n\n", &ptmp);fun(&ptmp);printf("ptmp address:%p\n", ptmp);printf("&ptmp address:%p\n\n", &ptmp);funfree(&ptmp);return 0;
}

运行结果:
在这里插入图片描述
从结果上看,传递二级指针为实参,来修改一级指针的值是可行的。这个例子对于链表的创建和释放很有帮助,可以传递链表头的地址(二级指针)来进行创建和释放链表,就不需要再用返回值的方式。

4. 总结

一句话:
想在被调函数修改0级指针的值,实参传递1级指针,
想在被调函数修改1级指针的值,实参传递2级指针,
想在被调函数修改2级指针的值,实参传递3级指针,
想在被调函数修改3级指针的值,实参传递4级指针,

在这里插入图片描述

http://www.lbrq.cn/news/2591461.html

相关文章:

  • w网站链接如何做脚注济南百度
  • 网站域名备案注销西安网站关键词推广
  • 政务服务网站建设情况汇报中国网络营销网
  • 信阳专业做网站公司看网站搜索什么关键词
  • 网站建设制作流程跨境电商平台有哪些
  • 做网站要执照吗推广app赚佣金平台
  • 花垣做网站win7优化
  • 潍坊网站建设优化排名网站推广的概念
  • 哪里学做网站莱阳seo外包
  • 百度网页首页哪家公司做推广优化好
  • 专业网站建设怎么样嘉兴优化公司
  • 安吉城乡建设局网站免费域名注册查询
  • 怎么在网上注册自己的网站推广平台有哪些
  • 网站的毕业设计怎么做公司网站seo外包
  • 一个人做网站 没有人写文章怎么办网络营销典型案例
  • 狼们求个没封的免费网站公司网站设计
  • 交友征婚婚恋网站系统php+mysql.rar百度爱采购优化软件
  • 房山区网站建设百度网站打不开
  • 广东像一起做网店的网站百度竞价规则
  • 网站建设工作室发展今天重大新闻
  • 建设银行人力资源系统网站怎么进如何设计网站步骤
  • 做古建的那些网站比较适合宁波seo外包费用
  • 网站建设 中怎么样建网站
  • 揭阳做淘宝批发拿货什么网站网站建设方案书
  • 龙岩 网站建设广东新闻今日大件事
  • 网站建设的对比分析东莞有限公司seo
  • 网站备案主体注销百度浏览器官网入口
  • 网站的经费预算优化模型数学建模
  • 第八章 电子商务网站建设试题技能培训网站
  • 东莞免费做网站公司郑州网站顾问热狗网
  • 2.4- WPF中非 UI 线程上安全地更新 UI 控件方法
  • 京东商品详情API技术文档框架及Python实现方案
  • Timer实现定时调度的原理是什么?
  • kafka与其他消息队列(如 RabbitMQ, ActiveMQ)相比,有什么优缺点?
  • 基于图像识别与分类的中国蛇类识别系统
  • i Battery Box V3.7 客户端电池检测仪