让我们用希望更熟悉的数据类型替换“指针”一词,例如int
:
int n = 42;
这里 42 是一个int
值,以及n
是一个变量,其中包含int
。你可以打电话n
an "int
变量”。int 是像 42 或 -25315685 这样的数字,并且int
变量保存这些数字。一旦你有了一个变量,你就可以给它分配不同的数字。到目前为止没有什么令人困惑的事情吗?
A pointer就像一个 int: 一个数字。它恰好是一个标识内存位置的数字,如果该内存位置中存储了某些内容,您可以将其称为address。与 int 类似,指针可以存储在变量中。存储指针的变量可以称为指针变量。
So, 指针和指针变量有什么区别?第一个是一个值,例如数字,第二个存储这些值。但人们通常通过变量存储的值来引用变量;人们不打电话n
an "int
变量”,但只是int
,即使它可以在不同的时间存储不同的int
s。在本文中,我将做同样的事情,有时当我指的是指针变量时写为指针;希望这种区别是清楚的。
指针总是地址吗?这是一个关于“地址”一词含义的问题。指针始终是一个地址,因为它以某种方式对应于一个内存位置,它是该内存位置的“地址”。但另一方面,如果程序无法访问该内存位置或者其中没有存储任何有用的内容,那么它真的是任何东西的“地址”吗?
现在让我们研究以下代码:
int *p;
p = &n;
第一行声明一个指针变量,名为p
。可以存储的指针p
是内存位置int
数据;这很重要,原因我们稍后会看到。我们还是不给p
任何值,因此它存储的指针是任意的。它当然不存储任何有用的地址;它甚至可能指向程序无法访问的内存区域。
在第二行中,我们获取的地址n
变量与&
- 运算符并将其分配给p
. Now p
存储地址n
,值所在的内存位置n
被储存了。
我们可以用指针做什么?我们可以读取和写入指针标识的内存位置。为此,我们“取消引用”指针*
- 运算符,然后(*p)
可以像你一样使用n
。例如,您可以将新值写入n
有了这个:
*p = 123;
正是在这一点上,为什么我们需要知道数据的类型就变得显而易见了。p
可以指向:否则你不知道可以分配给什么(*p)
.
了解数据类型很重要的另一个原因p
可以指向的是指针算术。例如p+1
是一个指向int
之后立即存储在内存中n
; if p
是一个指向大数据结构的指针p+1
将是一个指向紧随其后存储的相同类型数据结构的指针。为此,编译器必须知道指针指向的内容的大小。