知识要点:指针的概念、定义和运算、指针变量作函数的参数
视频:
目录
一、任务分析
输入两个整数,按大小顺序输出,要求用函数处理,而且用指针类型的数据作函数参数。
1.首先大家对这个任务并不陌生,在这里要求用函数调用的形式来完成;
2.定义一个自定义函数swap,用于交换两个变量(a和b)的值;
3.要求用指针变量作函数参数,那么swap函数的形参p1、p2是指针变量;
4.在主函数中,对两个整数比较大小,将两个整型变量的地址作为实参传递给swap函数中的p1、p2。
二、必备知识与理论
1.指针的概念
为了掌握指针的基本概念,巧妙而恰当地使用指针,必须了解计算机硬件系统的内存地址、指针之间的关系和变量的直接访问与间接访问。
(1)内存地址
在计算机中,所有的数据都存放在存储器中,一般把存储器中的一个字节称为一个内存单元,为了方便地访问这些内存单元,我们为每个内存单元进行了编号,这样根据内存单元的编号可以准确地找到内存单元。通常我们把这些内存单元的编号叫做内存地址。
(2)指针
变量的内存地址在程序运行过程中起到寻找变量数值的作用,就好比用一个指针指向了一个变量,因此变量的地址常被称为"指针"。
(3)变量的地址和变量的内容
在程序中定义变量时,计算机就按变量的类型,为其分配一定长度的存储单元。
(4)变量的直接访问与间接访问
在C语言程序中,使用一个变量可以直接通过其变量名存取数值,这种方式称为"直接访问方式"。除此之外,还可以把该变量的地址存入到另一个指针变量中,然后通过该指针变量来存取变量的值,这种访问方式称为"间接访问方式"。
****注意:****内存单元的指针(地址)和内存单元的内容是两个不同的概念。
2.指针变量的定义
C语言规定所有变量在使用之前必须定义,规定其类型。指针变量不同于整型变量和其它类型的变量,它是专门用来存放地址的。
指针变量定义的一般格式为:存储类型 数据类型 *指针变量名[=初始地址值];
3.指针变量的引用
指针变量同普通变量一样,使用之前不仅要说明,而且必须赋予具体的值。指针变量的赋值只能赋予地址,不能赋予其它任何数据,否则将引起错误。禁止使用未初始化或未赋值的指针,此时,指针变量指向的内存空间是无法确定的,使用它可能导致系统的崩溃。
4.指针的运算
如同其它变量一样,指针变量也可以参与一些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算术运算及关系运算。
(1)指针运算符
&运算符:取地址运算符。其功能是取变量的地址。&是单目运算符,其结合性为自右向左。
*运算符:指针运算符(或称"间接访问"运算符)。用于表示指针所指向的变量。*是单目运算符,其结合性为自右向左。
(2)赋值运算
指针变量的赋值运算有以下几种形式:
①指针变量在定义的时候直接初始化赋值,前面已介绍过。
②把一个变量的地址赋予指向相同数据类型的指针变量。
③把一个指针变量的值赋予指向相同类型变量的另一个指针变量。
④把数组的首地址赋予指向数组的指针变量。
⑤把字符串的首地址赋予指向字符类型的指针变量。
⑥把函数的入口地址赋予指向函数的指针变量。
(3)加减运算
对于指向数组的指针变量,可以加上或减去一个整数n。设p是指向数组a的指针变量,则p+n、p-n、p++、p--、++p、--p运算都是合法的。
①指针加减任意整数运算
指针变量与一个整数的加或减的操作实质上是一种地址运算。
②两指针变量相减
只有指向同一数组的两个指针变量之间才能进行相减运算,否则运算毫无意义。
(4)指针的关系运算
指向同一数组的两指针变量进行关系运算时,可表示它们所指数组元素之间的关系。
空指针是由对指针变量赋予0值而得到的。
例如:#define NULL 0
int *p=NULL;
对指针变量赋0值和不赋值是不同的。指针变量未赋值时,可以是任意值,是不能使用的,否则将造成意外错误。而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。
5.指针变量作函数的参数
函数的参数不仅可以是整型、实型、字符型及数组等数据,也可以是指针类型的数据。当使用指针类型的数据作函数参数时,实际上是将一个变量的地址传向另一个函数。由于被调函数中获得了变量的地址,该地址空间中的数据变更在函数调用结束后将被物理地址保留下来(不同于用简单变量作函数参数时的单向值传递关系)。
三、任务实施
本任务是输入两个整数,按大小顺序输出。(用函数处理,而且用指针类型的数据作函数参数)。
算法分析:
(1)这个任务跟【例6.2】的任务相同,但在这里要求用函数调用的形式来完成。
(2)定义一个自定义函数swap,用于交换两个变量(a和b)的值。
(3)要求用指针变量作函数参数,那么swap函数的形参p1、p2是指针变量。
(4)在主函数中,对两个整数比较大小,将两个整型变量的地址作为实参传递给swap函数中的p1、p2。
#include <stdio.h>
swap(int *p1,int *p2) /*定义函数swap,参数为指针类型*/
{int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
main()
{
int a,b;
int *pt1,*pt2; /*定义两个指针变量*/
scanf("%d,%d",&a,&b);
pt1=&a;pt2=&b; /*为指针变量赋值*/
if(a<b) swap(pt1,pt2); /*调用函数swap*/
printf("\n%d,%d\n",a,b);
}
运行结果如下:
56,78↙
78,56
由于在调用函数时,实际参数是指针变量,形式参数也是指针变量,实参与形参相结合,函数调用将指针变量传递给形式参数p1和p2。由于此时传递的是变量地址,使得在被调用函数中p1和p2具有了pointer_1和pointer_2的值,指向了与主函数相同的内存变量,并对其在内存存放的数据进行了交换。