1.间接访问运算符*和取地址运算符&
& 取地址运算符
* 间接访问运算符(或称“指针运算符”)
例如:
&a为变量a的地址,*p为指针变量p所指向的变量。
在C语言程序中,间接访问运算符“*”出现的位置不同,含义也不同。
● *出现在指针定义的语句中,这时表示定义的变量是一个指针变量。
● *出现在程序的其他语句中,表示取指针变量所指向的变量的值。
取地址运算符&表示取出变量的地址。地址运算符&操作的对象只能是变量,不能是表达式。
运算符*和&的优先级相同,按自右向左方向结合。
例如:
int a=8, b=12; // 整型变量a的初始值为8,整型变量b的初始值为12
int *p1, *p2, *p3; // p1,p2,p3是指向整型变量的指针
p1=&a; // 将变量a的地址赋给 p1,即p1指向整型变量a
p2=&b; // 将变量b的地址赋给 p2,即p2指向整型变量b
b=*p1; // 将p1指向的整型变量a的值8,赋给变量b。等价语句“b=a;”
p3=&*p1; // 等价语句为“p3=&a; ”,p3也指向整型变量a
表达式“&*p1”的含义是:先进行*p1运算,就是变量a,再进行&运算。因此“&*p1”与“&a”含义相同。
2.二级指针
可以定义一个指针变量,它所指向的变量本身就是一个指针变量,这个指针就是一个指向指针的指针。这样定义的指针称为二级指针。定义的形式如下:
基类型 **指针变量名;
例如
int a=15; //整型变量a的初始值为15
int *p1=&a; //定义指针变量p1并初始化,p1指向变量a
int **p2=&p1; //定义二级指针变量p2并初始化,p2指向指针变量p1
printf("%d,%d,%d\n",a,*p1,**p2); //输出的3个变量的值均为15
3.两个指针变量相减
两个指针变量相减,用于表示两个地址间存放的数据对象的个数,而不是地址的绝对值的差。例如:
int a[6]={0}; // 定义一维数组a,初始化a的6个元素值均为0
int *p1=&a[0], *p2=&a[5]; //指针变量p1赋a[0]地址值,指针变量p2赋a[5]地址值
printf("%d\n", p2-p1);
输出结果为5,表示两个地址间存放了5个整数数据。(www.xing528.com)
需要注意的是,两个指针相加,即两个地址值相加没有什么物理意义。
4.指针变量的自加自减运算
指针变量的自加自减运算,可以很方便地实现指针的偏移,通常用在循环中。
例如:
其中的for循环语句也可以改写成如下形式:
*p++表示先取指针p指向的值,然后指针偏移。这种表达式十分常见,它等价于
*(p++),但要注意*p++与*(++p)和 (*p)++的区别。
*(++p)表示先p=p+1,再取指针P指向的值。
(*p)++表示将指针p指向的值加1,指针本身并无变化。
5.下标运算[ ]和取地址运算&
指针的间接引用运算和下标运算功能是相同的。例如:
p[0]等价于*p
p[i]等价于*(p+i)
下标运算[ ]与取地址运算&,又是互逆的。例如:
&p[0]、p、&*p也是等价的。
正是因为指针语法的灵活性,给初学者带来很多困难,但掌握后,使用起来也会十分方便。
6.两个指针变量的关系运算
(1)指向同一数组的两个指针变量进行比较
指向同一数组的两个指针变量进行关系运算,可以表示它们所指数组元素之间的关系。
例如:
int a[6]={0};
int *p1=a, *p2=&a[3];
printf("%d\n", p1==p2); // 输出0,表示p1和 p2所指元素地址不相同
printf("%d\n", p1<p2); // 输出1,表示p1所指元素地址低于p2所指元素地址
printf("%d\n", p1>p2); // 输出0,表示p1所指元素地址不高于指针p2所指元素地址
通常两个或多个指针指向同一数组(如一串连续的存储单元)元素时,比较才有意义。
(2)指针变量与0进行比较。、
设p为指针变量,则p==0表示p为空指针,它不指向任何变量;p!=0表示p不是空指针。空指针是由对指针变量赋予0值而得到的。
例如:
#include <stdio.h>
int *p=Null; // p为空指针
对指针变量赋0值与不赋值是不同的。指针变量未赋值时,称为野指针可以是任意值,是不能使用的。否则会造成意外错误。而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。