学C的第十七天【指针初阶: 1. 指针是什么?;2. 指针和指针类型;3. 野指针;4. 指针运算】2

简介: 3. 野指针 概念:野指针就是这种指向的位置时不可知的(随机的、不正确的、没有明确限制的)

3. 野指针

                 

概念:野指针就是这种指向的位置时不可知的随机的不正确的没有明确限制的

3.1 * 野指针成因

               

1. 指针未初始化

c463ca5d4035409595b3b905ff6c46bf.png

2. 指针越界访问

4e9ffc6d414c46dea0abe495646fab73.png

3. 指针指向的空间释放

29463888234c4adf8f0ba0b96eaefc58.png

3.2 * 如何规避野指针

                 

1. 指针初始化

               

(1). 明确知道这种应该初始化为谁的地址,就直接初始化

(2). 不知道这种初始化为何值时,暂时初始化为NULL(空指针),没有指向任何有效的空间,该指针不能直接使用

               

           

2. 小心指针越界

   

3. 指针指向的空间释放,及时将它置为NULL(空指针)

             

4. 避免返回局部变量的指针

5. 指针使用之前检查有效性                                          

09837d0f1918410e99330048c076ac37.png

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;
}

c1907eb409184baaa2a25e07dafef90e.png

补充:

image.png

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;
}

69720fb639d64922b4fae6f77158992d.png

应用:使用 指针 - 指针 求字符串长度

//应用:
#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;
}

ee4615cbf3e242b4b7f745a1e46fd425.png

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;
}

fd6db486bc9c491eb25042339ede14f7.png

标准规定:

                 

允许指向数组元素的指针指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

相关文章
|
2月前
|
存储 C语言
文件的类型指针
文件的类型指针
15 0
|
2月前
|
编译器 C语言
void的指针类型
void的指针类型
10 0
|
2月前
|
存储 程序员 C++
在C++编程语言中指针的作用类型
在C++编程语言中指针的作用类型
16 0
|
10天前
|
存储 人工智能 编译器
【重学C++】【指针】一文看透:指针中容易混淆的四个概念、算数运算以及使用场景中容易忽视的细节
【重学C++】【指针】一文看透:指针中容易混淆的四个概念、算数运算以及使用场景中容易忽视的细节
19 1
|
15天前
|
存储 安全 Java
Go语言学习10-指针类型
【4月更文挑战第11天】本篇 Huazie 向大家介绍 Go语言的指针类型
10 2
Go语言学习10-指针类型
|
2月前
|
C语言
Void 指针类型
Void 指针类型
9 0
|
2月前
|
存储 C语言
C语言指针类型和空类型详解
C语言指针类型和空类型详解
27 0
|
2月前
|
存储 C++
在C++语言中函数指针的作用类型
在C++语言中函数指针的作用类型
11 0
详解7道经典指针运算笔试题!
详解7道经典指针运算笔试题!
|
2月前
|
安全 程序员 编译器
了解野指针与assert断言 拿捏指针的使用!
了解野指针与assert断言 拿捏指针的使用!