C/指针
指针的定义
[编辑]- 指针为一种变量,存储的内容是存储器地址。
- 指针的使用会因为目的类型不同而有些微的影响。
理解指针
[编辑]指针是C语言中一个较难理解的概念,因为这个概念很接近底层。要想理解它,要从计算机底层开始。
计算机底层的存储
[编辑]在计算机内部有很多的存储单元,每个存储单元都可以存放数据。这些存储单元就像一个个小盒子,每个盒子里只能存放一个数字。
于是你看着眼前堆放的一大堆盒子,如何找到某个特定的盒子里存放的数据呢?
我们可以把盒子整齐排成一排,按顺序编号。这样,我们只需要报出编号,就能顺利找到一个盒子。
你可以想象,在计算机的虚拟世界中,有一个很高的柱子,这个柱子有很多层,每层都是一个格子,每个格子存放一个数字。这些格子按顺序编号,每个格子都有唯一的编号,用这个编号就能找到对应的格子。
无论采用哪种比喻,本质上都是相同的。内存中有很多存储单元,按顺序编号,用编号定位。这个“编号”就是“内存地址”。这就是计算机内部的内存组织形式。
指针
[编辑]所谓指针,无非是一类变量,这类变量存储的值是存储单元的地址,而不是通常的需要加工处理的数据(不过少数情况下也可能对指针进行运算)。你可以理解成:“指针”就是“指”向一个存储单元的“针”。
指针的类型
[编辑]指针的类型,其实就是指针指向的存储单元中的数据的类型。任何类型的数据,在计算机内部都不过是二进制形式的数字。存储单元可没有区分数据类型的能力。所以,为了方便使用、避免出错,C语言的设计者让指针拥有了类型,这样就可以用指针的类型来区分目标存储单元中的数据的类型。
不同类型的指针在使用时是有区别的。
现实中的计算机几乎全部是按字节编址的,也就是每个小盒子里都只能装一字节(8 个二进制位)的数据。而在 C/基本数据类型 中讲到,不同类型的数据会占用不同字节数的空间,如 int 占用 4 字节、long long 占用 8 字节。
当我们使用指针时,即操作指针指向的存储单元的值时,实际上会连同这个目标存储单元后面的几个单元一起操作,具体的单元数量取决于指针的类型。比如,操作 int 型的指针指向的存储单元,就会从目标地址开始,一同操作四个单元的数据;操作 long long 型的指针指向的存储单元,就会一口气操作 8 个单元的数据。
你可以理解成,我们认为这几个连续的存储单元中存放了某种类型的数据,于是我们定义了一个指针为这种类型,并让它指向这段存储单元的开头。这样,我们只需要操作这个指针,就可以很方便的操作这几个连续存储单元中存放的整个数据。
讲完了理论,接下来该看看实践了。
变量指针
[编辑]- 指针的声明:
int *ptr; /* 则 (int *) 为变量类型,prt 为变量名称 */
- 获取存储器地址:在变量前面使用 '&' 字符。
- 指向存储器地址:在变量前面使用 '*' 字符。
#include <stdio.h>
int main()
{
int v = 5;
int *ptr = &v;
printf("%d\n", *ptr);
}
函数指针
[编辑]函数其实也可以是指针。
#include <stdio.h>
typedef void (*MyDelegate)(int i );
MyDelegate test1( int i )
{
printf("%d\n", i );
}
MyDelegate test2( int i )
{
printf("%d\n", i+1 );
}
int main(int argc, char* argv[])
{
MyDelegate function;
function = (MyDelegate)test1;
function( 21 ); /* 等同于调用 test1 */
function = (MyDelegate)test2;
function( 21 ); /* 等同于调用 test2 */
}