你必须知道的指针基础-3.指针的移动及指针的危险
一、指针的移动
1.1 指针的向前及向后移动
指针每次加一就是指针向前移动指针类型对应的字节数。下面通过一个int指针来指向一个int数组,看看指针的加法运算到底是个什么鬼?
int nums[]={33,55,77,88,99};int* ptr = nums;printf("%d\n",*ptr);ptr++; // ptr是int类型的指针,所以向后移动4个字节printf("%d\n",*ptr);ptr+=2; // 向后移动2*4 个字节printf("%d\n",*ptr);
运行结果如下图所示:
可以看到,指针的加法就是向前移动指定类型字节数,在数组中就是指向下一个元素。
下面再来看看与加法相反的减法,仍然以上面的代码为例,新增一句:ptr--;
int nums[]={33,55,77,88,99};int* ptr = nums;printf("%d\n",*ptr);ptr++; // ptr是int类型的指针,所以向后移动4个字节printf("%d\n",*ptr);ptr+=2; // 向后移动2*4 个字节printf("%d\n",*ptr);ptr--;printf("%d\n",*ptr);
运行结果如下图所示:
可以看出,减法即代表向后移动指针类型对应的字节数。
1.2 char类型指针的移动
对于char类型的指针移动,实际就是指向下一个字符或上一个字符:
char s1[]="hello edisonchou.cn";char* p=s1;p=p+2; // char类型占一个字节,因此这里向后移动2*1个字节printf("%s\n",s1);printf("%s\n",p);
这里实现了一个类似于求子串的操作,运行结果如下图所示:
1.3 同类型指针的相减
同类型指针相减,得出的是相距的数据类型的长度。下面以两个指向同一个int数组的int类型指针为例,验证一下是否得到相距的数据类型的长度:
int nums[]={33,44,55,66,77};int* iP1=nums;int* iP2=nums;iP2=iP2+3; // 同类型指针相减得出的是相距的数据类型的长度printf("The distance is %d\n",iP2-iP1);
当iP2-iP3得到的是距离是3,这是因为iP2在进行减法操作之前已经向前移动了3个int类型的长度。
二、指针强大但又危险
2.1 从你家到他家
刚刚了解了指针的移动的强大,现在我们来看看指针的强大所带来的一些“危险”。例如下面一段代码,我们定义了两个int类型的整数。
int i1=555;int i2=666;int* p=&i1;printf("%d,%d\n",&i1,&i2);p--;int i3=*p; //从p当前指向的内存中取出4个字节,解释成i3printf("%d\n",i3);
在指针p的定义中,我们指向的是i1。而当我们对p指针进行减法运算移动时,我们发现当前p指针指向的居然不是i1而是i2了。这也就说明,本来声明指针时指向的是你家的地址,而当对指针进行运算操作后却指向了隔壁老王家的地址,这是搞什么鬼!
可以从运行结果图看出,i1和i2的地址分别为2686740和2686736(是连续的地址),p指针最开始指向的是i1。而当p向后移动之后,此时已经指向了i2。因此,输出的值为666。
2.2 内存访问越界
继续上面的例子,我们此时再将p指针向后移动,看看此时p指针所指向的内容的值是多少?当我们再把p指针向后移动99999位时,其所指向的内容的值又是多少?
int i1=555;int i2=666;int* p=&i1;printf("%d,%d\n",&i1,&i2);p--;int i3=*p; //从p当前指向的内存中取出4个字节,解释成i3printf("%d\n",i3);p--;printf("%d\n",*p);
当运行程序后,结果变为了下图:
那么,这个4200782地址是个什么鬼?它存放的又是什么内容?我们不得而知,这也是另一个程序里边某个变量所存储的位置,但现在在我们这个程序中居然通过指针访问到了!这是个可怕的事情!想想,当A程序中的指针通过移动取得了B程序中的内存地址或数据内容,再对指针对其修改数据,这是一件不安全的事儿!想想一帮苦逼程序员辛辛苦苦加班加点做的游戏,轻而易举地就被挂了外挂,本来需要用RMB才能买的积分或者道具让外挂直接给改了,是不是觉得人生已经没有意义啦?
下面一段代码则展示了,当指针移动的距离过大时,Windows系统会对此访问限制,程序直接报错。
p-=99999; //这个内存地址可能是无法访问的,又被称为访问越界//Windows对此做了访问越界的限制printf("%d\n",*p);
运行结果是,直接崩溃,弹出错误按钮:
错误框的出现,代表了指针使用不当的危害,会给客户造成一定时间的延迟服务。因此,指针虽然很强大,但是也很危险!
参考资料
如鹏网,《C语言也能干大事(第三版)》
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
你必须知道的指针基础-3.指针的移动及指针的危险相关推荐
- 【C语言学习】国嵌21__指针基础
2019独角兽企业重金招聘Python工程师标准>>> 一.指针基础 变量只是一段存储空间的别名,那么是不是必须通过这个别名才可以使用这段存储空间?答案是否定的.我们还可以通过指针也 ...
- C语言-第21课 - 指针基础
第21课 - 指针基础 口诀:加*符号变大门 变量回顾 既然程序中的变量只是一段储存空间的别名,那么是不是必须通过这个别名才能使用这段存储空间?我们看下面的例子: #include<stdio. ...
- C语言指针基础与深入
目录 1.指针定义 1.1指针定义 1.2'*'的含义 1.3'&'的含义 1.4'*'与'&'的联用,'*&'.'&*'是否相同 1.5'[ ]'的解引用功能 2.指 ...
- 【C语言】指针基础知识点汇总
指针(一) 基础 一 指针的概念 为了方便访问内存中的内容,给每个内存单元一个编号,我们称这个编号为地址,及为指针. 指针也是一种数据类型 所以指针都有自己的内存 存储的是地址(编号) 指针的四要素 ...
- 指针基础*p ;**pp
指针基础 目录: 1. 定义指针 2. 指针初始化 3.高阶指针(二级指针) 4.二级指针的本身与指向 5.区分char str[ ] = "abc" 与 char *str = ...
- C语言指针(基础篇)
文章目录 前言 一.指针与地址 1. 变量与内存 2. 地址与指针 3. 常量.变量.内存.地址.指针的关系 二.指针的基础操作 1.大端模式与小端模式 2. 指针的定义与初始化 2.1 指针的定义与 ...
- c语言中字符指针变量输入,C语言指针基础知识实例讲解
对程序进行编译的时候,系统会把变量分配在内存单位中,根据不同的变量类型,分配不同的字节大小.比如int整型变量分配4个字节,char字符型变量分配1个字节等等.被分配在内存的变量,可以通过地址去找到, ...
- 【笔记】简明C++指针基础总结
简明C++指针基础 文章目录 简明C++指针基础 1. 什么是指针? 内存单元的直接和间接访问 地址与指针 指针的主要用途 2. 变量与地址 定义指针变量 通过指针变量间接访问所指向的变量 3. 函数 ...
- C语言基础之10:数组和指针
Tips1: 关键字:static 运算符:&.*(一元) 如何创建并初始化数组 指针(在已学过的基础上). 指针和数组的关系 编写处理数组的函数 二维数组 Tips2: 人们通常借助计算机完 ...
- C语言指针基础知识点(六)--通过指针引用多维数组
指针系列目录 C语言指针基础知识点(一)–指针及指针变量 C语言指针基础知识点(二)–指针变量的引用 C语言指针基础知识点(三)–指针变量作为函数参数 C语言指针基础知识点(四)–通过 ...
最新文章
- FtpCopy数据定时自动备份软件(FTP定时备份)
- python各个解释器的用途-11 个优秀的 Python 编译器和解释器
- hdu4821 字符串hash
- 浮点数用大小端存储吗_干细胞存储有什么用,干细胞有必要存储吗
- Mongodb账号密码模式的基本认证
- 前端学习(2637):this
- oracle的awr日志,oracle 导出awr信息
- ASP脚本语言之vbscript用法
- linux操作系统基础与实训教程,清华大学出版社-图书详情-《Linux操作系统基础与实训教程》...
- 美的集团:董事长减持两千万股套现13亿属个人资产配置需要
- 【clickhouse】Code: 135. DB::Exception: Received from xxx:9000. DB::Exception: Indices in strings are
- coloros11跟Android,安卓10与安卓11究竟差异在哪里?我们拿这两台新机试了一下
- 阿里云物联网平台python开发手册_阿里云物联网平台之云端API调用(即云端开发教程)...
- python-常用模块-time、datetime模块
- 团队开发之个人博客一
- 「洛谷P1231」教辅的组成 解题报告
- JQuery WEUI Tabbar 的坑
- java执行bat代码
- 书剑中医电子处方软件 V16.0
- 关于音频芯片MICIN和LINEIN,HPOUT和OUT的区别