您的位置:首页 > 其它

理解指针之基础篇

2012-04-08 22:30 127 查看
理解指针

指针是程序开发中经常使用的类型,然而却对它的概念一直迷迷糊糊的,经常犯一些莫名其妙的错误,甚至对一些用法不知其意。今天看了一些指针的文章,做一下总结。

什么是指针

int * a;

准确的说,指针也是一种变量,特殊的是该类型变量存储的是内存地址。举个例子.
上述表达式中,指针a指向了一个整形变量,上述表达式映射到内存中,其存储方式如图1所示:



图1
从图1中可以看出,指针a的值为10004688,内存中地址10004688处存储了值为5的整形,我们说指针a指向的整形值为5.

char * c;

float* f;

bool* b;

当然指针指向的值也可以是其他类型,比如如下类型:
那么,既然都是指针类型,那么他们之间能进行复制吗?比如c = f.答案是否定的。虽然他们都是指针,但是他们指向的具体类型是不一样的,编译器在编译时,会检查指针所指向的具体类型,当指向的具体类型不一样,是无法编译通过的.因此有必要更加具体的说明指针的类型,我们称之为指针类型。也就是说,虽然指针的值都是内存单元地址,但是它们的类型还是各不相同的,如果上面的几个例子来说,a的类型是int*,c的类型是char*,以此类推.

int g;

char h;

既然指针也是有类型,那么如何确定指针是什么类型的呢?很简单,获取普通变量的类型方法一样.见如下代码:

Int* i;

Char* j;

g的类型是int,h的类型是char,只要去掉变量名便可获得变量类型,对于指针也是如此,见如下代码:
去掉变量名后,i和j的类型分别是int*和char*,此时我们说i的类型是int*,j的类型是char*。既然指针有类型,那么我们如何声明一个指针呢?声明的方法也很简单,只需在普通类型后加*便可.比如我们要声明一个双精度类型的指针.只需按如下方法书写即可.

double* a;

通过上述说明相信你应该明白了指针变量的值、指针变量的类型、指针所指向的值一直指针所指向的值的类型.理解这些概念后,你对指针就有了初步的了解。下面我们将进一步介绍指针与数组的关系.

指针与数组

Int arr[10] = {1,2,3,4,5,6,7,8,9,10};

我们经常用指针来操作数组,因此有必要介绍一下指针与数组的关系.分析如下数组:
上述代码中定义一个数组,该数组中含有10个int类型的成员,该数组在内存中的镜像如图2:



图2
从图2中可以看出arr内存储了一个内存地址,该地址为数组的首个元素地址。因此,arr也是一个指针,该指针指向的即是数组的首个元素.同样的我们可以看出,由于数组的内容连续的存放在内存空间中,因此只要通过简单的运算,以arr的值作为基值,便可得出数组第二个元素、第三个元素的地址,从而获取或修改其值.下面我们就将介绍指针如何运算.

指针的运算

Int arr[10] = {1,2,3,4,5,6,7,8,9,10};

Int* p;

p = arr + 1;

上面介绍到数组的名称,也是指向数组第一个算是的指针,我们可以通过这个指针的运算,获取其他元素的内存地址。那么具体的是如何获取其他元素的内存地址呢?方法很简单,比如获取第二个元素的地址代码如下:
上述代码中,我们定义了一个int*类型的指针p,并将p赋值为arr+1.此时指针p便指向了数组的第二个元素.请注意,此处不能对指针arr进行操作,如arr++或arr
= arr+1是非法的,因为arr使用指向数组的首个元素,如果它的值发生改变,将不一定指向数组的首个元素,因此它是不可被修改的.

int _tmain(int
argc, _TCHAR*
argv[])

{
int
arr[10] = {1,2,3,4,5,6,7,8,9,10};
int*
p;
p =
arr + 1;

printf("arr:
%d\n",arr);
printf("p:
%d\n",p);

int
wait;
scanf("%d",&wait);
return 0;
}

对于上述代码中p = arr + 1,是不是表示p的值为10006689呢?答案是否定的,此处的加1,代表加一个单位指针所指向的类型长度.对于上式,指针指向的类型是int,int类型在内存中占4个字节,因此p
= arr + 1后p的值将比arr的值多4,变成10006682;验证程序如下:
运行结果如下:



由上可知,对于字符型的指针来说char* c; c++后,c的值将比原来多2,因为字符在内存中占用两个字节.以此类推可以得出其他类型,进行指针运算后,其值的变化情况.

获得指针后,我们便可以通过指针来获取,指针所有指向的内存单元的值了,那么如何取值呢?

取值与取址

通过指针运算得到一个新地址后,地址本身对我们没什么意义,有意义的是该地址处,存放的值,那么如何取值呢?c语言为我们提供了取值符号*,该符号与指针定义时使用的符号一样.只不过放的位置有点区别,指针定义时,*号是放在类型之后,表示该类型指针,取值的时候,指向把*号放于指针变量之前即可.如对于上述数组指针运算,如果想取得第二个元素的值,直接使用*p即可。与取值向对应的是取址,即获取一个指定变量所存放的内存地址,C语言为取址提供的符号是&,想获得某个变量的地址时,指向将&放于其前即可.下面的代码展示了如何取值和如何取址:

int _tmain(int
argc, _TCHAR*
argv[])

{
int
a = 5;
int*
b;
b = &a;
printf("%d\n",&a);
printf("%d\n",b);
printf("%d\n",*b);

int
wait;
scanf("%d",&wait);
return 0;
}

运行结果如下图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: