首页 理论教育 指针变量的引用|C语言程序设计

指针变量的引用|C语言程序设计

时间:2023-10-29 理论教育 版权反馈
【摘要】:指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予其具体的值,未经赋值的指针变量不能使用。而且,指针变量的赋值只能赋予地址,决不能赋予任何其他数据,否则将引起错误。因此必须指定指针变量所指向的变量的类型。“*p1”代表p1所指向的变量,就是变量a,因此最后两个printf函数的作用是相同的。程序第5行的“*p1”和“*p2”表示定义两个指针变量p1和p2,它们前面的“*”只是表示该变量是指针变量。

指针变量的引用|C语言程序设计

指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予其具体的值,未经赋值的指针变量不能使用。而且,指针变量的赋值只能赋予地址,决不能赋予任何其他数据,否则将引起错误。在C语言中,变量的地址是由编译系统分配的,对用户来说是完全透明的,用户不知道变量的具体地址。

与指针变量相关的两个运算符:地址运算符“&”和指针运算符“*”。

1.地址运算符

&:用于获取变量的地址。

其使用格式:

&变量名;

将“&”施加在变量或数组元素上,就可以得到该变量或数组元素的地址。需要注意:“&”不能施加在常数或表达式上。例如:不能对数组名施加“&”运算,数组名代表的是数组的首地址,是一个常量;也不能对诸如20或“a+b”这样的常数或表达式施加“&”运算。

2.指针运算符

*:用于获取指针变量所指向的变量的值。

其使用格式:

*p(p为指针变量或地址表达式);

(1)“*ptr”的功能是访问ptr所代表的地址中的数据。

例如:

“&a”是地址,“*&a”表示取地址“&a”中的值。

(2)“*”运算符为一元运算符,它和“&”处于相同的优先级上,结合性为从右向左,因此,“*&a”和“*(&a)”是等价的。

(3)注意“*”运算符与乘法运算符的区别,虽然它们在形式上相同,但乘法运算符是二元运算符,二者在使用上是不会产生混淆的。

【例7.1】编写一个简单程序,输出显示一组字符串。

程序内容如下:

1 #include<conio.h>

2 #include<stdio.h>

3 void main()

4 {

5  int a=6,*p;

6  p=&a;

7  printf("a=%d\n*p=%d\n",a,*p);

8  printf("&a=%d\np=%d\n",&a,p);

9  printf("&p=%d\n",&p);

10  getch()

11 }

程序结果如图7.2所示:

图7.2 例7.1程序结果图

【例题中关键问题说明】

(1)在程序第4行定义了一个指针变量p,p前面的“*”表示所定义的变量是指针变量,而不是普通变量,int表示所定义的指针变量是指向整型变量的。

(2)程序第5行把a的地址赋给p,此时p的值为“&a”(即a的地址),这就使p指向a。

(3)在程序的第6行输出a的值和指针变量p所指向的变量a的值;第7行输出a的地址和指针变量p的值;第8行则输出p的地址。

3.指针变量的赋值

C语言中提供了地址运算符&来表示变量的地址,其一般形式为:

&变量名;

例如,&a表示变量a的地址,&b表示变量b的地址。注意,变量本身必须预先声明。

设有指向整型变量的指针变量p,如要把整型变量a的地址赋予p可以有以下两种方式:

(1)指针变量初始化的方法:

int a;

例如:

int*p=&a;

(2)赋值语句的方法:

int a;

例如:

int*p;

p=&a;

需要注意:在定义指针变量时:

①指针变量前面的“*”表示该变量的类型为指针变量;指针变量名是p,而不是*p。

②在定义指针变量时必须指定指针所指向的变量类型。不同类型的数据在内存中所占的字节数是不相同的(例如在Visual C++中,整型数据占4字节,字符型数据占1字节),如果指针是指向一个整型变量的,那么“使指针移动1个位置”意味着移动4个字节,“使指针加1”意味着使地址值加4个字节。如果指针是指向一个字符变量的,则增加的不是4个字节而是1个字节。因此必须指定指针变量所指向的变量的类型。一个指针变量只能指向同一类型的变量,不能忽而指向一个整型变量,忽而指向一个实型变量。

③赋给指针变量的是变量地址而不能是任意类型的数据,而且只能是与指针变量所指向的变量类型相同的变量地址。例如,整型变量的地址可以赋给指向整型变量的指针变量,但实型变量的地址不能赋给指向整型变量的指针变量。分析下面的赋值:

float a;    //定义a为float型变量

int*p1;   //定义p1是基类型为int型的指针变量

p1=&a; //将float型变量的地址赋给基类型为int的指针变量,错误

④指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量。

例如:

*p1=100; //p1是指针变量,100是整数,不合法

【例7.2】通过指针变量访问整型变量,分析程序。

程序内容如下:

1 #include<stdio.h>

2 void main()

3 {

4  int a,b;

5  int*p1,*p2;

6  a=100;b=10;

7  p1=&a;

8  p2=&b;

9  printf("a=%d,b=%d\n",a,b);

10  printf("*p1=%d,*p2=%d\n",*p1,*p2);

11 }

程序结果如图7.3所示:

图7.3 例7.2程序结果图

【例题中关键问题说明】

(1)在程序第5行定义了两个指针变量p1和p2,p1和p2前面的“*”表示所定义的变量是指针变量,而不是普通变量,int表示所定义的指针变量是指向整型变量的。它们只是提供了两个指针变量,规定它们可以指向整型变量,至于指向哪一个整型变量,要在程序语句中指定。

(2)程序第7、8行把a的地址赋给p1,把b的地址赋给p2,此时p1的值为“&a”(即a的地址),p2的值为“&b”(即b的地址),这就使p1指向a,p2指向b。

(3)第10行语句中的“*p1”和“*p2”就是变量a和b。“*p1”代表p1所指向的变量,就是变量a,因此最后两个printf函数的作用是相同的。程序中有两处出现了“*p1”和“*p2”,其含义是不同的。程序第5行的“*p1”和“*p2”表示定义两个指针变量p1和p2,它们前面的“*”只是表示该变量是指针变量。程序最后一行printf函数中的“*p1”和“*p2”则代表p1和p2所指向的变量。

4.指针变量的运算

指针变量可以进行某些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算术运算。

(1)赋值运算

指针变量的赋值运算有以下几种形式:

①指针变量初始化赋值。

②把一个变量的地址赋予指向相同数据类型的指针变量。

例如:

int a,*pa;

pa=&a;   //把整型变量a的地址赋予整型指针变量pa

③把一个指针变量的值赋予指向相同类型变量的另一个指针变量。

例如:

int a,*pa=&a,*pb;

pb=pa;   //把a的地址赋予指针变量pb

由于pa、pb均为指向整型变量的指针变量,因此可以相互赋值。

④把数组的首地址赋予指向数组的指针变量。(www.xing528.com)

例如:

int a[5],*pa;

pa=a;(数组名表示数组的首地址,故可赋予指向数组的指针变量pa)

也可写为:

pa=&a[0];   //数组第一个元素的地址也是整个数组的首地址

也可采取初始化赋值的方法:

int a[5],*pa=a;

⑤把字符串的首地址赋予指向字符类型的指针变量。

例如:

char*pc;pc="c language";

或用初始化赋值的方法写为:

char*pc="C Language";

这里应说明的是并不是把整个字符串装入指针变量,而是把存放该字符串的字符数组的首地址装入指针变量。

⑥把函数的入口地址赋予指向函数的指针变量。

例如:

int(*pf)();pf=f;   //f为函数名

(2)加减算术运算

对于指向数组的指针变量,可以加上或减去一个整数n。设pa是指向数组a的指针变量,则pa+n,pa-n,pa++,++pa,pa--,--pa运算都是合法的,意义是把指针指向的当前位置(指向某数组元素)向前或向后移动n个位置。数组指针变量向前或向后移动一个位置和地址加1或减1在概念上是不同的。因为数组可以有不同的类型,各种类型的数组元素所占的字节长度是不同的。如指针变量加1,即向后移动1个位置表示指针变量指向下一个数据元素的首地址,而不是在原地址基础上加1。

例如:

int a[5],*pa;

pa=a;       //pa指向数组a,也是指向a[0]

pa=pa+2;     //pa指向a[2],即pa的值为&pa[2]

指针变量的加减运算只能对数组指针变量进行,对指向其他类型变量的指针变量作加减运算是毫无意义的。

(3)两个指针变量之间的运算只有指向同一数组的两个指针变量之间才能进行运算,否则运算毫无意义。

①两指针变量相减

两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实际上是两个指针值(地址)相减之差再除以该数组元素的长度(字节数)。

例如:

pf1和pf2是指向同一浮点数组的两个指针变量,设pf1的值为2016 H,pf2的值为2000H,而浮点数组每个元素占4个字节,所以“pf1-pf2”的结果为“(2016H-2010H)/4=4”,表示pf1和pf2之间相差4个元素。两个指针变量不能进行加法运算。

②两指针变量进行关系运算

指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的关系。

例如:

“pf1==pf2”表示pf1和pf2指向同一数组元素

“pf1>pf2”表示pf1处于高地址位置

“pf1<pf2”表示pf2处于低地址位置

【例7.3】指针变量运算举例。

程序内容如下:

1 #include<stdio.h>

2 void main()

3 {

4  int a=10,b=20,s,t,*pa,*pb;

5  pa=&a;

6  pb=&b;

7  s=*pa+*pb;

8  t=*pa**pb;

9  printf("a=%d\nb=%d\na+b=%d\na*b=%d\n",a,b,a+b,a*b);

10  printf("s=%d\nt=%d\n",s,t);

11 }

程序结果如图7.4所示:

图7.4 例7.3程序结果图

【例题中关键问题说明】

(1)第4行定义pa、pb为整型指针变量。

(2)第5行、第6行分别给指针变量pa和pb赋值,pa指向变量a,pb指向变量b。

(3)第7行求a+b之和(*pa就是a,*pb就是b)。

(4)第8行求a*b之积。

(5)第9~10行输出结果。

(6)指针变量还可以与0比较。设p为指针变量,则“p==0”表示判断p是否是空指针;“p!=0”表示判断p是否不是空指针。对指针变量赋0值和不赋值是不同的。指针变量未赋值时,可以是任意值,是不能使用的。而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。

【例7.4】从键盘输入三个数,输出最大值和最小值。

程序内容如下:

1 #include<stdio.h>

2 int main()

3 {

4  int a,b,c,*pmax,*pmin;

5  printf(“input three numbers:\n”);

6  scanf(“%d%d%d”,&a,&b,&c);

7  if(a>b)

8  {

9   pmax=&a;

10   pmin=&b;

11  }

12  else

13  {

14   pmax=&b;

15   pmin=&a;

16  }

17  if(c>*pmax)

18   pmax=&c;

19  if(c<*pmin)

20   pmin=&c;

21  printf("max=%d\nmin=%d\n",*pmax,*pmin);

22 }

程序结果如图7.5所示:

图7.5 例7.4程序结果图

【例题中关键问题说明】

(1)在第4行,定义整型变量a、b、c,指针变量pmax、pmin。

(2)第6行输入3个数。

(3)第7~16行比较a和b的大小,将较大者的地址赋给指针变量pmax,将较小者的地址赋给指针变量pmin。

(4)第17~20行确定与变量c的大小,得出最大数和最小数。

(5)第21行输出结果。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈