3. 野指针
概念:野指针就是这种指向的位置时不可知的(随机的、不正确的、没有明确限制的)
3.1 * 野指针成因
1. 指针未初始化
2. 指针越界访问
3. 指针指向的空间释放
3.2 * 如何规避野指针
1. 指针初始化
(1). 明确知道这种应该初始化为谁的地址,就直接初始化
(2). 不知道这种初始化为何值时,暂时初始化为NULL(空指针),没有指向任何有效的空间,该指针不能直接使用
2. 小心指针越界
3. 指针指向的空间释放,及时将它置为NULL(空指针)
4. 避免返回局部变量的指针
5. 指针使用之前检查有效性
4. 指针运算
- 指针 +- 整数
- 指针 - 指针
- 指针的关系运算
4.1 * 指针 +- 整数
//指针运算 #include <stdio.h> int main() { int arr[10] = { 0 }; //不使用下标访问数组 int* p = &arr[0]; //相当于arr int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); //数组长度 //使用指针运算循环赋值: //第一种方法: for (i = 0; i < sz; i++) { *p = i; p++; //指针运算 // p = p + 1; 指针加一,移到数组中的下一位 } //第二种方法: //for (i = 0; i < sz; i++) //{ // *(p + i) = i; //} //使用指针打印 p = arr; //地址位置还原到数组第一个元素位置进行打印 for (i = 0; i < sz; i++) { printf("%d ", *(p + i)); } return 0; }
补充:
4.2 * 指针 - 指针
//地址-地址(指针-指针) #include <stdio.h> int main() { int arr[10] = { 0 }; printf("%d\n", &arr[9] - &arr[0]); printf("%d\n", &arr[0] - &arr[9]); // 指针-指针 得到的数值的绝对值:是指针和指针之间的元素个数 // 指针-指针 运算的前提条件:指针和指针指向了同一块空间(同一数组) return 0; }
应用:使用 指针 - 指针 求字符串长度
//应用: #include <stdio.h> //第一种版本:正常思路 //int my_strlen(char* s) //{ // int count = 0; //统计字符串个数 // if (*s != '\0')//数组首元素不是结束标志 // { // count++; //能进来说明有元素,个数++ // s++; //判断下一位 // } // return count; //} //第二种版本:递归 //int my_strlen(char* s) //{ // if (*s == '\0') // { // return 0; // } // else // { // return 1 + my_strlen(s + 1); // } //} //第三种版本:指针减指针求数组元素个数 int my_strlen(char* s) { char* start = s; while (*s != '\0') //也可以写成 while(*s) ,\0的ASCII码值是0 { s++; } //循环到找到 \0 的地址 return s - start; //指针-指针:\0地址 - 首地址 = 元素个数 } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }
4.3 * 指针的关系运算
//指针的关系运算(比较大小) #include <stdio.h> #define N_VALUES 5 //定义宏:数组长度为5 int main() { float values[N_VALUES]; //浮点数数组 float* vp; for (vp = &values[N_VALUES]; vp > &values[0];) // vp 等于 数组第五个元素的地址;vp 大于 数组第0个元素的地址 { *--vp = 0; // vp先 -- ,再解引用 vp,把第四个元素赋值为0,然后是第三个、第二个…… } //实现倒着给数组赋值 int i = 0; for (i = 0; i < N_VALUES; i++) { printf("%d ", *(vp + i)); } return 0; }
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。