一、指针简介
指针很灵活,它可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内存,以下是有效的指针声明:
int *p; /* 一个整型的指针 */
double *p; /* 一个 double 型的指针 */
float *p; /* 一个浮点型的指针 */
char *p; /* 一个字符型的指针 */
二、野指针
概念
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
成因
1.指针未初始化
#include<stdio.h>
int main()
{
int* p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2.指针越界访问
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = &arr[0];//p此时不是野指针
int i = 0;
for (i = 0; i <= 11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
运行结果:
这就是指针越界访问了后的结果。
3.指针指向的空间释放
#include<stdio.h>
int* test()
{
int a = 0;
return &a;
}
int main()
{
int* p = test();
printf("%d\n", *p);
return 0;
}
这就是非法访问了。
如何规避野指针
1.指针初始化
1.如果明确知道指针指向哪⾥就直接赋值地址,如果不知道指针应该指向哪⾥,可以给初始化一个明确的地址。2.如果现在还不知道应该指向哪里,就初始化为NULL。
例如:
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;//1.明确知道指针指向哪里
int* p2 = NULL;//不明确指针指向哪里
return 0;
}
2. 小心指针越界
一个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是
越界访问。如上面那个代码的解释。
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = &arr[0];//p此时不是野指针
int i = 0;
for (i = 0; i <= 11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
3.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性免返回局部变量的地址
当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使⽤这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问,同时使⽤指针之前可以判断指针是否为NULL。我们可以把野指针想象成野狗,野狗放任不管是⾮常危险的,所以我们可以找⼀棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。不过野狗即使拴起来我们也要绕着⾛,不能去挑逗野狗,有点危险;对于指针也是,在使⽤之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使⽤,如果不是我们再去使⽤。
4.避免返回局部变量的地址
不要返回局部变量的地址(解释如上图)
#include<stdio.h>
int* test()
{
int a = 0;
return &a;
}
int main()
{
int* p = test();
printf("%d\n", *p);
return 0;
}
三、空指针(NULL)
在 C 语言中,如果一个指针不指向任何数据,我们就称之为 空指针 ,用 NULL 表示。例如:
int *p = NULL;
注意区分大小写,null 没有任何特殊含义,只是一个普通的标识符。NULL 是一个宏定义,在 stdio.h 被定义为:
#define NULL ((void *)0)
我们知道,变量一旦定义就要分配内存,指针变量也是如此。例如:
int *p; //它不是空指针,这个是为初始化
它的值是随机的,是垃圾值,如果不小心使用了它,运行时一般会引起段错误,导致程序退出,甚至会不知不觉地修改数据。p 经过定义,就一定在内存中分配了 4 个字节的空间,只是它的值是随机的,不像 int 会被初始化为 0,但是它确实指向了一段正常使用的内存。使用 p 时,操作的就是这段内存的数据,幸运的话能够正常运行,不过大部分情况下这段内存是无权操作。
NULL 和 0
不要把 NULL 和 0 等同起来,下面的写法也是不对的:
int *p = 0;
正确的书写:
int *p = NULL;
欧耶!!!!!!!我学会啦!!!!!!!