8.1引例
【例8.1】已知数组a[5]中存放了5个整数,要求输出其中的最大元素。
8.2 指针与指针变量
8.2.1 地址和指针
C程序中所定义的每一个变量,都会被分配若干个连续的内存单元,变量的值就存放在这些内存单元中;变量被分配的内存单元数量由变量的类型决定。
定义变量后,对变量的访问实质是访问变量所占用的内存单元,例如:
假设变量a被分配的内存单元为 2000和2001,a的初值67存储到由2000开始的两个内存单元中,如图8.1(a)所示。
语句“scanf("%d",&a);”执行结束后,内存单元的情况如图8.1(b)所示,用户输入的100被存储到了变量a占用的内存空间中。执行语句“printf("%d",a);”时,从变量a占用的2000开始的内存单元中读出值100,将其输出到屏幕上。
上述利用变量名访问分配给变量的内存空间的方式称为直接访问方式,即对变量名a的存取都直接通过变量a的地址(2000)实现;另一种访问方式被称为“间接访问”,如图8.2所示,变量a的地址(2000)存放在变量p中。访问变量a分两步实现:第一步,从变量p中取出变量a的地址(2000);第二步,根据取得的变量a的地址再访问变量a。这时,变量p所指向的变量a称为“对象”或“目标”。
指针就是某个对象(如简单变量、数组和函数等)所占用的内存单元的首地址。例如,上述变量a的首地址2000就是变量a 的指针。存放变量地址的变量称为指针变量,例如,上述的变量p就是指向变量a的指针变量
8.2.2 指针变量的定义与初始化
指针变量定义的形式为:
类型名 *指针变量名[=地址];
其中:“类型名”是指针变量所指向对象的类型;“*” 是用于区分指针变量和其它类型变量的字符,表示其后的变量名是指针变量;“[=地址]”用于在定义时初始化指针变量,可省略。
指针变量的初始化(赋值)可以在定义指针时或者在定义指针后进行,常见的方式有:
(1)指针指向变量的初始化
指针指向变量初始化时,经常需要使用取变量的地址运算符“&”,初始化方式为:
指针变量名=&变量名;
(2)指针指向数组的初始化
指针指向数组初始化的方式为:
指针变量名=数组名;
(3)使用指针变量初始化其它同类型指针变量
使用指针变量初始化其它指针变量的方式为:
指针变量名1=指针变量名2;
(4)指针可以被初始化为0或NULL
指针初始化为0或NULL的方式为:
指针变量名=0(NULL)
使用指针,常见的错误有:
① 使用未初始化的指针
② 指针赋值常量
③ void 指针
④ 指针与初始化指针的对象类型不一致
8.2.3 指针变量的引用
访问指针所指对象的运算符有两个:
(1)间接访问(引用)运算符* 取指针所指对象的值。*右边的操作数必须是指针,而且它已指向了确定的对象。
(2)下标运算符[] 取指针所指对象的值。[]左边的操作数必须是指针,而且它已指向了确定的对象。
8.3 指针与函数
8.3.1 指针作为函数的参数
指针作为函数的形参时,在形参说明时需要使用格式“类型名 *指针名”,“*”号不可省略,在函数定义或声明的说明部分,“*”号的作用都只是类型说明。
8.3.2 返回指针值的函数
返回值是指针类型的函数称为返回指针值的函数。返回指针值的函数的一般形式为:
数据类型名 *函数名(参数表)
8.3.3 指向函数的指针
指向函数的指针的定义格式为:
类型名 (*指针变量名)(参数表);
指向函数的指针调用函数的格式如下:
(*指针变量名)(实参表);