《指针计算机基础知识.ppt》由会员分享,可在线阅读,更多相关《指针计算机基础知识.ppt(142页珍藏版)》请在三一办公上搜索。
1、指针,指针的故事,“该程序执行了非法操作,即将关闭”这种错误几乎全是由指针和数组导致的黑客攻击服务器利用的bug绝大部分都是指针和数组造成的,主要内容,1.地址和指针的概念 2.变量的指针和指向变量的 指针变量 3.数组与指针 4.字符串与指针 5.指向函数的指针 6.返回指针值的函数 7.指针数组和指向指针的指针,地址,内存中每一个字节的存贮单元都有一个编号,这个编号就是“地址”。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配存贮单元。,.按变量地址存取变量值的方式称为“直接访问”方式(,);(,);,将每个数据的首字节地址作为该数据的地址。,内存是一个连续编址的空间
2、,每一个存储单元都有一个固定的编号,这个编号称为地址。地址是一个无符号整数(通常用16进制数),其字长与主机相同,例如:已定义了一个整型数组d6。设该数组的起始地址为ee10(d0的地址),赋值d0=10。数组名是一个常量地址,也为ee10,2000 2002 2004,用户内存数据区,(1)求地址运算(&)每个变量/数组都有一个内存地址,在何地址一般无法预测。可通过求地址运算得到。,2、求地址运算和访问地址运算,例:#include main()int a=1;float b=2.0;double c=3;int d6=-1,-2,-3,-4,-5,-6;printf(“address of
3、 a is%xn”,说明:输出的地址值 用4位十六进制数表示。&只能施加在变量或数组元素上。&25&(x+y)均是错误的,采用访问地址的方法存取数据,速度快,效率高。,将地址存放在一种特殊类型的变量中,把对地址的操作转换为对变量的操作。,存放地址的变量指针变量指针变量中存放的地址指针,变量地址:变量一定占用一个数据的存储空间,该存储空间的首地址称变量地址。指针:一个变量的地址称为该变量的指针。指针变量:若一个变量专用于存放另一个变量 的地址(指针),则该变量称为指 针变量。指针的对象:指针指向的存储空间中的数据。,指针的概念,指针变量是存放地址的变量,它的值是指针,指针所指向的变量是指针变量所
4、指向的存贮单元中的内容,指针变量,指针所指向的变量,10.1 定义一个指针变量,定义指针变量的一般形式为基类型*指针变量名;int i,j,*pointer_1,*pointer_2;/基类型是int下面都是合法的定义:float*pointer_;char*pointer_;,指针变量的引用(1)指针变量只能存放地址,不能将整型数据、字符型数据、实型数据等非地址类型的数据赋值给指针变量。(2)指针变量只能指向同一类型的变量。int a=8;char h=A;int*p1;char*p2;p1=,int a,*p;p=*p=5;,(1)&a 表示取a变量的地址。*p则表示指针变量p所指的对象a
5、。,*p,*&a,&*p,相关的运算符 取地址运算符:&指针运算符(或间接访问运算符):*,(2),(5)(*p)+等价于a+。(6)&与*互为逆运算,当与&连续在一起时,具有抵消作用:*&a=a,&*p=p.,7、指针变量的赋值运算用取地址运算符(,将一个指针变量赋给另一个同类型的指针变量。,int i,pi,pj;,pi=,pj=pi;,作用是使 pi,pj 都指向变量 i。,&i,&i,给指针变量(pi)赋“空”值:,a.pi=NULL;,b.pi=0,c.pi=0,在定义一个变量时,将变量的指针(即地址)直接赋给指针变量:,int x,p=,可以用赋值语句使一个指针变量得到另一个变量的
6、地址,从而使它指向一个与基类型相同的变量。例如:pointer_;pointer_;,在定义指针变量时要注意两点:,10.2.2 指针变量的引用,1.给指针变量赋初值 int*p,*q;int a=10;(1)q=/让p指向q所指向的存贮单元,a,q,10,10.2.2 指针变量的引用,1.给指针变量赋初值 int*p,*q;int a=10;(1)q=/让p指向q所指向的存贮单元,a,q,10,10.2.2 指针变量的引用,1.给指针变量赋初值 int*p,*q;int a=10;(1)q=/让p指向q所指向的存贮单元,a,q,p,10,注意:指针变量中只能存放地址(指针),不要将一个整数(
7、或任何其他非地址类型的数据)赋给一个指针变量。,2.访问指针变量所指向的变量printf(“%d”,*p);说明:(1)定义指针变量后,变量没指向任何存贮单元,要通过赋值语句来确定它所指向的存贮单元(2)&,*的优先级相同,结合方向自右向左,为互逆操作&*p p,*&a a,(3)(*p)+与*p+的区别 前者是为p所指向的变量+1,后者满足右结合,p+后执行*操作,但+是后加,所以先使用*p的值,然后再对p进行+1操作*(+p)?,例10.1 通过指针变量访问整型变量#include void main()int a,b;int*pointer_1,*pointer_2;a=100;b=10
8、;pointer_1=,100,10,例10.2 输入和两个整数,按先大后小的顺序输出 和。,#includemain()int a,b,*p1,*p2,*p;scanf(%d%d,例10.2 输入和两个整数,按先大后小的顺序输出 和。,#includemain()int a,b,*p1,*p2,*p;scanf(%d%d,a,b的值没发生变化!,p=p1;p1=p2;p2=p;,&a,p=p1;p1=p2;p2=p;,&a,&b,p=p1;p1=p2;p2=p;,&a,&b,&a,p=p1;p1=p2;p2=p;,&b,&a,p=p1;p1=p2;p2=p;,*p1=9,*p2=5a=5,b
9、=9,10.3 指针变量作为函数参数,例10.3 交换两个变量的值,#includemain()void swap(int*p1,int*p2);int a,b;int*pointer_1,*pointer_2;scanf(%d%d,void swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;,void swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;,void swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;,voi
10、d swap(int*p1,t*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;,如果将swap函数做如下修改:,void swap(int*p1,int*p2)int*temp;temp=p1;p1=p2;p2=temp;,如果将swap函数做如下修改:,void swap(int*p1,int*p2)int*temp;temp=p1;p1=p2;p2=temp;,没有实现交换操作!,void swap(int*p1,int*p2)int*temp;temp=p1;p1=p2;p2=temp;,void swap(int*p1,int*p2)int*temp;te
11、mp=p1;p1=p2;p2=temp;,void swap(int*p1,int*p2)int*temp;temp=p1;p1=p2;p2=temp;,&a,&b,9,5,9,5,5,9,使用指针做形参的说明,如果要通过函数调用得到n个要改的值,要经过以下步骤:(1)主函数中设n个变量,并用n个指针变量分别指向它们(2)用指针变量作形参(3)通过形参指针变量,改变n个实参的值(4)主调函数中使用这些改变了值的变量,上节课小结,1.指针与指针变量2.指针所指向的变量3.用指针访问其所指向的变量4.用指针变量做为函数的形参,int*p,i;p=*pi,*pvoid swap(int*p,int*
12、q),例10.输入,3个整数,按从大到小顺序输出,#include void main()void exchange(int*q1,int*q2,int*q3);int a,b,c,*p1,*p2,*p3;scanf(%d%d%d,void exchange(int*q1,int*q2,int*q3)void swap(int*pt1,int*pt2);if(*q1*q2)swap(q1,q2);if(*q1*q3)swap(q1,q3);if(*q2*q3)swap(q2,q3);void swap(int*pt1,int*pt2)int temp;temp=*pt1;*pt1=*pt2;*
13、pt2=temp;,10.3 数组与指针,一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。,定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:int a10;int*p;a0;,10.3.1 指向数组元素的指针,p=a;,p+i,&ai,*(),10.通过指针引用数组元素,引用一个数组元素,可以用:()下标法,如ai形式或pi(但要先执行p=a);()指针法,如*(a+i)或*(p+i)。其中是
14、数组名,是指向数组元素的指针变量,其初值。(3)p=a;p+,用*p访问数组元素,说明:(1)指针可以实现+和-操作,但数组名不可以,因为数组名是一个指针常量(2)p+代表指针移向下一个数组元素,而不是一个存贮单元,int型下移两个单元,float型下移4个单元,假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:(1)下标法。(2)通过数组名计算数组元素地址,找出元素的值。(3)用指针变量指向数组元素。,例10.5 输出数组中的全部元素。,(1)下标法。main()int a10;int i;for(i=0;i10;i+)scanf(“%d”,(1)下标法。main()int a10
15、;int i,*p;for(i=0;i10;i+)scanf(“%d”,(2)通过数组名计算数组元素地址,找出元素的值。main()int a10;int i;for(i=0;i10;i+)scanf(“%d”,(2)通过数组名计算数组元素地址,找出元素的值。main()int a10;int i,*p;for(i=0;i10;i+)scanf(“%d”,(3)用指针变量指向数组元素。main()int a10;int*p;int i;for(i=0;i10;i+)scanf(%d,(4)用-操作实现逆向输出元素,void main()int a10;int*p;int i;for(i=0;i
16、=a;p-)printf(%5d,*p);,例10.通过指针变量输出数组的个元素。,main()int a10,*p,i;p=a;for(i=0;i10;i+)scanf(%d,p+);for(i=0;i10;i+,p+)printf(%dn,*p);,main()int a10,*p,i;p=a;for(i=0;i10;i+)scanf(“%d”,p+);p=a;for(p=a;i10;i+,p+)printf(“%d”,*p);,10.3.3 用数组名作函数参数,在第8章8.7节中介绍过可以用数组名作函数的参数如:void main()(int arr,int);int array;(ar
17、ray,);void(int arr,int),例10 将数组中个整数按相反顺序存放。,main()int a10=1,2,3,4,5,6,7,8,9,10;int i;inv(a,10);for(i=0;i10;i+)printf(%3d,ai);printf(n);,void inv(int x,int n)int*i,*j;int temp,m;m=n/2;i=x;j=x+n-1;for(;ix+m;i+,j-)temp=*i;*i=*j;*j=temp;,对刚才的程序可以作一些改动。将函数inv中的形参改成指针变量。,void inv(int*x,int n)int temp,*i,*
18、j,m=(n-1)/2;i=x;j=x+n-1;for(;i=x+m;i+,j-)temp=*i;*i=*j;*j=temp;,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:,(1)形参和实参都用数组名,如:void main()void(int,int)int;(,);,(2)实参用数组名,形参用指针变量。如:void()void(int*,int)int;(,);,(3)实参形参都用指针变量。例如:void main()void(int*,int)int,*p=a;(p,);,(4)实参为指针变量,形参为数组名。如:void main()void(
19、int x,int),*p=a;(p,);,例10.从10个数中找出其中的最大值和最小值,int max,min;void max_min(int array,int n)int*p,*array_end;max=min=*array;array_end=array+n;for(p=array+1;pmax)max=*p;else if(*pmin)min=*p;,main()int a10=6,7,8,1,2,3,4,5,9,10;max_min(a,10);printf(max=%3d,min=%3dn,max,min);,10.3.4 多维数组与指针,用指针变量可以指向一维数组中的元素,
20、也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。,复习一维数组与指针之间的关系,int a10,*p;p=a;p=,p,p+i,1.多维数组元素的地址,先回顾一下多维数组的性质,可以认为二维数组是“数组的数组”,例:定义int a34=1,3,5,7,;则二维数组a是由3个一维数组所组成的。,a0,a1,a2,a,a+1,a+2,a+i=&ai,(1)a,a+1,a+2分别代表&a0,&a1,&a2,a0,a1,a2,a+i=&ai,(2)a0,a1,a2分别代表&a00,&a10,&a20,a0,a1,a2,a,a+1,a+2,a+i=&ai,a2+
21、1,a2+2分别代表&a21,&a22,ai+j,(3)&aij,a0,a1,a2,a,a+1,a+2,a+i=&ai,*(a+i)+j,&aij,*(a+i)=ai,ai+j,a0,a1,a2,a,a+1,a+2,a+i=&ai,*(a+i)+j,(4)&aij,*(a+i)=ai,a0,a1,a2,a,a+1,a+2,a+i=&ai,*(*(a+i)+j),(5)*(&aij),*(a+i)=ai,a0,a1,a2,a,a+1,a+2,a+i=&ai,*(*(a+i)+j),(5)aij,*(a+i)=ai,a0,a1,a2,a,a+1,a+2,a+i与*(a+i)有什么区别?,小结,(1
22、)a,a+1,a+2分别代表&a0,&a1,&a2(2)a0,a1,a2分别代表&a00,&a10,&a20(3)ai+j 代表&aij(4)*(a+i)+j代表&aij(5)*(*(a+i)+j)代表aijai从形式上看是一维数组的第i个分量,但当a为二维数组时,ai只代表一个地址,2.指向二维数组的指针变量,(1)用指针变量输出数组元素的值 main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int*p;/printf(%on%on%on%on,a,a0,用普通的指针变量输出数据元素时,要先二维数组序列化为一维,然后再输出.接下来定义提向一维数组的指针变量.,
23、(2)指向一维数组的指针变量,指向一维数组的指针变量的声明形式:int(*p)4;p可以指向由四个分量组成的一维数组,p每次+1,移动的单元数是一维数组所占的单元数,它等同于二维数组的行移动.因此,p等价于二维数组。,例,输出二维数组中任一行任一列元素的值main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int i,j,(*p)4;p=a;scanf(%d%d,3.用指向数组的指针作函数参数,一维数组名可以作函数参数,多维数组名也可以做为参数传递。用指针变量做形参时接收实参数组名传递来的地址时,有两种方法:指向变量的指针变量,实参为*数组名指向一维数组的指针变量
24、,实参为 数组名,例,有一个班有3名学生,4门课程,计算总平均分以及查找第n个学生的成绩。main()void average(float*p,int n);void search(float(*p)4,int n);float score34=65,67,70,60,80,87,90,81,90,99,100,98;average(*score,12);search(score,2);,void average(float*p,int n)int i;float*p_end;float sum=0.0,avg;p_end=p+n-1;for(;pp_end;p+)sum=sum+(*p);a
25、vg=sum/n;printf(average=%5.2fn,avg);,void search(float(*p)4,int n)int i;printf(the score of number%d student is n,n);for(i=0;i4;i+)printf(%5.0f,*(*(p+n)+i);,例,在上题的基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程成绩,void search(float(*p)4,int n)int i,j,flag;for(i=0;in;i+)flag=0;for(j=0;j4;j+)if(*(*(p+i)+j)60)flag=1;,if
26、(flag=1)printf(number%d student fails:n,i);for(j=0;j4;j+)printf(%5.1f,*(*(p+i)+j);printf(n);/if/for,10.字符串与指针,1.字符串的表示形式C语言用两种方式处理字符串字符型数组 main()char str=”I love China”;printf(“%sn”,str);字符指针 main()char*str=”I love China”;printf(“%sn”,str);,说明:(1)char*str=”I love China”;等价于char*str;str=”I love China
27、”;把字符串的首地址赋给str,不等价于char*str;*str=”I love China”;,(2)用字符型指针变量或字符数组表示的字符串可以用%s整体输入输出,其他类型的指针变量或数组不可以,只能逐个分量操作。,例,将字符串a复制到字符串b main()char a15=I am a boy;char b15;int i;for(i=0;*(a+i)!=0;i+)*(b+i)=*(a+i);*(b+i)=0;for(i=0;bi!=0;i+)printf(%c,bi);/printf(%s,b);,用指针变量处理上题 main()char a=”I am a boy”,b20,*p1,
28、*p2;int i;p1=a;p2=b;for(;*p1!=0;p1+,p2+)*p2=*p1;*p2=0;printf(“%s”,b);,2.字符串指针作函数参数,字符串数组或指针做函数参数可以实现地址传递(1)用字符数组做参数 void copy_str(char from,char to)int i=0;while(fromi!=0)toi=fromi;i+;toi=0;,(2)形参用字符指针变量 void copy_str(char*from,char*to)for(;*from!=0;from+,to+)*to=*from;*to=0;,对上述函数体可有多种写法,(1)while(*
29、to=*from)!=0)to+;from+(2)while(*to+=*from+)!=0);(3)while(*from!=0)*to+=*from+;*to=0;(4)while(*to+=*from+);它等价于 while(*to+=*from+)!=0);(5)for(;(*to+=*from+)!=0;);或(6)for(;*to+=*from+;);,形参为数组时,也可以用指针变量 void copy_str(char from,char to)char*p1,*p2;p1=from;p2=to;while(*p2+=*p1+)!=0);形参和实参都可以是字符数组或字符指针变量
30、,很灵活,3.对字符指针变量和字符数组的讨论,(1)字符数组的每个元素存放一个字符,字符指针变量只存放字符串的首地址,而不是将字符串放到字符指针变量中(2)赋值方式,对字符数组只能对各元素赋初值,字符指针变量可以整体赋值 char str20;str=”I love China”;/错误的 上述两语句不等价于:char str20=”I love China”,char*a;a=”I love China”;/合法的上面两语句等价于:char*a=”I love China”;(3)定义了字符数组后,编译时对数组分配单元,而字符指针变量不分配单元,要人为赋初值(通常指向某一数组首址)char*
31、s;scanf(“%s”,s);/语法上没有错误,但危险 通常的做法:char*s,str10;s=str;scanf(“%s”,s);,(4)指针变量的值可以改变,而数组名是常量,不可以改变其值 char*a=”I love China”;a=a+7;printf(“%s”,a);结果是China,字符指针变量输出字符串时从当前位置开始,输出到0为止。(5)定义了一个指针变量并使它指向一个字符串后,就可以用下标形式引用其中的字符。char*a=”I love China”;ai,10.5 指向函数的指针,1.用函数指针变量调用函数 一个函数在编译时初分配一个入口地址,这个地址就称为函数的指针
32、,可以用一个指针变量指向函数,然后通过该指针变量调用此函数。函数名代表该函数的入口地址,main()int max(int,int);int(*p)();/定义指向整型函数的指针 int a,b,c;p=max;scanf(%d%d,(1)指向函数的指针变量的一般定义形式:数据类型(*指针变量名)();(2)函数调用可以通过函数名,也可以通过函数指针调用(3)(*p)()只是定义了一个指向函数的指针变量,但指向哪一个并不确定;在一个程序中,一个指针变量可以先后指向返回类型相同的不同函数(4)给函数指针变量赋初值时,只给函数名不给参数(5)调用函数时,用(*p)取代函数名,实参照常(6)对指向函
33、数的指针变量进行加减运算没有意义,如p+,2.用指向函数的指针作函数参数,函数指针变量的主要用途是做函数参数。形参是指向函数的指针变量,实参是函数名,结合的过程就是将函数的地址传给形参。通过用函数指针变量做函数形参,可以实现灵活调用不同的函数,提高函数的通用性。例,设一个函数process,在调用它的时候,每次实现不同的功能。输入a,b后,第一次调用时找出a和b中的大者,第二次找出小者,第三次求a+b;,main()int max(int,int);int min(int,int);int add(int,int);int process(int,int,int(*fun)();int a,b
34、;scanf(%d%d,printf(max=);process(a,b,max);printf(min=);process(a,b,min);printf(add=);process(a,b,add);,process(int x,int y,int(*fun)()int result;result=(*fun)(x,y);printf(“%dn”,result);,说明:主函数中对max(),min(),add()等三个函数的声明是必不可少的,以前函数不声明,隐含为函数类型为整型,但在此max,min,add做为函数参数进行调用时,只给函数名而没有函数的实参及括号,所以编译系统些时不易区分
35、它们是变量还是函数名,以前做为函数调用时,后面的括号及参数可以告知编译系统它们是函数名。,10.6 返回指针值的函数,函数的类型为指针类型。一般定义形式为:类型名*函数名(参数列表)int*a(int x,int y)调用a后能得到一个指向整型数据的指针。()的优先级高于*,所以这是函数形式,a前的*代表此函数是指针函数,例,有若干名学生,4门课,要求在用户输入学生序号后,能输出该学生的全部成绩,用指针函数实现。定义函数search,返回第n个学生的首门课的地址(列)float*search(float(*pointer)4,int n)float*pt;pt=*(pointer+n);ret
36、urn pt;,main()float score4=60,70,80,90,56,89,67,88,34,78,90,6;float*search(float(*pointer)4,int n);float*p;int j,n;scanf(%d,例,对上例中的学生,找出其中有不及格课程的学生及其学号 main()float score4=60,70,80,90,56,89,67,88,34,78,90,6;float*search(float(*pointer)4);float*p;int i,j;,for(i=0;i3;i+)p=search(score+i);if(p=*(score+i
37、)printf(No.%d scores:,i);for(j=0;j4;j+)printf(%5.0f,*(p+j);printf(n);/end_if/end_for,float*search(float(*pointer)4)int i;float*pt;pt=*(pointer+1);for(i=0;i4;i+)if(*(*pointer+i)60)pt=*pointer;return pt;,该函数的作用是检查一个学生是否有不及格的课程,先让指针pt指向下一个学生的第一门课,如果该学生有不及格的课程,则让指针pt指回该学生的每一门课,便于主函数进行判断。,10.7指针数组和指向指针的指
38、针,1.指针数组的概念元素均为指针类型的数组,称为指针数组。一般定义形式:类型名*数组名数组长度;int*p4;的优先级高于*,所以p先与结合,形成数组,然后再与*结合,*表示此数组是指针类型,每个元素都可指向一个整型变量,指针数组比较适合处理若干字符串,使字符串处理更加方便灵活。比如,处理图书馆中的图书名字,由于书名长度不同,所以用指针数组比较方便,每个元素是个字符串指针。当要对字符串进行排序时,可以不改变字符串本身的存贮,只改变指针值即可,可节约时间。,例,将若干字符串按字母顺序(由小到大)输出 void sort(char*name,int n)char*temp;int i,j,k;f
39、or(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(strcmp(namej,namek)0)k=j;if(k!=i)temp=namei;namei=namek;namek=temp;,void print(char*name,int n)int i;for(i=0;in;i+)printf(%sn,namei);main()char*name=Follow me,BASIC,Great wall,FORTRAN,Computer design;int n=5;sort(name,n);print(name,n);,2.指向指针的指针,指向指针数据的指针变量,简称为指
40、向指针的指针,定义的形式:类型*变量;char*p;*运算的结合性从右向左,所以上述定义相当于char*(*p);*p是一个指向字符型的指针变量,*p是一个指向字符型指针变量的指针。,例1,用指向指针的指针输出字符串 main()char*name=Follow me,BASIC,Great wall,FORTRAN,Computer design;char*p;int i;for(i=0;i5;i+)p=name+i;printf(%sn,*p);,例2,间接寻址举例 main()static int a5=1,3,5,7,9;int*num5=,3.指针数组作main函数的形参,指针数组一
41、个重要的应用是作为main函数的形参。main(argc,argv)实参的给定是执行程序时,在命令行中文件名的后面给出argc:命令行中给出的实参个数argv:是一个指向字符串的指针数组,存放命令行中的各实参字符串,argv0中存放的是文件名,从argv1开始存贮实参。main函数的原型是:main(int argc,char*argv),main(int argc,char*argv)while(argc1)argv+;printf(%sn,*argv);argc-;命令行中给出file1 China Beijing 则输出:ChinaBeijing,也可以改写为:main(int argc
42、,char*argv)while(argc-1)printf(%sn,*+argv);,echo程序:main(int argc,char*argv)while(argc-1)printf(%s%cn,*+argv,(argc1)?:n);在不同的参数间加一个空格,当所有参数输出完毕,加一个回车符,10.8 小结,1.有关指针的数据类型的小结int iint*pint anint*pnint(*p)nint f()int*p()int(*p)()int*p,2.指针运算小结,(1)指针变量加(减)一个整数n:加n个存贮单元的地址(2)指针变量赋值 p=/p不指向任何存贮单元,但它已被赋初值,可以避免无初值对系统造成的破坏,(3)两个指针变量可以相减:如果两个指针变量指向同一个数组的元素,两指针变量之差是两个指针之间的元素个数;两个指针相加没有意义,(4)若两个指针指向同一个数组的元素,则可以进行比较。指向前面的元素的指针变量“小于”指向后面元素的指针变量。否则无意义,3.void指针类型,void代表一种抽象的数据类型,使用时进行强制类型转换。void*p2;char*p1;p1=(char*)p2;,