"探秘C语言指针的奥秘:类型、内存区和四大要素"
版权申诉
111 浏览量
更新于2024-03-07
1
收藏 69KB DOC 举报
;指针的类型"这种方式找到一个指针的类型后,接下来就要找找这个指针所指向的类型。这种类型就是指针所指向的内存区里存储的对象的类型。例一中的指针各自指向的类型是:
(1)int*ptr;//ptr所指向的类型是 int
(2)char*ptr;//ptr所指向的类型是 char
(3)int**ptr;//ptr所指向的类型是 int*
(4)int(*ptr)[3];//ptr所指向的类型是 int[3]
(5)int*(*ptr)[4];//ptr所指向的类型是 int*[4]
不难发现,只要用指针的类型声明语句里的指针名字加上一个"*",就是这个指针所指向的类型。怎么样?这也是很简单的吧? 指针的值即指针所指向的内存区 所谓指针的值,指的就是这个指针所指向的内存区域的地址。指针的值可以被赋予一个十六进制的数值,这个数值就是指针的变量。如果一个指针变量还没有被初始化,那么把它当成一个合法的指针来用是一个很危险的事情。任何一个非0的内存地址,都有可能是刚刚好是你的程序完全不能访问的,如果你的指针指向了这样的一个内存区域,那么你的程序将在那一刻崩溃。表2里是几个指针的声明语句。列出了它们和它们所指向的内存区的关系。 int i; int a[4]; int*p1=&i; int*p2=a; int*p3=&a[0]; int*p4; int p5[4]; p1指向了一个int类型的内存区i,p2自己本身是一个指向int类型内存区的指针,但它被赋值成了一个指向a[0]的指针,所以它现在指向了一个int类型的内存数组。而p3和它的赋值和p2是一样的,只不过这次是直接用a[0]去赋值p3的。p1和p2都是合法的指针,它们指向了可访问的内存区,p3在这一点上和p2是一样的,但是p3指向一个数组中的某一个元素。p5则是尝试定义了一个包含4个指针的数组,它里面的每一个元素都可以指向一个地址,但这些数组元素自己本身是不合法的指针。内存中经常会出现“野指针”。野指针是指指向程序中我们无权访问的内存的指针,即: 1. 指针变量没有被初始化。 2. 指针变量指向的位置在释放内存后,该位置的内存已经不再属于该进程。 3. 指针指向的内存部分被释放。 4. 指针操作超出变量范围。 野指针变量可能会呈现不固定的行为,这取决于变量被初始化以后等一系列不确定状态。在C、C++中,野指针指向的内容是无效的、不安全的,可以随时改变,所以必须谨慎对待。 读写野指针通常会导致非法访存错误。 一些IDE在运行程序时,会在释放一些指针所指内存后,将所使用的指针变成NULL指针,以避免形成野指针。 根据以上理解得到结论: 初始化指针变量时是一种很简单的工作,当指针变量在一个很短的作用域中被定义时并且这么饿作用域的外面没有静态的全局的变量职能够和这个指针有一些
关系的话,那么这个指针的周期一定会是经历一个很明显的两个步骤的。先是它的值根据它在栈里的位置被分了一个值出来,然后这个值会在运行时被一个合法的地址值给取代。 静态的全局变量和动态的内存分配而产生的变量职能够存在着一种在被定义的时候就被初始化的状态。这时候声明语句里的指针名所指向的内存区就是一个合法的内存区。 如何理解这个结论,我们接着来看下面的内容: 指针本身所占据的内存区 到现在为止还没有谈到过指针变量本身所占据的内存区。我们实际上也熟悉的不多。在例一中定义的那几个指针变量都要占据内存,那其中有几个字节呢?这取决于你的编译器。 一个指针变量所占据的内存区能够叫做什么呢? 这要因编译器而易。指针占据的内存区是专门存储地址的。所以我们可以用“地址变量”来表示它所占据的内存区。 至于这个地址变量占据的内存区要有多大,完全取决于使用的编译器。不过事实上,指针本身所占据的内存区的大小都是固定的。它们占据的内存大小总是固定不变的。我们可以把这个内存区的大小定义为一个整数。这个大小可能是2,也可能是4,或则是8。不过所有不同的类型的指针本身所占据的内存区大小还是要统一的。这也就是说,所有不同类型的指针都占据着相同大小的内存区。 了解了这些之后我们可以正确的理解指针。指针本身是一个变量,它的类型是一个“地址变量”,它所指向的类型是完全明确的,它有值那这个值就是一个合法的地址。 用好指针转化成为一个非常简单的问题了。
150 浏览量
126 浏览量
1660 浏览量
点击了解资源详情
146 浏览量
165 浏览量
![](https://profile-avatar.csdnimg.cn/5d3d17b770eb4c6785682f01b138d5bc_z9894.jpg!1)
悠闲饭团
- 粉丝: 212
最新资源
- Javaweb与ASP项目源码及论文合集
- 龙邱蓝牙参数修正上位机V1.02管理员身份运行指南
- Laravel模板开发教程与实践指南
- Notepad++ 6.5.4发布,新增FTP插件简化Linux远程编辑
- tiny+cdx防跳V1.4正式版发布
- STC89C51单片机CAN总线通讯C语言程序开发
- JavaScript框架Captain-Falcon深入解析
- 伟福icexplorerw/T仿真器绝版驱动发布
- JLink_V686a驱动程序发布,支持国产MCU烧录
- Huntress: PHP开发者的多功能机器人框架
- 深入探索Flash版Logo语言999的编程奥秘
- C# ASP.net实现文件夹压缩下载功能
- 开源WEB开发项目sarticle_html的快速安装与功能扩展指南
- MATLAB开发案例:实现C均值聚类算法
- Uroboros:GNU/Linux单进程监控分析工具介绍
- Destiny 2蓝品自动拆解工具Blue Dismantler