5.2.3 取址运算符和取值运算符
通过指针变量来访问其所指向的变量,需要首先定义该指针变量。在程序中使用指针变量时,常会用到与指针变量有关的两个运算符,即取址运算符“&”和取值运算符“*”,其具体用法介绍如下。
1.取址运算符“&”
取址运算符“&”用于取变量的首地址。取址运算符是单目运算符,符合自右至左的结合性。在上一节中,已经使用了&运算符,其表示形式如下所示。
&变量名
其中,在“&”运算符后的变量是指针变量所指向的变量。该语句的含义是获得变量在单片机内存中的实际地址。示例如下。
int a=10,*p=&a;//定义整型变量a和整型指针变量p,使p指向a
本例中,a的值为10,假设a在内存中的实际地址为2000H,因为&a的值即为变量a的地址,所以&a=2000H。所以指针p的内容即为2000H。其赋值操作时的指针指向如图5.5所示。
由图中可看出,&a=2000H,*p=10。虽然不能将数据直接赋值给指针,但是该指针所指向的内存单元存储了变量数据。
图 5.5 *p=&a的情况
2.取值运算符“*”
取值运算符“*”用来表示指针变量所指向的内存单元中的内容。取值运算符也是单目运算符,符合自右至左的结合性。其表示形式如下所示。
*指针变量名
其中,“*”运算符后的变量是指针变量。该语句的含义是获得指针变量所指向的变量在内存中的数值。
在指针变量定义中也曾出现过该符号“”,它和取值运算符“”是有区别的。在指针变量的定义中,“”是类型说明符,表示其后的变量是指针类型的变量。而表达式中出现的“”,则是一个取值运算符,用来表示指针变量所指向的地址中的数据值。取值运算符“*”的程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
int x=5,y,p=&x;//指针变量p指向变量x,则p等价于x
y=*p+20;//表示把x的值加20并赋给y,即y=x+20
printf(“y=%d\n”,y);//输出y的值
y=++p;//p的内容加上1之后赋给y,即y=x+1
printf(“y=%d\n”,y);//输出y的值
y=*p++;//先将x的值赋给y;然后x再加1;
printf(“y=%d\n”,y);//输出y的值
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下所示。
y=25
y=6
y=5
从上例中可以看出,与直接访问一个变量相比,通过指针访问显得不直观,因为通过指针要访问的变量,取决于指针的值,也就是通过间接访问的形式进行。使用指针访问变量时,要认真分析指针变量的指向,但是使用指针有其优势,程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
int a=1,b=2,p2,p1;//定义变量并赋值
p1=&a;//指针变量p1指向a
p2=&b;//指针变量p2指向b
p2=p1;//等价于b=a,将a的值赋给b
p1=p2;//使p1、p2指向b
}
在本例中,语句p2=p1实际上就是将p1所指向变量a的值赋给p2所指向的变量b,即等价于“b=a”。而p1=p2使p1指向p2所指向的变量,这样p1和p2就指向相同的对象b。此时*p1等价于b,而不是a。
在实际的程序设计中,通过改变指针变量的指向,来间接访问不同的地址,而不改变地址中变量的值,这样可以使程序代码更为简洁。