一文搞懂指针,指针的指针,悬浮指针,野指针

学习C语言过程中,指针的概念往往是重难点,伴随着时隐时显的*,令人头晕。实际上指针并非如此复杂,掌握最基础概念,有利于我们更深刻的理解指针。

【百科概念】
指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。

【初识指针】

int p=9;

这段代码是非常基础的声明了一个整型变量p,并且赋予初始值为9。当我们在int 后的变量i前加“*”后,就会成为指针变量。

int *p=NULL;

虽然只是一个星号的差距,但本质却发生了巨大变化。int声明的并非i的数据类型,p也并非存储一个int数据类型的值。变量p实际存放的是一个内存“地址”,而int所声明的是这个地址对应内存里存储的数据类型。这点尤为重要,务必彻底搞懂,这是往下理解所必须的,而这里还有一点务必注意,此处的“ * ”属于声明这是一个指针的意思,并非取地址内容的“*”,不要搞混。

接下来将通过一段代码来探索指针的更多性质

    int i=9;printf("变量i的地址:0X%x\n",&i);int* p1=NULL;printf("指针p1自己的地址:0X%x\n",&p1);printf("指针p1存放的地址:0X%x\n",p1);p1=&i;printf("指针p1自己现在的地址:0X%x\n",&p1);printf("指针p1存放的地址:0X%x,指针p1存放的地址内的值:%d\n",p1,*p1);

“&”是一个取地址符,代码中,对指针p1的两种输出,“p1”“&p1” 是截然不同的。
直接打印p1将会得到p1实际存储的地址,这个地址起先因为赋予的NULL,所以是0,后面将变量i的地址给P1后,就变成了变量i的地址,运行代码可以发现,“p1”“&i” 的结果是一致的。

当打印“&p1”时,得到的将会是指针p1自身的地址。这里会有点容易混淆,一个指针怎么出现了两个地址?指针变量本身也是一种变量,也需要内存空间来存储一个值,只不过这个值不同于int,double,char等,而是一个代表特定内存位置的“门牌号”。所以针对指针p1我们确实可以得到两个地址,一个是自己的,一个是别人的

而地址与我们而言并没有太多的实际意义,我们关心的从来不是冰冷的地址字符串,而是他所对应内存中所存储的实际内容。基于这个需求,“*”又再次出现了。当我们打印 “*p1” 时,将会得到变量i的值。

同时还会注意到,对指针p1的不同赋值,并不会影响到“&p1”的结果,这其实是必然的,毕竟指针自己的地址是不会随着他所存储内容的变化而改变的,就像住房的地址不因入住人的改变而改变一样。
下面是上面代码的输出,不同机器,实际的地址是不同的。

变量i的地址:0Xefbff4fc
指针p1自己的地址:0Xefbff4f0
指针p1存放的地址:0X0
指针p1自己现在的地址:0Xefbff4f0
指针p1存放的地址:0Xefbff4fc,指针p1存放的地址内的值:9

对指针赋值时,如下两种方式,区别是什么呢?

int i=0;
int *p=&i;
//1
*p=5;
//2
p=5

代码1是对指针p所指向地址实际内容的修改,而代码2是对指针本身的修改,让他存储了一个新地址,实际上这样的赋值是非法的,应该是

p=&变量;
或
p=p2(p2是另一个指针)

【指针的指针】
指针的指针,顾名思义,是一个指针存放的地址是另外一个指针。实际上像一个“套娃”。他的声明形式是

int **p2=NULL;

如果你想定义一个指针的指针的指针

int ***p2=NULL;


以此类推,我们主要研究指针的指针,为他赋值:

int **p2=NULL;p2=&p1;

这里的p1是上文指向变量i的p1。
当有两个“*”时,我们还是逐层为他“脱衣”,看看会输出怎样的结果

 //定义指针的指针int **p2=NULL;p2=&p1;printf("p2自身的地址:0X%x,p2存放的地址:0X%x, p1指针存放的地址:0X%x,p2存放指针指向的地址实际的值:%d\n,",&p2,p2,*p2,**p2);

输出:

p2自身的地址:0Xefbff4e0,p2存放的地址:0Xefbff4f0, p1指针存放的地址:0Xefbff4fc,p2存放指针指向的地址实际的值:9

换句话说:

“&p2”是指针变量p2 自己 的地址。
“P2” 是p2存储的地址,这里等价于“&p1”
“*p2”是p1所存放的地址,等价于&i
“**p2”是p1存放地址对应内存实际的内容,等价于直接打印变量i

【野指针】
当一个指针未初始化时,他的指向是不确定并且危险的,所以称之为“野指针”,如下便是一个“野指针”

//野指针int *n;

【悬浮指针】
当一个指针指向的内存被释放时,却没有对指针赋NULL时,这个指针就是悬浮指针。试想别人昨天给了你一个住址,今天他家拆迁搬走了,但却没告诉你,而你明天去了会有怎样的结果!换到程序这里可能引起软件和系统的崩溃。
如下是一个悬浮指针:

//悬浮指针void *x=malloc(1024);free(x);

【指针简单应用】

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {// insert code here...int i=0;ChangeI(i);printf("(changeI)i的值:%d\n",i);}
void ChangeI(int i){i=123;
}

上面的输出是多少呢?答案是123.这当然是不对的!答案是0,因为实参与形参是不同的内存空间,函数参数的传递也仅仅只是值的传递。那要如何才能改变i呢?用指针即可!

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {// insert code here...int i=0;ChangeII(&i);printf("(changeII)i的值:%d\n",i);}
void ChangeII(int *i){*i=123;
}

上述结果就是123了。

一文搞懂指针,指针的指针,悬浮指针,野指针相关推荐

  1. ES6学习——一文搞懂ES6

    ES6学习--一文搞懂ES6 es6介绍 ES全称EcmaScript,是脚本语言的规范,而平时经常编写的EcmaScript的一种实现,所以ES新特性其实就是指JavaScript的新特性. 为什么 ...

  2. 一文搞懂 MySQL 索引

    一文搞懂 MySQL 索引 1.MySQL 索引 简介 1.1.MySQL 索引 是什么?  索引是一个单独的.存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针. 1.2. M ...

  3. 悬垂指针(Dangling pointer)和野指针(Wild pointer)

    转自:http://www.cnblogs.com/submarine/archive/2013/03/02/2940169.html 参看维基百科: Dangling pointer 迷途指针 == ...

  4. 一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  5. c6011取消对null指针的引用_C++中的野指针及其规避方法

    今天在调试程序过程中,用到了一些指针的方法,这里记录一下野指针的概念. 1.概念 野指针,也就是指向不可用内存区域的指针.通常对这种指针进行操作的话,将会使程序发生不可预知的错误. 野指针与空指针(N ...

  6. 一文搞懂 Python 的 import 机制

    一.前言 希望能够让读者一文搞懂 Python 的 import 机制 1.什么是 import 机制? 通常来讲,在一段 Python 代码中去执行引用另一个模块中的代码,就需要使用 Python ...

  7. python语言语句快的标记是什么_一文搞懂Python程序语句

    原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...

  8. 一文搞懂 Java 线程中断

    转载自   一文搞懂 Java 线程中断 在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程 ...

  9. 一文搞懂HMM(隐马尔可夫模型)-Viterbi algorithm

    ***一文搞懂HMM(隐马尔可夫模型)*** 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序, ...

最新文章

  1. 网络安全模型_基于TCM的网络安全访问模型
  2. jQuery - 设置内容和属性
  3. Shiro在SpringBoot中的应用
  4. hdu 3853 LOOPS 概率DP
  5. 查看运行时间_怎样查看自己电脑系统的版本信息?
  6. [react] Mern和Yeoman脚手架有什么区别?
  7. PostgreSQL的核心架构
  8. 扑捉和捕捉的区别照相_扑捉和捕捉的区别照相
  9. [CF671E] Organizing a Race
  10. mysql查询临时表是否存在_[转]SQL判断临时表是否存在
  11. php bc gmp,php中ipv6转纯数字和反转
  12. python random 之基础点名器
  13. ArcGIS制图(一)之流向图
  14. JAVA实现中点画线_Java 实现中点法画线
  15. 如何利用python中的pandas模块计算环比和同比
  16. igraph基本使用方法示例
  17. 智能管家---4.Log封装
  18. S7-1200PLC 与温控仪表Modbus RTU通信
  19. ThreadPoolExecutor(五)——线程池关闭相关操作
  20. python笔试题110题_吐血整理:110道python面试题(带答案)

热门文章

  1. Unity 多个Camera叠加显示
  2. dgl源码阅读笔记(3)——DeepWalk
  3. C++无法打开源文件
  4. 一个最大化条件概率问题
  5. 结合泛函极值_泛函极值与变分法
  6. 有向图邻接矩阵c语言编程,邻接矩阵有向图(一)之 C语言详解
  7. 2021年制冷与空调设备运行操作免费试题及制冷与空调设备运行操作考试试卷
  8. Internal Order内部订单
  9. 子域名扫描工具-Sublist3r
  10. 第31章 Python3 标准库概览教程