1、取地址运算与赋值运算
取地址运算的运算符是“&”,前面学习 scanf函数时已经使用过该运算符,其一般形式为&变量。
取地址运算符是单目运算符,其作用是返回其后的变量(包括数组元素)的地址。register存储类型的变量不能使用“&”返回地址。
例如:
int *pa,*qa,a=10;
pa=&a;//获得变量a的地址并赋值给指针变量pa
double *pd,d;
pd=&d;//获得变量d的地址并赋值给指针变量pd
对指针变量进行赋值运算时,要求赋值运算符右边表达式的地址类型与左边指针变量的类型相同。如果不相同,编译器会给予警告,程序运行过程中可能会发生错误。
相同类型的指针变量之间也可以进行赋值,例如:
qa=pa;
2、取内容运算
取内容运算的运算符是“*”,其一般形式为:
*指针表达式
取内容运算符是单目运算符,其后的“指针表达式”运算结果是一个“地址”。该运算符
也称为“间接访问运算符”,其作用是访问“指针表达式”计算出的地址对应的存储单元。
例如
int *pa,a=10;
pa=&a; //指针变量pa指向变量
*pa=100;//间接访问变量a,是给变量a赋值100
【例1】阅读并分析下面程序。源代码如下
#include<stdio.h>
int main()
{
int x,*p;
p=&x;
printf("p=%p,&x=%p\n",p,&x);
*p=100;
printf("x=%d,*p=%d\n",x,*p);
x=200;
printf("x=%d,*p=%d\n",x,*p);
return 0;
}
程序运行结果:
说明:在不同的计算机系统上运行程序,第1行输出的地址可能不同的。
取地址运算符是获取一个内存单元的地址,取内容运算符是间接访间一个地址的对应的存储单元中存放的值。这两种运算可以进行混合运算,例如,给定如下指针变量的定义
int *p, a=10;
p=&a;
表达式“*&a”计算结果是10,计算过程是先计算&a,获得a的地址,然后对该地址进行间接访问得到最终结果是a的值10,因此,*&a等价于a。
表达式“&*p”计算结果是变量a的地址,计算过程是先计算*p(间接访问a),再获取地址时,得到的就是变量a的地址,因此,&*p等价于p。
3、指针表达式与整数进行加减运算
指针表达式可以加或减一个整型数据,其形式为
p+n
p-n
上面表达式中,p为指针表达式,n是整型表达式。其作用是使指针变量p值变成当前指向储存单元地址的后面(或前面)的第n个存储单元的地址。变量p的数值大小变化规则是:
p+n的值=p的值+p指向类型的字节数*n
p-n的值=p的值-p指向类型的字节数*n
同样,可以使用自增(自减)运算符实现加1(减1)的效果。
【例2】阅读并分析以下程序。
源代码如下:
#include<stdio.h>
int main()
{
int x,*px;
double y,*py;
px=&x;
py=&y;
printf("px=%p,py=%p\n",px,py);
px=px+3;
py--;
printf("px=%p,py=%p\n",px,py);
return 0;
}
程序运行结果:
说明:地址是以十六进制形式输出的,观察输出结果发现px的值增加了12,py的值减少了8。在不同的计算机上运行时,具体输出结果可能不同,但增加或减少的差值是不变的。