C语言:深入理解指针(1)

1. 内存和地址

在了解指针前,我们需要知道内存和地址是什么。

1.1 内存

首先来看内存。举个例子:当你在酒店找房间时,你并不是一层一层一间一间找,而是通过酒店为每间房子设置的门牌号直接找到你的房间,这样的效率就会快很多。

把上面的例子投影到计算机中:CPU在处理数据的时候,需要在内存中取数据,处理后的数据又会放回到内存中。内存空间管理时就会把内存划分为一个个内存单元,每个内存单元大小设置为一字节。每个内存单元也有其相应的编号,这样CPU就可以通过编号快速找到一个内存单元。这个编号在计算机中我们称它为地址 。C语言中给地址起了个新的名字,叫指针 。因此我们可以理解为:内存单元的编号==地址==指针

1.2 如何理解编址

首先,需要知道,计算机内部是有很多硬件单元的,各个硬件单元相互工作时是通过"线"连接起来的。而CPU和内存之间也是有⼤量的数据交互的,所 以,两者必须也⽤线连起来。我们今天只关心地址总线(还有数据总线和控制总线)。当CPU在访问某个内存单元时,必须知道该内存单元在哪个位置,因此需要给每个内存单元进行编址。

计算机中的编址,并不是把每个字节的地址记录 下来,⽽是通过硬件设计完成的。就像吉他和钢琴等乐器一样,琴弦和钢琴键上并没有标注 do、re、mi......。但是演奏者总能精准地找到在什么位置,这是大家约定俗成的。

硬件编制也是如此,32位机器就有32根地址总线,每一位都有 0 和 1 两种结果,32根像就能表示出 2 的 32 次方种结果,每一种排列都表示一个地址,64位机器以此类推。地址信息被下达给内存,在内存上,就可以找到 该地址对应的数据,将数据在通过数据总线传⼊ CPU内寄存器。

2.指针变量和地址

2.1 取地址操作符(&)

在C语言中创建变量的本质就是向内存申请空间。如图:

右下角的内存中 & 为取地址操作符,图中为取出 x 的地址,是一个单目操作符。我们之前学的 a&b 表示 a 按位与 b ,两者不一样。上述代码就是创建了一个整型变量 x ,在内存中申请了 4 个字节用来存放 4。当我们打印 x 的地址时,就会发现这个内存单元中正好存放的是 4。

2.2 指针变量和解引用操作符

2.2.1指针变量

我们通过取地址操作符(&)得到一个变量的地址,我们通过指针变量将它存放起来,便于使用例如:

复制代码
#include <stdio.h>
int main()
{
    int x = 4;
    int * p = &x;//取出x的地址放到指针变量p中
    return 0;
}

指针变量也是一种变量,只不过让它是用来存放地址的,变量中的值都是地址。

2.2.2 如何理解指针变量

刚刚的定义的 int * p 中,* 说明 p 是一个指针变量,int 表示 p 指向的的类型是整型。同理如果有个 char、double、等类型的变量,他们的地址就要分别放在 char*、double* 中。

2.2.3 解引用操作符

我们将地址存起来肯定是要使用的,使用时我们就会用到解引用操作符(*)。

上图中就使用了解引用操作符我们通过 *p 找到了 x 并且修改了 x 的值,我们修改时并没有写 x = 0 ,而是直接通过指针变量来修改,即 *p=0 ,这样写代码时会更加灵活。

2.3 指针变量的大小

32位机器有32根地址总线,那么它就需要 4 个字节来存储地址(1个字节 8 个比特位,4个字节刚好 32 个比特位),同理 64 位机器则需要 8 个字节来存储地址。同时我们要注意**指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。**不管指针变量是 char 还是 int ,他们在32位机器下都是 4 个字节,在 64 位机器下都是 8 个字节。

3.指针变量类型的意义

3.1指针的解引用

让我们来对比下面两段代码:

我们发现 int* 和 char* 修改的字节不同,因此:指针的类型决定了对指针解引用的时候有多大的权限(⼀次能操作⼏个字节)。 ⽐如 char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引⽤就能访问四个字节。

3.2 指针+-整数

同样的,对指针+-时,不同的指针变量的类型所移动的距离也不同。若对 int* 进行+/-1时,会一次移动四个字节,而对 char* 进行+/-1时则一次移动一个字节。

3.3 void*指针

void* 表示无具体类型的指针。这种类型的指针可以接受任意类型的地址,但是我们不能直接对这种类型的指针进行+/-整数和对指针的解引用,需要进行强制类型转换。⼀般 void* 类型的指针是使⽤在函数参数的部分,⽤来接收不同类型数据的地址,这样的设计可以实现泛型编程的效果。使得⼀个函数来处理多种类型的数据。

4.指针运算

4.1 指针+-整数

数组在内存中是连续存放的,因此只要知道第⼀个元素的地址后,我们可以通过加减操作来获取后面的所有元素。

4.2 指针-指针

由图可得,指针-指针所得带的结果是两个指针之间的元素个数,但前提是这两个指针指向的是同一块内存空间。

另外,指针也能进行关系运算。

相关推荐
Dxy12393102163 小时前
Python观察者模式详解:从理论到实战
开发语言·python·观察者模式
阿捏利4 小时前
【加解密与C】Rot系列(四)Rot47
c语言·rot47
不写八个5 小时前
GoLang教程005:switch分支
开发语言·后端·golang
ZeroToOneDev5 小时前
Java(LinkedList和ArrayList底层分析)
java·开发语言
吃饭只吃七分饱6 小时前
C++第8章:IO库
开发语言·c++
宴之敖者、7 小时前
数组——初识数据结构
c语言·开发语言·数据结构·算法
青小莫7 小时前
c语言-数据结构-二叉树OJ
c语言·开发语言·数据结构·二叉树·力扣
典学长编程7 小时前
Java从入门到精通!第十一天(Java常见的数据结构)
java·开发语言·数据结构
后端小张7 小时前
智谱AI图生视频:从批处理到多线程优化
开发语言·人工智能·ai·langchain·音视频
m0dw7 小时前
js迭代器
开发语言·前端·javascript