一.如何规避野指针?1.指针初始化;
2.小心指针越界
3.指针指向空间释放即使置NULL
4.指针使用之前检查有效性
代码语言:javascript复制#include
int main(void)
{
//当前不知道p应该初始化为什么地址的时候,直接初始化为NULL
int* p = NULL;
//明确知道初始化的值
int a = 10;
int* ptr = &a;
//用以下方式可以检查其有效性
//int* p = NULL;
//if(p != NULL)
// *p = 10;二.指针运算1.指针+-整数代码语言:javascript复制//指针+-整数
#define N_VALUES 5 //define定义了一个变量
float values[N_VALUES}; //float定义了一个数组,为5个元素
float *vp;
for( vp = &values[0];vp < &values[N_VALUES]; )
{
*vp++ = 0; //解引用的时候,后置++,实际上指向的是,下一个元素(下标为0)的地址,将下一个元素赋值(下标为0)为0,循环继续,所以整个数组都被赋值为0,地址是由低到高变化的
}
//下面给一个例子加深理解
int main(void)
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个arr数组,元素10个
int *p =arr; //*p地址指向第一个元素的下标
int *pend = arr+9; //*pend地址指向第十个元素的下标
while(p<=pend) //当p<=Pend时,执行循环
{
printf("%d\n",*p); //最后打印出1~10的元素
p++;
}
return 0;
}2.指针-指针代码语言:javascript复制//指针-指针
#include
int main(void)
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",&arr[9] - &arr[0]); //这里打印出9
//指针-指针得到的是两个指针之间的元素个数
//指针和指针相减的前提是两个指针指向同一块空间
//下面给一个例子,用计数器的方法求字符串长度
#include
int my_strlen(char* str)
{
int count = 0;
while(*str != \0) //strlen求字符串长度,在看到\0的时候才会停止循环
//*str首先指向第一个元素的下标
{
count++;
*str++; //一直++循环直到找到\0,最后返回count++
}
return count++;
}
int main(void)
{
int len = my_strlen("abc");
printf("%d\n",len); //打印出3
return 0;
}
//下面是用递归 指针-指针的方式求字符串长度
#include
int my_strlen(char* str)
{
char* start = str; //将char*str 放在一个叫start的指针变量里面,赋值给start,start记住了这个a的地址
while(*str != '\0')
{
str++;
}
return str-start; //指针相减
}
int main(void)
{
int len = strtlen("abc"); //字符串实际上传的是首字符的地址,所以写char*
printf("%d\n",len); //打印出3
return 0;
}3.指针的关系运算代码语言:javascript复制//指针的关系运算
//第一种
for(vp = &values[N_VALUES] ; vp > &values[0]; )
{
* --vp = 0;
}
//第二种
for(vp = &values[N_VALUES]; vp > &values[0] ; vp--)
{
*vp = 0;
}
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较,所以第二种方法避免这样写。三.指针和数组数组名是首元素的地址
代码语言:javascript复制//指针和数组
#include
int main(void)
{
int arr[10] = {0}; //初始化全为0
int* p = arr;
int i=0;
for(i=0;i<10;i++)
{
// printf("%p <==>%p\n",&arr[i],p+i);//代码运行的结果是一样的
//p+i产生的就是下标为i这个元素的地址,&arr[i],p+i访问的是同一个地址
*(p+i) = i;
}
for (i=0;i<10;i++)
{
printf("%d ",*(p+i)); //代码打印出的是0~9
}
return 0;
}代码语言:javascript复制//指针和数组
#include
int main(void)
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr; //数组名
printf("%d\n",2[arr]); //代码运行结果是3
printf("%d\n",arr[2]); //代码运行结果是3
return 0;
}
// arr[2] <==> *(arr+2) <==> *(p+2) <==> *(2+p) <==> *(2+arr) <==> 2[arr]
// p[2] <==> *(p+2)
// []是一个操作符,2和arr是两个操作数四.二级指针代码语言:javascript复制//二级指针
#include
int main(void)
{
int a = 10; //pa 是指针变量,一级指针,pa指向了a,pa是个变量,是变量就在内存中有空间,&pa取出pa在内存中的起始地址,*pa是指针,前面int(pa指向的a是整型)
int * pa =&a;
int **ppa = &pa; //*ppa是指针,ppa指向的对象是pa,pa的类型是int*
//两颗*的含义不一样,*ppa中*说明这是一个指针,指向pa,pa的类型是int*
//ppa是一个二级指针变量
//*ppa == pa
//*pa == a
//**ppa == a
return 0;
}指针变量也是指针,是变量就有地址,那指针变量的地址存放在哪里?这就是二级指针。
指针数组是指针还是数组?
是数组。是存放指针的数组。
五.指针数组代码语言:javascript复制//指针数组
#include
int main(void)
{
int arr[10]; //整型数组--存放整型的数组就是整型数组
char ch[5]; //字符数组--存放的是字符
//指针数组--存放指针的数组
int* parr[5]; //整型指针的数组
char* pch[5]; //字符指针的数组
return 0;
}