摘要:本文概述了指针的核心概念与应用。主要内容包括:指针的优点(高效访问内存、操作硬件)、基本概念(地址与指针变量)、注意事项(野指针、内存泄漏)。介绍了指针运算符(&取地址,*解引用)和指针变量的定义形式(空指针NULL)。详细说明了指针算术运算的特性(偏移量由数据类型决定)以及指针作为函数参数的两种传递方式(值传递和地址传递)。文中通过具体示例展示了指针的操作方法,并强调了使用指针时的关键注意事项。
一、指针概要
1、优点
- 让代码更加简洁高效
- 提供直接访问内存的操作
- 利用指针可以直接操作硬件
2、概念
- 地址:内存中每个字节有唯一编号(地址),寻址范围由系统位数决定。区分内存中不同字节的编号(寻址范围:0 - 2^64 -1)
- 指针:指针就是地址,地址就是指针,指针比地址多了指向的概念
- 指针变量:存放指针(地址)的变量称为指针变量(64位操作系统中所有指针变量均为8个字节)
3、注意事项
- 未初始化指针(野指针)可能导致程序崩溃。
- 指针类型需与指向的数据类型匹配,避免未定义行为。
- 动态分配内存后需手动释放,防止内存泄漏。
二、指针的运算符
1、&:取地址运算符,获得变量在内存空间中的首地址
- 只有变量(左值)才能&,常量和表达式不能进行&操作
- &构成的表达式类型位:变量的类型升级后的类型
2、 *:获得指针指向的空间,或者对应空间中的值
- *运算符连接的内容必须为指针类型,不能是普通变量类型
- 如果直接使用*对应的表达式,表达式值为:该指针指向空间中的值
- 如果使用*对应的表达式其类型为:指针类型降级后的类型
- *对应的表达式作为左值表示,将等号右边的值放入指针指向的空间
三、指针变量
1、基本形式: 存储类型 数据类型 *变量名;
2、野指针:未经初始化的指针或者指向已经被释放空间的指针,称为野指针
3、空指针:指向内存地址为0x0的指针称为空指针,用NULL来表示。
内存地址0x0空间为只读空间,不能赋值,NULL指针不能执行*p = value操作
eg:
4、指针特性:间接访问
间接访问:通过变量在内存中的地址访问变量空间 (指针变量)
直接访问:通过变量的变量名访问变量空间 (普通变量)
四、指针的算数运算
1、算数运算符:
+ - ++ --
- 指针偏移的大小由指针指向的数据类型大小决定
- 两个指针相减得到的结果为,元素差 / 数据类型偏移量
2、不同数据类型的指针字节空间
- char *: 取0x2000开始的1个字节空间数据
- int *: 取0x2000开始的4个字节空间数据
- float *: 取0x2000开始的4个字节空间数据
- double *:取0x2000开始的8个字节空间数据
3、不同数据类型的指针偏移量
- char *: 偏移量为1个字节
- int *: 偏移量为4个字节
- float *: 偏移量为4个字节
- double *:偏移量为8个字节
4、示例
个人注解:
*q 为0x18 对应的十进制是 24 ,所以q - p 的元素差是24(NULL为0)
int *的偏移量是4个字节
所以q - p = 24 / 4 = 6
五、指针常见操作
1、注意事项:
- 指针有两个需要注意的概念:指针变量本身,指针指向的空间
- 对指针变量:p或者q修改,改变的是指针的指向
- 对*p或者*q操作,改变的是指针指向的空间,指针还是指向原有的空间
2、不同情况分析:
六、指针作为函数参数
1、值传递:
- 实参将值传递给形参,形参的值改变,实参不会改变
- 函数体内部想使用函数体外部变量值的时候,使用值传递
2、地址传递:
- 实参将地址传递给形参,形参是指向实参的指针,可以利用形参修改实参的值
- 函数体内部想修改函数体外部变量值的时候,使用地址传递
3、小试牛刀: