目录
1.指针的定义
2.野指针出现的原因以及如何避免写出野指针
3.指针间的运算
4.二级指针的表示以及使用
正文
1.指针的介绍
指针:是用来存放地址的变量(由于其为变量,因而可以对其进行加减【后文会有所涉及】)通过指针我们能找到内存单元
例如
int main()
{
int a=0;
int *pa=&a; //将a的地址放到了pa中,而*用于表示pa是一个地址,而int表示的则是a的指针类型
*pa = 20; //*可用于解引用 ,通过解引用pa (如*pa)可找到a,再将20赋予了a
printf("%d",a) //上一步赋予了a 20的值,因此a打印出来的值不再是0而是20
}
指针的存储采用的十六进制(可用1个16进制位表示4个二进制位)。
例如 假设 int *a=0x11223344 (其中0x表示其为16进制,则有11223344 8个十六进制位的数组成,也就是可看成 8 *4=32 个二进制位(一个二进制位所占内存为1个比特位,8个比特位又组成一个字节,因此 a 的指针占了4个字节的空间。
注:32位平台指针位4个字节,64位平台占8个字节。
指针类型的含义:
1.指针类型决定了 解引用的权限有多大
例如
int main( )
{
int a =0;
char *a =&a; //指针类型为char(1个字节)而a的为整形int(4个字节)
*a = 1; //所以仅能解引用a的第一个字节,赋予a的值也仅仅是改变了a地址中的第一个字节中的2个16进制位。
return 0;
}
2.指针类型决定了指针一步可以走多远(也称为步长)(跳过几个字节是由指针类型决定的)
例如
//假设arr首元素地址为0X004ffC40
int main( )
{
int arr[10]={0};
int *p = arr ; //p为arr 首元素的地址
char *pc =arr;
printf("%p",p); //0X004FFC40
printf("%p",p+1); //0X004FFC44
//指针p的类型是整形(4个字节),加1应跳过4个字节,是的指针地址也应是加4
printf("%p",pc); //0X004FFC40
printf("%p,pc+1); //0X004FFC41
//指针pc的类型是字符(1个字节),加1应该跳过1个字节,指针的值加1
return 0;
}
2. 野指针
野指针出现的原因:
1.指针未初始化
例如
int main()
{
int *p; //指针未初始化,称指针 p 为野指针
*p =20;
return 0;
}
2.指针越界访问
例如
int main( )
{
int arr [10] ={0};
int *p = arr[10 ];
//该处访问的是数组中第11的元素的地址,超出了数组(仅有10个元素)的范围,则称p位野指针,越界访问空间。
*p=10;
return 0;
}
3.指针指向的空间已经释放
例如
int test()
{
int a = 20;
return &a: //a为局部变量 它的位置传到主函数main前已被释放,即存放地址已被释放
}
int main()
{
int *p=test(); //指针p 指向的是a 的地址,其地址已被释放,故p为野指针
*p=20;
return 0;
}
如何避免野指针的出现:
1.不忘给指针初始化 (给不知道指针指向哪个位置的指针初始化为空指针 例如:int*p=NULL; NULL为空指针写法。给已知指针初始化 例如 int a =10;
int *pa =&a)
2.小心越界(c语言本身不会检查越界情况)
3.将指针释放后设置为NULL
4.使用之前检查有效性
例如 if (p!=NULL)
*p=10;
3. 指针的运算
1.指针加减整数
指针加一,则指针加上与指针类型相符的字节(如整形指针加一地址后加4,字符指针加以地址加1),减法类似。
2.指针减指针(要求两指针指向同一位置)
指针减指针得到的是两指针之间的个数 例如 int a=&arr[9]-&arr[0] ,a会等于9
3.指针关系运算(即指针可进行比较)
例如 &arr[9]>&arr[8] 原因:随着数组下标的增加,地址也会由低到高增加。
4.二级指针
二级指针:指针的指针(地址)
例如
int main()
{
int a = 0;
int *pa = &a; //该处的*表示的是pa是一个指针 int 为a的指针的类型;
int* *ppa = &pa; //*ppa 中的*表示的是ppa为一个指针,int*为pa 的指针的类型;ppa 是pa 的指针(指针的指针)称为二级指针
return 0;
}
解引用操作:
int main()
{
int a = 0;
int *pa = &a; //该处的*表示的是pa是一个指针 int 为a的指针的类型;
int* *ppa = &pa;
return 0;
}
//*ppa=pa *pa=a
//可以合写为**ppa=pa (理解为* (*ppa)两次解引用)
一般情况下推荐分开写。