(C++)函数参数传递中的一级指针和二级指针【【**】】
来源:互联网 发布:java导入jar包 编辑:程序博客网 时间:2024/05/01 12:57
主要内容:
1、一级指针和二级指针
2、函数指针传递的例子
3、什么时候需要传递二级指针?
4、二级指针在链表中的使用
1、一级指针和二级指针
一级指针:即我们一般说的指针,就是内存地址;
二级指针:指向指针的指针,就是地址的地址;
如:
int a=1;
int *p=&a; // p为a变量的地址,通过*p可以得到a的值
int **q=&p; // q为p指针的地址,通过**q可以得到a的值
2、函数指针传递的例子
程序1:
#include<stdio.h>
void
fun(
int
*p){
int
b=100;
p=&b;
}
int
main(){
int
a=10;
int
*q;
q=&a;
printf
(
"%d\n"
,*q);
fun(q);
printf
(
"%d\n"
,*q);
return
0;
}
运行结果:
10
10
程序2:
#include<stdio.h>
void
fun(
int
**p){
int
b=100;
*p=&b;
}
int
main(){
int
a=10;
int
*q;
q=&a;
printf
(
"%d\n"
,*q);
fun(&q);
printf
(
"%d\n"
,*q);
return
0;
}
运行结果:
10
100
程序3:
#include<stdio.h>
#include<stdlib.h>
void
myMalloc(
char
*s){
s=(
char
*)
malloc
(100);
}
int
main()
{
char
*p=NULL;
myMalloc(p);
if
(p==NULL)
printf
(
"P is not changed!\n"
);
else
{
printf
(
"P has been changed!\n"
);
free
(p);
}
return
0;
}
运行结果:
P is not changed!
程序4:
#include<stdio.h>
#include<stdlib.h>
void
myMalloc(
char
**s){
*s=(
char
*)
malloc
(100);
}
int
main()
{
char
*p=NULL;
myMalloc(&p);
if
(p==NULL)
printf
(
"P is not changed!\n"
);
else
{
printf
(
"P has been changed!\n"
);
free
(p);
}
return
0;
}
运行结果:
P has been changed!
3、什么时候需要传递二级指针?
通过上述例子,我们可以看到,在某些情况下,函数参数传递一级指针时,在函数体内对指针做变动,也不会对原始指针产生变化,而传递二级指针时,则可以,这是为什么呢?
在传递一级指针时,只有对指针所指向的内存变量做操作才是有效的;
在传递二级指针时,只有对指针的指向做改变才是有效的;
下面做简单的分析:
在函数传递参数时,编译器总会为每个函数参数制作一个副本,即拷贝;
例如:
void fun(int *p),指针参数p的副本为_p,编译器使_p=p,_p和p指向相同的内存空间,如果在函数内修改了_p所指向的内容,就会导致p的内容也做相应的改变;
但如果在函数内_p申请了新的内存空间或者指向其他内存空间,则_p指向了新的内存空间,而p依旧指向原来的内存空间,因此函数返回后p还是原来的p。
这样的话,不但没有实现功能,反而每次都申请新的内存空间,而又得不到释放,因为没有将该内存空间的地址传递出来,容易造成内存泄露。
void fun(int **p),如果函数参数是指针的地址,则可以通过该参数p将新分配或新指向的内存地址传递出来,这样就实现了有效的指针操作。
如果觉得二级指针比较难理解,也可以通过函数返回值的形式来传递动态内存(切记不能返回栈内存),如:
#include<stdio.h>
#include<stdlib.h>
char
* myMalloc(){
char
*s=(
char
*)
malloc
(100);
return
s;
}
int
main()
{
char
*p=NULL;
p=myMalloc();
if
(p==NULL)
printf
(
"P is not changed!\n"
);
else
{
printf
(
"P has been changed\n"
);
free
(p);
}
return
0;
}
知道了上述这些,就不难理解上面四个小程序的执行结果了。
4、二级指针在链表中的使用
在链表或者树的操作中,也需要用到二级指针,
比如创建链表的头指针:
在初始化链表函数中,传入头指针,并在函数中为该指针分配空间,此时就应该使用二级指针,如void initLinklist(Node **head);
而在添加删除结点的过程中,我们并没有改变函数参数指针的指向,而是通过传入的指针如Node *head,找到要删除结点的位置,并未对该指针做改变,因此退出函数后,该指针无影响。
- (C++)函数参数传递中的一级指针和二级指针【【**】】
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 函数参数的传递问题(一级指针和二级指针)
- 一级指针域二级指针的函数参数传递
- C++一级指针和二级指针做参数传递讲解
- c语言中一级指针和二级指针做函数参数
- 一级指针还是二级指针作函数参数(2)
- C++ 中的二级指针 和 一级指针
- C语言一级指针、二级指针、数组作为参数传递需要注意的若干问题
- 一级指针和二级指针
- 一级指针和二级指针
- 一级指针还是二级指针作函数参数
- Android Studio之基本Gradle使用
- 如何使用FL Studio中的时间标记
- java开发操作系统:进程间的消息通讯
- 获取手机的分辨率
- Excel-001 常用公式汇总
- (C++)函数参数传递中的一级指针和二级指针【【**】】
- iClient for JavaScript---客户端统计专题图
- SQL号段整理
- AFNetWorking --- README
- sz、rz命令的使用
- PageRank
- java打开文件
- Hadoop2.7.3+Spark2.1.0完全分布式集群搭建过程
- strtoul函数注意点