主要内容:

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将新分配或新指向的内存地址传递出来,这样就实现了有效的指针操作。

如果觉得二级指针比较难理解,也可以通过函数返回值的形式来传递动态内存(切记不能返回栈内存),如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#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++)函数参数传递中的一级指针和二级指针相关推荐

  1. 函数参数的传递问题(一级指针和二级指针)

    函数参数的传递问题(一级指针和二级指针) [转] 原以为自己对指针掌握了,却还是对这个问题不太明白.请教!   程序1:   void  myMalloc(char  *s)  //我想在函数中分配内 ...

  2. C语言:结构体中一级指针和二级指针的创建与释放示例

    http://blog.csdn.net/Bixiwen_liu/article/details/53610952 这几天把C语言巩固了一下,作为一门最基本的编程语言,C语言还是相当基础和非常重要的, ...

  3. 指针数组,数组指针,指针函数,函数指针,二级指针详解

    先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[ ...

  4. 【C基础】指针/指针运算/二级指针/函数指针

    指针定义: 指针是一种数据类型,使用它可以用来定义指针变量,指针变量中存储的其实是整数,这种整数代表了内存的编号. 指针的使用: 1.函数之间相独立,但有些时候需要共享变量.传参是值传递全局变量容易命 ...

  5. C++之指针探究(一):一级指针和二级指针

    一级指针: 例1: 运行结果:   二级指针(指向指针的指针)(二级指针存储着一级指针这个变量的地址): 例2: 运行结果: 例3:二级指针可改变一级指针的指向 运行结果: 附上例代码: //小问学编 ...

  6. 带你认识什么是一级指针、二级指针、三级指针

    今天带大家了解一下什么是一级指针.二级指针.三级指针 1.一级指针 一级指针其实就是我们平时常见的普通指针 如: int a = 12; int * b = &a; //一级指针,定义一个指针 ...

  7. Mybatis 中的一级缓存与二级缓存

    一,Mybatis中为什么要有缓存   缓存的意义是将用户经常查询的数据放入缓存(内存)中去,用户去查询数据的时候就不需要从磁盘(关系型数据库)中查询,直接从缓存中查询,从而提高了查询效率,解决了高并 ...

  8. 深入理解指针以及二级指针(指针的指针)

    前言:本文将讲解指针的定义.指针变量和普通变量的本质区别.一级指针和二级指针的关系以及如何通过二级指针修改一级指针所指向的内存.文末还附加了两个实例,帮助读者加深对二级指针的理解.本文试图通过图表的方 ...

  9. 对指针的详细认识(一)—— 指针概念+指针类型+野指针+指针运算+二级指针

    文章目录 指针是什么? 指针的定义 指针的大小 指针类型 指针有哪些类型? 指针类型有什么意义? 野指针 野指针的成因 如何避免野指针 指针运算 指针+-整数 指针-指针 指针的关系运算 二级指针 指 ...

最新文章

  1. 中国量子计算原型机 九章 问世 | AI日报
  2. ssh 免密码登录(设置后仍需输密码的原因及解决方法)
  3. jquery中ajax请求后台数据成功后既不执行success也不执行error解决方法
  4. 深度linux安装双,Deepin 20正式发布,新的外观和感觉,双内核安装
  5. python横坐标如何显示为月份_如何显示给定两个日期之间的所有月份?
  6. JMetro版本11.5.10和8.5.10发布
  7. 逆置/反转单链表(C语言)
  8. 交换系统可以在计算机网络应用吗,数据通信交换技术在计算机网络中的应用
  9. cassandra学习笔记四
  10. Ubuntu16.04源码安装postgresql-9.6.6数据库
  11. 程序员应该收藏哪些资讯类网站
  12. ArcGIS Server(详细介绍)转
  13. 服务器搬迁方案_医院机房迁移细则规范 amp; 机房搬迁实施规划方案
  14. Atitit 架构的艺术 目录 1. 按照技术站分类 1 1.1. LAMP架构,到IOE架构,再到分布式架构 1 1.2. Ssh ssm 1 2. Bs cs web hybrid架构 1 3.
  15. 获取浏览器地址栏字符串参数
  16. [Devcpp]为Devc自定义编译器及Devcpp路径读取的Bug
  17. PDF文件编辑并去除水印
  18. Unity | 实现粘贴、复制功能
  19. 前端JS时间验证,结束时间不早于开始时间
  20. 第二章 基本放大电路

热门文章

  1. winform中openfiledialog过滤压缩文件格式_什么是最佳图像格式?不同的文件格式及其特点...
  2. python内置作用域_python内置金融数据Python 五点搞定作用域
  3. 步步深入:MySQL架构总览-gt;查询执行流程-gt;SQL解析顺序
  4. Spring Boot结合spring-data-jpa
  5. 【最新合集】PAT甲级最优题解(题解+解析+代码)
  6. 设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是Li, 1<= i<= n。这n 个程序的读取概率分别是p1,p2,...,pn,且pi+p2+...+pn =
  7. ssh连接出现:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
  8. 在jsp页面实现保存登录用户名和密码
  9. Minigui及lgui使用全解释
  10. php双层foreach,php 双层foreach 如何提升效率