# 指针

210 阅读5分钟

指针是一个最小的内存单元的编号,也就是地址(内存单元的编号)

通常口语上讲的指针实际上是指“指针变量”

指针变量是一个用来存放地址的变量,在32位系统占4个字节,在64位操作系统中占8个字节,用于存储另一个变量的内存地址。通过指针,可以直接访问和修改内存中的数据。

  • 定义指针时,使用 * 符号。

  • 使用 & 符号获取变量的地址。

  • 使用 * 符号访问指针指向的值

  • int a = 10;

    int *p = &a;

    printf("%d\n", *p);

指针类型

指针可以指向任意类型的数据,如:int整形、float(double)浮点型、char字符型,甚至可以是指向数组、指针

在弄懂指针类型的作用时,我们必须先了解内存中地址的表示运作原理。

地址:

内存地址的表示

在计算机内存中,地址是用于标识和访问特定内存位置的数值。内存地址通常以字节为单位进行编号,每个字节都有一个唯一的地址。

屏幕截图 2024-11-10 160332.png 数据在内存中存储时,通常会将每一个内存单元用十六进制进行进行编号,而编号所代表的内存单元就叫做该数据的地址。

但很显然,大部分数据所占有的内存都不是仅仅一个内存单元,所以这时该数据的地址就由第一个内存单元的编号所表示

内存单元的存储

内存地址在内存中以二进制形式存储。每个内存地址对应一个字节(8位),地址的位数取决于系统的寻址能力。例如,32位系统的地址是32位长,64位系统的地址是64位长。

在32位机器下,地址是32个0或者1组成的二进制序列

地址所包含的信息

  • 内存位置:地址标识了内存中的一个特定位置。
  • 数据类型:地址所指向的数据类型决定了如何解释该地址处的数据。
  • 数据大小:地址所指向的数据类型决定了该数据在内存中占用的字节数。
  • 访问权限:地址可能包含访问权限信息,例如只读或可写。

指针类型的意义:

​ 1.决定了有几个字节的访问权限

​ 2.指针加减跳过的字节 个数

一般指针形式

一级指针

屏幕截图 2024-11-10 154754.png

int*pointer_1说明pointer_1是一个指针变量,它所指向的对象类型是int型,实际上pointer_1只是一个存储数据的地址

当一个类型的数据的地址被另一个数据类型的指针所存储时,其读取的有效数据是有局限的。

同时我们可以通过强制类型转换将该数据的地址用其他类型的指针存储起来,但用不同数据类型所存储的数据在输出时可能无效。

image-20241110160748976.png

野指针

1.指针未初始化,导致所指向地址未知,非法访问内存

该操作可能将系统中重要内存占用,导致系统出现故障

image-20241110161943259.png

2.指针越界访问

指针访问的空间超出了已知的范围,指向未知

image-20241110162430884.png

3.指针指向内存释放及时滞空NULL;局部地址内存销毁了

image-20241110162743364.png

image-20241110162656571.png

为了避免故障的发生我们需要尽量避免野指针出现---->指针初始化,定义空指针,指针指向内存释放及时滞空NULL,避免返回局部变量的地址

1.初始化

image-20241110163130563.png

2.定义空指针

image-20241110163215191.png

3.避免返回局部变量的地址

image-20241110163619139.png

指针数组

存放指针的数组 image-20241110170147257.png prr就是存放指针(地址)的数组,称为指针数组

image-20241110163908881.png 指针数组模拟二维数组

二级指针

二级指针是指指向指针的指针。在C语言中,指针是一种变量,它存储的是另一个变量的内存地址。二级指针则存储的是一个指针变量的内存地址。

二级指针的基本概念

  • 一级指针:指向普通变量的指针。
  • 二级指针:指向指针变量的指针。

二级指针的声明和使用

声明

int **p;  // 声明一个二级指针

初始化

int a = 10;

int *ptr = &a; 

一级指针,指向变量 a

int **p = &ptr;

二级指针,指向指针 ptr

printf("%d\n", **p); 

通过二级指针访问变量 a 的值

二级指针的应用场景

  1. 动态内存分配

    • 在动态内存分配中,二级指针常用于分配二维数组或多维数组。
  2. 函数参数传递

    • 在函数参数传递中,二级指针常用于修改指针本身的值,例如在函数中修改指针指向的地址。

image-20241110164737474.png 指针比较标准:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较

​ 但是不允许与指向第一个元素之前的那个内存位置的指针相比较。

屏幕截图 2024-11-07 200954.png

指针的运算

1.指针加减整数

指针加减整数的结果是将地址向前或向后偏移几个地址

image-20241110173042066.png

2.指针加减指针

指针本质上是地址,所以指针加指针没有意义

而指针减指针则代表之间所含元素个数(只有指向相同一块空间的指针才能相减)

image-20241110173713558.png

址传递

image-20241110171800038.png

函数参数是指向实参的指针。函数内部通过指针修改实参的值,会影响调用者中的变量。

  1. exchange 函数

    exchange函数的参数arry` 是一个指向数组的指针。

    arry[0] = 333; 修改了数组的第一个元素。

    由于 arry 是指向 arr 的指针,exchange 函数对 arry 的修改会影响 arr

  2. main 函数

    exchange(arr);调用exchange函数,传递数组arr` 的地址。

    printf("%d\n", arr[0]);输出数组的第一个元素,此时已经被修改为333`。