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

十八、指针

目录

1.指针是什么?

2.指针类型

3.野指针

4.如何规避野指针

5.指针运算

6.指针和数组

7.二级指针

8.指针数组

1.指针是什么?
 

指针理解的2个要点:

  1. 指针是内存中一个最小单元的编号,也就是地址。
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量。

总结:指针就是地址,口语中说的指针通常指的是指针变量。

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址 。

总结:指针变量是用来存放地址的,地址是唯一标示一块地址空间的。

指针的大小在32位平台是4个字节,在64位平台是8个字节。

2.指针类型

x86 - 32位的环境

x64 - 64位的环境

结论:指针类型决定了指针在被解引用的时候访问几个字节

如果是int*的指针,解引用访问4个字节

如果是char*的指针,解引用访问1个字节

推广其他类型

如果是double*的指针,解引用访问8个字节

结论:指针的类型决定了指针+-1操作的时候,跳过几个字节

决定指针的步长

指针指向的是首地址,4个字节,但是如果是double可以向后访问8个字节。

指针的类型决定了指针能访问几个字节。

3.野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
1.指针为初始化

int* p;

*p=10; //非法访问内存,这里的p就是野指针。

p没有初始化,就意味着没有明确的指向。

一个局部变量指针未初始化,放的是随机值:0xccccccc
2.指针越界访问

当指针指向的范围超出数组arr的范围时,p就是野指针。

3.指针指向的空间释放

a将地址串到*p但是,return &a,之后a就销毁了,但是地址传到*p,*p在去访问这个地址时,不能使用这块空间。

如果空间没有被覆盖,还是能访问到原来的数值。

4.如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放即时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性

int* p2=NULL;//NULL ->0

等价于 int a=0;

//*p2=100//err

NULL是0,0地址是不能访问的,

5.指针运算

*vp++ 和 (*vp)++ 区别

*vp++ -> *vp; vp++; //地址++

(*vp)++; //是对指向的对象++。

1.指针+-整数

    int arr[10] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//数组下标的写法for ( i = 0; i < sz; i++){arr[i] = 1;}
    int arr[10] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//指针int* p = arr;for ( i = 0; i < sz; i++){*p = 1;p++;}
    int arr[10] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//与上面效果一样int* p = arr;for ( i = 0; i < sz; i++){*(p + i) = 1;}

2.指针-指针

| 指针-指针 | 得到的是指针之间元素的个数

不是所有的指针都能相减,指向同一块空间的2个指针才能相减!

地址+地址? 没有意义

3.指针的关系运算

实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
也就是可以往后越界比较,不允许往前越界比较。

6.指针和数组

arr[i] -->*(arr+i)

7.二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?

这就是二级指针

pa就是一级指针变量

ppa就是二级指针变量

二级指针是用来存放一级指针变量的地址

8.指针数组

指针数组是指针还是数组?

答案:是数组。是存放指针的数组。

数组我们已经知道整形数组,字符数组。
 

parr[0]就相当于arr1,可以把parr[0][j]理解为arr1[j]

arr[i]就等价于 *(arr+i)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux下如何设置系统定时任务
  • 鸿蒙 next 5.0 版本页面跳转传参 接受参数 ,,接受的时候 要先定义接受参数的类型, 代码可以直接CV使用 [教程]
  • 神经网络之卷积神经网络
  • 运维锅总浅析Kubernetes之Ceph
  • DVWA的安装和使用
  • CTF ssrf 基础入门 (一)
  • android audio 相机按键音:(一)资源加载与替换
  • 使用RedisTemplate操作executePipelined
  • 【系统架构设计 每日一问】四 如何对关系型数据库及NoSql数据库选型
  • 第十章 软件工程
  • MongoDB教程(十八):MongoDB MapReduce
  • 对递归的一些理解。力扣206题:翻转链表
  • 细说网络安全五家龙头企业,你去过哪一家?
  • SkyWalking入门搭建【apache-skywalking-apm-10.0.0】
  • 二、QGroundControl开发环境搭建
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • C# 免费离线人脸识别 2.0 Demo
  • Fastjson的基本使用方法大全
  • JAVA_NIO系列——Channel和Buffer详解
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • mysql 5.6 原生Online DDL解析
  • MySQL主从复制读写分离及奇怪的问题
  • PHP的类修饰符与访问修饰符
  • socket.io+express实现聊天室的思考(三)
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • Webpack 4x 之路 ( 四 )
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 力扣(LeetCode)22
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 使用Swoole加速Laravel(正式环境中)
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • python最赚钱的4个方向,你最心动的是哪个?
  • 阿里云ACE认证学习知识点梳理
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​MySQL主从复制一致性检测
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #Datawhale X 李宏毅苹果书 AI夏令营#3.13.2局部极小值与鞍点批量和动量
  • #include
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (9)目标检测_SSD的原理
  • (LeetCode 49)Anagrams
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (多级缓存)缓存同步
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (汇总)os模块以及shutil模块对文件的操作
  • (十三)Maven插件解析运行机制
  • (四)进入MySQL 【事务】
  • (转) 深度模型优化性能 调参
  • *2 echo、printf、mkdir命令的应用
  • .cfg\.dat\.mak(持续补充)