一、指针概括
1、指针定义
Def: 指针(pointer)也就是内存地址(指针==地址),指针变量是用来存放内存地址的变量,在同一CPU下,不同类型的指针变量所占用的存储单元长度是相同的,但所占空间大小由指针变量的类型所决定。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。
一般形式为:类型(int char long short...) * 变量名
void*为泛指类型,可以用来接收任何类型的地址,但不能直接解引用或位置加减
2、指针运算符
& 取址运算符
功能:取出变量的内存地址(升一级)
* 取值运算符(解引用)
功能:访问指针指向的变量内容(降一级)
3、指针大小
(a)×86(32位):32个bite位(相当于32个地址总线),占4个字节空间大小,最多占2^32字节空间大小(一个地址线发出两个信号)
(b) ×64(64位):64个bite位(相当于64个地址总线),占8个字节空间大小,最多占2^64字节空间大小(一个地址线发出两个信号)
注:大小与变量类型无关,变量类型只决定指针解引用访问的权限大小和向前向后走的长度
4、const修饰指针(变量不变)
const放在的左边限制p(为p指向空间的内容,p不受限制)【const int * a / int const * a】
const放在*的右边限制p(为p的地址,*p不受限制)【 int * const a】
5、指针运算
a、指针+/-数字=指针;
b、指针-指针=指针之间元素的个数(数字)【两个指针需要指向同一区域】
c、指针见的关系运算【比大小(地址的高低)】
6、野指针
(1)指针的初始化
通过赋值语句初始化指针变量:int * pa = &a(将a的地址赋值给pa指针变量,*告诉我们pa为指针,int告诉我们pa指向的空间存的数据为int类型,int *告诉我们pa的类型)
(2)野指针的形成
a、定义
Def:C语言中指针初始化是指给所定义的指针变量赋初值。指针变量在被创建后,如果不被赋值,他的缺省值是随机的,它的指向是不明确的,这样的指针形象地称为“野指针”。野指针是很危险的,容易造成程序出错,且程序本身无法判断指针指向是否合法。
b、成因
#变量未初始化(局部变量为随机值,全局变量默认为0)
#指针访问越界
c、规避
#可以在指针定义后,赋值NULL空值
也可写成:p=0或p='\0'
这两种形式和p=NULL是等价的
举例说明
上面两行代码的含义是,指针变量p被赋值为空。虽然定义了一个指针变量,但是它并不指向任何存储空间。
#使用assert断言
包含头文件#include<assert.h>,用于终止错误代码并指出路径
assert的使用
(1)表达式:assert(表达式)【仅在Debug版本使用,release版本不行(Linux系统可以)】
(2)可用#define NeDEBUG取消断言
7、简易应用
1、交换两个int类型的值:
a、引入第三变量交换(常用)
b、使用按位异或^进行交换(罕见)
c、传址调用(让函数与主调函数产生联系)
二、二级指针
1、定义:用于存放指针变量的指针变量称为二级指针
注:第二个*告诉我们pb为指针,int*告诉我们pb所指向的空间存储数据类型为int型指针,int**告诉我们pb的类型为二级指针。
三、指针数组
1、定义:(本质为数组)数组元素为指针变量的数组成为指针数组
2、形式:
int *arr[ ]形式等同于int arr[ ]
四、字符指针
1、定义:用于存放字符(数组)地址的变量成为字符指针(变量)。
p[3]=>"abcdef"[3]=d(%c)
五、数组指针
1、定义:用于存放数组地址的变量成为数组指针(变量)。
六、数组传参
1、数组名相当于数组首元素的地址(一维)
二维数组数组名相当于第一行即第一个一维数组的的地址
2、数组传参的本质是传数组首元素的地址
arr[i][j]==*(*(arr+i)+j) *(arr+i)==arr[i]
七、函数指针(数组)
1、定义:函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。函数指针有两个用途:调用函数和做函数的参数。
函数指针数组是一个其元素是函数指针的数组。那么也就是说,此数据结构是一个数组,且其元素是一个指向函数入口地址的指针。
2、函数名==&函数名==函数的地址
3、形式:int(*p)(类型)p为函数指针,指向类型为int(*)(类型)
int(p[])(类型)数组存放数据类型为int()(类型)p[]为数组
3、应用:
(1)简易
2)与函数指针数组合作用于实现计算器(回调函数)
专业术语为转移表( 使用转移表可以替代冗长的switch和if-else语句,分离了具体操作和选择代码,是一种良好的设计方案。和其他指针一样,对函数指针执行间接访问之前,必须把它初始化并指向某一个函数。)