一 野指针
(1)概念
++++++++++++++++++'类比'++++++++++++++++++
1. '野'狗、猫:没有主人,没有任管理;疯狗-->'失控'
2. '没有人管理'或者'管理不了'
概念: 野指针就是指'针指向的位置'是'不可知(Unknown)'的('随机'的、'不正确'的、没有'明确限制'的)
(2)野指针成因
① 指针未初始化
规则: 局部变量'未初始化',默认是'随机值(random_value)';
补充: '指针也是',随便开了'一块'内存空间,现在默认值是'NULL',空指针
② 指针越界访问
③ 指针指向的空间释放
说明: 这里以'函数'中'局部变量'为案例
原则: 局部变量在进函数'{'进行创建,出'}'函数就销毁了,test函数'被调用'完之后,这块空间就'释放',就返回给当前'OS',不属于'编译器'管理,不属于'当前程序'
理解: 男女朋友分手 --> '一方被踹'--> '记住电话号码' --> '非法骚扰'
#include <stdio.h>
int* test() {
// 合法方式:static修饰,因为test()函数调用之后,变量'没有'销毁
static int a = 10;
return &a;
}
int main() {
int* p = test();
*p = 20;
printf("%d\n",*p);
return 0;
}
(3)如何避免野指针
1. 指针'初始化'
2. 小心指针'越界'
3. 指针指向空间释放'及时'置为'NULL'
4. 指针使用之前'检查(check)'有效性
细节: 'NULL'空间地址,是'不能访问'和'设置'
(4)指针运算
1. 指针 "+、-" 整数
2. 指针 "-" 指针
3. 指针的"关系"运算
① 指针与整数
1)加法
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
2)减法
等价: p -= 1
② 指针与指针的运算
说明1: 指针与指针只能是'-(减法)'才有意义!
说明2: 必须是指向'同一块连续的空间'才有意义,一般是'数组'
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' ) {
p++;
}
return p-s;
}
1)案例
2)注意事项
++++++++++'方式1:建议'++++++++++
for(vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}
++++++++++'方式2(不建议)'++++++++++
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
原因: 实际在'绝大部分的编译器上'是可以'顺利'完成任务的,然而还是'应该避免'这样写,因为'标准'并不保证它可行
1) 允许指向'数组元素'的指针与指向'数组最后一个'元素后面的那个内存位置的指针比较
也即: p2-p1 是 符合'C语言标准的'
2) 但是'不允许'与指向'第一个元素之前'的那个内存位置的指针进行比较
也即: p1-p3 是 符合'C语言标准的',虽然编译器'不会'报错
③ 求字符串的长度
④ 回顾知识点
'数组名'arr '完全等价' &arr[0] -->数组'首元素'的地址
&arr 虽然'数值结果'与上面'一样',但'含义'不一样,表示'整个(all)数组的地址-->起地址'
(5)二级指针
指针变量也是变量,是变量就有地址,那'指针变量'的'地址'存放在哪里? 这就是 '二级指针'
+++++++++++++++++++'二级指针的运算'+++++++++++++++++++
1) *ppa 通过'对ppa中的地址'进行'解引用',这样找到的是 'pa' ,,*ppa 其实访问的就是 pa
2) **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
(6)指针数组
老婆饼 --> '老婆'是'修饰'
指针数组是'数组',是'存放'指针'的'数组'