目录
一.野指针
二.如何避免野指针
三.指针运算
1、指针+(-)整数
2、指针 - 指针
3、指针关系运算
小编在这里声明一下,将某一块的知识点分为上中下或者1,2,3来编写不是为了增加小编的文章总量,也不是故意这样的,是小编个人认为在编写文章的时候如果把一个知识点,就比如指针全写在一篇文章中,那样只会导致读者难以找到想要的知识点。
一.野指针
1、未初始化:这是很多初学者容易犯的错误(本人也是这样),就是在写任何变量的时候不喜欢或者说是没有这个习惯去赋初值,从而会时不时导致程序无法运行!
比如: int* p ;
*p = 20 ;
上述代码就是没有初始化,所以指针变量 p 到底指向什么我们不知道,后面解引用p,让*p = 20 ,也就是错误的。(这是很经典的野指针)
2、越界访问:多见于数组中,如下面的代码:
这里我们发现,程序运行就会出错,倒也是能出现结果,但是弹出上述的窗口。
原因很好理解,我们此处定义的是一个大小位10的数组,但是在for循环中循环了11次,所以也就越界了。
3、指针指向的空间释放:这个可能不太好理解
举一个例子,有一天你去了宾馆,然后登记了一间房子,在你登记的时间内,这件房子你可以随意进出,但是第二天,到期了(也就是指向的空间释放了),这时候你再进入这件房子就不礼貌了!
二.如何避免野指针
(1)养成一个初始化的习惯,不仅仅是此处的指针
(2)避免越界
(3)指针指向空间释放后及时的指向NULL(指向NULL代表是一个空指针,没有指向任何有效的内存空间)
(4)使用指针之前检查有效性
使用 if(p!=NULL)
{
*p = 10;//这里很好理解,也就是如果这个指针不是空指针,那就让他随意的指向一块空间,这里的10可以是任何已知空间的常量或者变量或者数组等
}
三.指针运算
1、指针+(-)整数
如:
int main() { int a[5] = {1, 2, 3, 4, 5}; int* p = a; for(p = &a[0]; p < &a[5];)//这里有指针的关系运算 { *p++ = 0;//这里就是指针自加(也就是指针加整数) } }
这里我们发现这样确实将数组内的元素全都变为了0,且指针最后指向了一个任意值!(具体是如何指向的各位读者可以自己笔画推导一下!)
2、指针 - 指针
如 int a[5] = {1,2,3,4,5} ;
int n = &a[4] - &a[0] ; //这里就是指针减指针,也就代表两指针间的元素个数
如下:模拟实现strlen函数(使用指针 - 指针)
int my_len(char *str)//使用指针作为形参,指向abc字符串的首地址 { char* sta = str;//代表sta指向最初str指向的空间(也就是a) while (*str != '\0') { str++;//str自加指向该字符串的最后的地址 } return str - sta;//指针减指针,得出字符串长度 } int main() { int l = my_len("abc");//字符串“abc”传的是首地址 printf("%d\n", l); return 0; }
上图中说的已经很清楚了,这里不在赘述
3、指针关系运算
上文中已经涉及到指针的关系运算,也就是两个指针的比较
需要注意的是:c标准规定
允许数组指针可以和该数组最后一个元素之后的内存位置比较,但不可以和第一个元素之前的空间位置比较!具体可以看下图理解
意思就是 pa 可以和 pc 比较,但不可以和 pb 比较!