您的位置:首页 > 编程语言 > C语言/C++

学习C语言指针

2009-06-17 22:57 232 查看
先看个程序,是华为2005年招聘笔试题之一

#include <stdlib.h>
main(){
int a[3]={1,2,3};
int *p,*q;
p=a;
q=&a[2];
printf(" a[p-q]=%d/n q=%d/n p=%d/n q-p=%d/n",a[q-p],q,p,q-p);
getch();
}

运行结果:
a[q-p] = 3
q = -42
p = -46
q-p = 2

6.3 指针的运算


指针的运算就是地址的运算。由于这一特点,指针运算不同于普通变量,它只允许有限的几种运算。除了上一节介绍过的赋值运算可把指针指向某一存储单元外,允许指针与整数相加、减,用来移动指针;允许两个指针相减,可以得到两个地址之间的数据个数;还允许指针与指针或指针与地址之间进行比较,可以决定指针所指向的存储位置的先后。
6.3.1 指针与整数相加减(指针的移动)
可以通过对指针与一个整数进行加、减运算来移动指针,例如:
p+n p-n p++ p-- ++p --p
等,其中n是整数。进行加法运算时,表示p向地址增大的方向移动;进行减法运算时,表示p向地址减小的方向移动。移动的具体长度取决于指针的数据类型,由计算机自动确定。设p是指向type(type代表类型关键字)类型的指针,n是整型表达式,则p±n为一个新地址,其值为p±n×sizeof(type),即在p原有值的基础上增加或减少了n×sizeof(type)字节。
例6.4
#include <stdio.h>
main()
{ int a,b,c,d;
int *pb=&b;
float x,y,z;
float *py=&y;
a=1;b=2;c=3;d=4;
x=2.5;y=3.5;z=4.5;
printf("a=%d,b=%d,c=%d,d=%d/n",*(pb-1),*(pb+1),*(pb+2));
printf("x=%f,y=%f,z=%f/n",*(py-1),*py,*(py+1));
}


本程序的运行结果为:
a=1,b=2,c=3,d=4
x=2.500000,y=3.500000,z=4.500000
程序中各变量的存储位置及指针移动情况如图6-5所示。



图6.5 指针与整数相加减(指针移动)示意图
图6.5中,指针pb存放的是整型变量b的地址(FF02),pb-1表示向地址减小的方向移动2字节(一个整型数据的长度),结果指向变量a的首字节地址;pb+2表示向地址增大的方向移动4字节(两个整型数据的长度),结果指向变量d的首字节地址。浮点型指针py存放的是浮点型变量y的地址(FF0E),py-1表示向地址减小的方向移动4字节(一个浮点型数据的长度),结果指向变量x的地址;py+1表示向地址增大的方向移动4字节(一个浮点型数据的长度),结果指向变量z的地址。因此,指针加、减一个整数后,将指向另一个地址。
初学者要注意,*p+n和*(p+n)是不同的,前者是先取值再加n,后者是先移动指针再取值。指针p进行p±n运算后,其结果得到一个新的地址,即指向了新的存储单元,而p本身的地址值并未发生变化,即它仍指向原来的存储单元(如上例中pb、py分别指向变量b和y)。当对指针进行
p++ p-- ++p --p
运算后,指针p本身的值会发生变化,即p不再指向原先的对象,而会指向新的对象。
例6.5
#include <stdio.h>
main()
{ int a,b;
int *p;
a=1;p=&a;b=10;
printf("%d/n",*p);
p++;
printf("%d/n",*p);
}


程序运行结果为:
1
10
在进行p++之前和之后,各变量的存储位置分别如图6.6(a)和图6.6(b)所示。



图6.6 指针p++运算示意图
从图中可以看出,在进行p++运算之前,p指向变量a(p值为FF00),在进行了p++后,p指向变量b(p值为FF02)。
③由于*和++同属一个优先级,其结合性均为从右至左,因此*p++与*(p++)等价,但不与(*p)++或++(*p)等价。

6.3.2 两个同类型指针相减

两个同类型的指针可以相减。如果这两个指针之间所存储的数据的类型也与指针相同(通常是数组的情况),则相减的结果是这两个指针之间所包含的数据个数。显然,两个指针相加是无意义的。
例6.6
#include <stdio.h>
main()
{ float x[0];
float *p,*q;
p=&x[0];
q=&x[5];
printf("q-p=%d/n",q-p);
}


程序运行结果为:
q-p=5
6.3.3 指针的比较
两个同类型的指针,或者一个指针和一个地址量可以进行比较(包括>、<、>=、<=、==和!=),比较的结果可以反映出两个指针所指向的目标的存储位置之间的前后关系,或者反映出一个指针所指向的目标的存储位置与另一个地址之间的前后关系。
例如,假定指针p和q都是指向同一数组的成员,那么关系表达式
p
表示:如果p所指向的数组元素在q所指向的数组元素之前,其值为1;否则,为0。
不同类型指针之间或指针与一般的整型数据之间的比较是没有实际意义的。但是指针与零之间进行等于或不等于的比较,即
p==0 或 p!=0(0也可以写成/0''或NULL)
常用来判断指针p是否为一空指针(即未指向任何目标)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: