| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> c语言的指针初阶总结 -> 正文阅读 |
|
[C++知识库]c语言的指针初阶总结 |
何为指针?指针是内存中一个最小单位(一个字节)的编号,也就是地址。而平时说的指针,指的是指针变量,是用来存放地址的变量,也可以说,存放在指针变量中的值都被当做地址处理。我们可以通过&(取地址操作符)取出变量的地址,并把这个地址存放到另一个变量中,这个变量就是指针变量,当然了,指针变量也有自己的地址。 如何编址? 如果是32位的机器,就会有32个二进制位来进行编址,那就会有个地址。每一个地址标示一个字节,但每一个地址本身大小却是4个字节的。 上述图的意思是,char类型的内存大小是1个字节,只用一个地址,而int类型的内存是4个字节,那么就会用4个连续的地址来标识,但取地址时会显示首地址。? 注:只是为了好画,变量内存的位置并不是挨着的,空几个取决于编译器。 指针类型既然指针变量的大小都一样,为什么指针变量还需要那么多种类型? 指针的类型决定了 1.该指针变量解引用操作能访问多少个字节(权限) char*类型的指针,解引用能访问1个字节 int*类型的指针,解引用能访问4个字节 double*类型的指针,解引用能访问8个字节的指针 2.该指针变量的步长(向前/向后走一步都有多大距离) char*类型的指针,指针名+1的意思是跳过一个字符,也就是往后走1个字节 int*类型的指针,指针名+1的意思是跳过一个整型,也就是往后走4个字节 double*类型的指针,指针名+1的意思是跳过一个double,也就是往后走8个字节
?但如果可以运行的话,就会发现,pa,pc的地址是一样,但pa+1的地址是在pa地址上+4,而pc+1是在pc地址上+1。 野指针野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的),比如 1.未初始化的指针,如
未初始化的指针,会存储一个随机值,并把这个随机值当成是地址,解引用的话,就会访问这个地址,并把这个地址上的值修改成20,但问题是,这个地址我们并未对其声明,是不属于我们的。 2.指针越界访问
当i=10的时候,p指向arr[10],一个未被声明的整型,并把arr[10]的值修改成10,属于越界访问了,此时的p就是野指针。 3.指针指向的空间被释放了
num是局部变量。调用完函数test()之后,内存就被释放,但地址却传给了p,并解引用修改成200,这也使得p是个野指针。 总结一下,野指针就是指针指向的空间不属于我们当前程序。 如何规避野指针1. 指针初始化
2. 小心指针越界 3. 指针指向空间释放,及时置NULL 4. 避免返回局部变量的地址 5. 指针使用之前检查有效性 空指针是不能直接访问的
指针的运算指针+-整数
?虽然最后vp越界了,但并没有进行修改或读取,这也是可行的,只是有隐藏的危险。 对上述代码进行修改,使其更加简洁:
上述修改造成指针最后指向数组首元素之前的位置,虽然在绝大多数编译器上可行,但标准并不允许。所以我们最好避免这样写。 标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 指针-指针
输出:9 ? ? ? ? ? ?-9 可以利用指针-指针来计算字符串的长度
输出:7 指针和数组数组名是首元素的地址,可以通过把地址存到一个指针变量中,来间接访问数组。 二级指针上面说过,指针变量也有自己的地址,这时,该指针变量就是一级指针,如果把指针变量的地址再一次地赋给一个新的指针变量,那么这个新的指针变量就是一个二级指针。三级、四级指针以此类推。
pp的类型是 int**,其中int*指的是pp指向的类型是个一级指针,而第二个*表明pp是个指针。同样的,p的类型是int*,其中int指的是p指向的类型是个int,而*表明p是个指针。 上述代码输出:250,通过对pp的两次解引用,访问a的值。 指针数组指针数组是数组,是存放指针的数组。
示例:
?由上图可知两件事,一是数组在内存中的存放是连续的,地址随下标的增加而增加;二是先声明的变量地址会比后声明的变量地址高。 arr[i]其实相当于*(arr+i),arr本身就是地址,是首元素的地址,arr[i]就是对arr自身的地址解引用,访问里面存储的内容,只是这个内容又是一个地址而已,再一次arr[i][j],即*(*(arr+i)+j),才能访问到三个数组里面的数字。 例题1.下面代码输出?
输出:250 解析:pp存放了p的地址,*pp是把p存放的内容,即a的地址,赋给了ps,因此*ps访问a。 2.下面代码运行的结果是:
输出:0 0 3 4 5 解析:考察前面介绍的指针类型的用处。一是访问的权限,short*只能访问2个字节,二是指针的步长,因此p+1,每次跳过2个字节。 3.下列程序段输出的结果为:
输出:6 12 解析:*(pulPtr+3)+=3等价于*(pulPtr+3)=*(pulPtr+3)+3,等价于pulArray[3]=pulArray[3]+3 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:25:45- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |