野指针
野指针成因
1.指针未初始化
int* p; //p没有初始化,意味着没有明确的指向
//一个局部变量不初始化,放的是随机值 0xcccccccc
*p = 10; //非法访问内存 野指针
2.指针越界访问
int arr[10] = { 0 };
int* p = arr; //&arr[0]
int i = 0;
for (i = 0; i <= 10; i++)
{
*p = i;
p++; //
}
3.指针指向的空间释放
int* test()
{
int a = 10; //a是局部变量
return &a;
}
int main()
{
int* p = test(); //
printf("%d\n,*p); //得出10 (不一定每次都是)
}
保持指针良好习惯
int a = 10;
int* p = &a;
int* p2 = NULL; //不知道初始化什么的时候这么干
*p = 20;
//*p2 = 20; //非法,0地址不能访问
if (*p2 != NULL) //避免出现问题
{
*p2 = 20;
}
指针运算
±整数
float values[5];
float* vp;
for (vp = &values[0]; vp < &values[5];)
{
*vp++ = 0; //先使用再对地址++
//(*vp)++表示对*vp指向的内容++
}
数组下标
int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (i = 0; i < sz; i++)
{
*p = 1;
p++;
}
//上下写法等价
for (i = 0; i < sz; i++)
{
*(p + i) = 1;
}
指针 减 指针
绝对值得到指针之间元素个数
int main()
{
int arr[10] = { 0 };
printf("%d\n", &arr[9] - &arr[0]); //9
char ch[5] = { 0 };
//不是所有的指针都能相减
//指向同一块空间的两个指针才能相减
//printf("%d\n", &ch[0] - &arr[5]); //err
}
int mystrlen(char* str)
{
char* start = str;
while (*str != '\0')
{
str++;
}
return (str-start);
}
int main()
{
int len = mystrlen("abcdef");
printf("%d\n", len);
}
float values[5];
float* vp;
for (vp = &values[5]; vp > &values[0];)
{
*--vp = 0;
}
指针相加无意义
指针和数组
数组名表示首元素地址
二级指针
二级指针变量是用来存放一级指针变量的地址
int a = 10;
int* pa = &a; //pa是一个一级指针变量
*pa = 13;
printf("%d\n", a);
//int*pa中 int 为指针指向类型对象 *意味着pa是指针
int** ppa = &pa; //ppa是一个二级指针变量
**ppa = 20; //int*说明ppa指向类型对象是int*类型的 *说明ppa是指针
printf("%d\n", a);
指针数组
存放指针的数组就是指针数组
int a = 10;
int b = 20;
int c = 30;
int arr[10];
int* pa = &a;
int* pb = &b;
int* pc = &c;
int* parr[10] = { &a,&b,&c }; //指针数组
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d ", *(parr[i])); //10 20 30
}
指针实现二维数组
arr[i]等价于*(arr+i)
int arr1[4] = { 1,2,3,4 };
int arr2[4] = { 2,3,4,5 };
int arr3[4] = { 3,4,5,6 };
int* parr[3] = { arr1,arr2,arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("%d ", parr[i][j]); //arr[i]等价于*(arr+i)
}
printf("\n");
}