【C语言】指针

指针是什么?

指针理解的2个要点:

  1. 指针是内存中一个最小单元的编号,也就是地址。
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量。

总结:指针就是地址,口语中说的指针通常指的是指针变量。

那么这里就有以下两种理解:

  1. 内存

把内存划分为一个一个的内存单元,这个内存单元的大小为一个字节。给每个字节一个唯一的编号,我们将这个编号称为地址,地址在C语言中也叫指针。

在这里插入图片描述

编号 == 地址 == 指针

  1. 指针变量

我们可以通过&(取地址操作符)取出变量的内存的起始地址,把地址可以存放到一个变量中,这个变量就是指针变量。

在这里插入图片描述

总结:指针变量,用来存放地址的变量。(存放在指针变量中的值都被当成地址处理)。

指针和指针类型

指针和变量一样,都有不同的类型。要将&num(num的地址)保存到p中,我
们知道p就是一个指针变量,我们需要给指针变量相应的类型:

  • char* 类型的指针是为了存放 char 类型变量的地址。
  • short* 类型的指针是为了存放 short 类型变量的地址。
  • int* 类型的指针是为了存放 int 类型变量的地址。
  • long* 类型的指针是为了存放 long 类型变量的地址。
  • float* 类型的指针是为了存放 float 类型变量的地址。
  • double* 类型的指针是为了存放 double 类型变量的地址。

指针的定义方式是: type + * 。

  • char* p = NULL;
  • short* p = NULL;
  • int* p = NULL;
  • long* p = NULL;
  • float* p = NULL;
  • double* p = NULL;

而无论指针类型是什么,指针的大小始终在32位平台是4个字节,在64位平台是8个字节。那么指针类型存在的意义又是什么呢?请接着往下看看吧!

指针±整数

指针类型的第一个意义:指针的类型决定了指针向前或者向后走一步有多大(距离)。

在这里插入图片描述

指针的解引用

指针类型的第二个意义:指针的类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。

int* 的指针的解引用就能访问四个字节。

在这里插入图片描述
在这里插入图片描述

char* 的指针解引用就只能访问一个字节。

在这里插入图片描述
在这里插入图片描述

野指针

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。

野指针成因

  1. 指针未初始化(局部变量指针未初始化,默认为随机值)
#include <stdio.h>
int main()
{
    int *p;   //局部变量指针未初始化,默认为随机值
    *p = 20;
    return 0;
}
  1. 指针越界访问
#include <stdio.h>
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
    {
            //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
    }
    return 0;
}
  1. 指针指向的空间释放
#include<stdio.h>
 
int* test()
{
    int a = 10;  //变量a在出了test()函数后消失
    return &a;
}
 
int main()
{
    int* p = test();
    *p = 100;
    return 0;
}

如何规避野指针

  • 指针初始化
  • 小心指针越界
  • 指针指向空间释放,及时置NULL(一个指针不知道该指向哪里的时候,暂时可初始化NULL)
  • 避免返回局部变量的地址
  • 指针使用之前检查有效性

指针运算

指针±整数

示例1:模拟实现求字符串长度的函数。

在这里插入图片描述

示例2:利用指针初始化数组。

在这里插入图片描述

指针-指针

指针-指针相当于地址-地址,但有两个前提:

  1. 两个指针指向同一块空间
  2. 指针的类型是一致的。

指针-指针得到的是元素之间的个数。(大指针-小指针是正数,小指针-大指针是负数)

在这里插入图片描述
在这里插入图片描述

示例1:模拟实现求字符串长度的函数。

在这里插入图片描述

指针的关系运算

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

在这里插入图片描述

化简上述代码后:

在这里插入图片描述

虽然比原来的代码阅读起来更清晰,但是不推荐,原因如下:

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

指针和数组

数组名表示的是数组首元素的地址。(2种情况除外,数组博客有讲解)

在这里插入图片描述

指针可以指向数组元素,因为指针可以运算,所以可以借助指针访问数组。

在这里插入图片描述

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在二级指针里。

在这里插入图片描述

在这里插入图片描述

关于二级指针的运算:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa。
  • **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a 。

指针数组

指针数组:存放指针的数组。

在这里插入图片描述

使用指针可以将一维数组模拟为二维数组。

在这里插入图片描述

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值