本课重要知识点:
1.知识点:指针的概念与指针变量
第 36 页 共 78 页
? 指针就是地址。指针变量是用来存储地址,而一般变量是【解析】*和++同级别,按自左向右的结合方向,因此D选项用来存储数值。 可转变为*(p++),从而只是使指针发生移动,而不能将p所例1.(09-09-26)有如下程序输出结果为 1,2,2,1 指变量增1 #include
【解析】p、q为指针,初始化时p指向m,q指向n。执行 【解析】对于scanf函数,输入数据列表必须是合法地址r=p ;p=q ;q=r ;p和q的值交换,从而p指向n,q指向m。指表达式(可以使地 针的改变不会应用m、n的值,最后输出*p和*q的值分别为n、址常量、指针),A选项、B选项*使用错误。 m的值。 例3.(09-03-16)若有定义语句 doule x,y,*px,*py;执行了2.知识点:指针的引用 px=&x;py=&y;之后,正确的输入语句是(C)
? 指针的引用是通过两个运算符实现“&”和“*”实现的 A) scanf(\%f%f\ B) scanf(\%f%f\ &是取地址符号,它的一半格式是:&变量名。例如:int i ; C) scanf(\%f%le\D) scanf(\%lf%lf\&i表示取i的地址。 【解析】A,D选项中的x,y缺少取地址符,B项中&x之前缺少 *是取值运算符,它的一般格式:*指针变量名。例如:int 逗号,格式不正确。 i=10,*p=&i; *p表示取i的值10 3.知识点:指针变量的初始化
例1.(2011-09-25)若定义语句:int year=2009,*p=&year;,以下不? 指针变量在使用前必须要初始化,把一个具体的地址赋给能使变量year中的值增至2010的语句是 (D) 它,否则引用时会出错,如果不指向任何数据就赋“空值” A.*p+=1; B.(*p)++; C.++(*p); NULL。 D.*p++; ? 指针变量两种初始化方法:方法一:int a=2,*p=&a;(定
第 37 页 共 78 页
义的同时初始化) ② pa=a;或pa=&a[0];使pa保存了数组a的首地址, 方法二:int a=2,*p;p=&a;(先pa,a,&a[0]都指向一个地址。 定义后初始化) ③以上操作可等价于 int a[6],*pa=a; 例1.(07—04—29)设已有定义:float x;则以下对指针变量P ④如果pa=&a[3];表示*pa的值就是a[3]的地址。 进行定义且赋初值的语句中正确的是 (D) 注意:数组a是一个地址常量,它永远指向数组的首地址,不A)float *p=1034; B)int *p=(float)x; C)float p=&x; D)float 能重新赋值。因此 a=&i;或a++都是错误的。 *p=&x; 例1.(08—04—23)有以下程序 【解析】可以给一个指针赋值的只能是一个与该指针同类型的 #include
针变量所指的数据变化。一个指针变量加一个整数不是简 A)y=0 B)y=l C)y=2 D)y=3
单的数学相加,而是连续移动若干地址。当两个指针指向【解析】程序中定义一个一维数组,并初始化,再一定义了一同一数组时,它们可以比较大小进行减法运算。 变量和一个指针(将指针指向数组下标为3的一个元素),执行例如:int a[10],*p; p=a; p++;表示p移动一个存储单元,p指向--p;(注意,当指针指一个元素后,指针变量加上“*”时,表a[1],只有当指着指向数组元素时,指针的运动才有意义。 示引用的是元素的值,当不加“*“时表示引用的是地址),向5:知识点:指针与数组 前移动一个位置,指向a[2],y=+p;(将p指针指向的值3赋? 指针与一维数组 给变量y),输出y的值为3。
数组名代表数组的首地址。一维数组中,第一个元素的地例2.(11-03-24)设有定义:double x[10],*p=x;,以下能给数组x址即为该数组的起始地址。建立指针变量与一维数组的联系:
下标为6的元素读入数据的正确语句是( C ) 例如: int a[6],*pa; pa=a;或pa=&a[0];
说明:①数组名a代表该数组的首地址,也即a[0]的地址。 A)scanf(\ B)scanf(\
第 38 页 共 78 页
例如:int *p,a[5]; p=a;
说明:①p[0]表示p指针指向的内存单元,p[1]表示p指向
【解析】数组名是数组的首地址,p=x,指针p指向数组的首的内存单元
②a[i]的等价引用方法:a[i]、p[i]、*(a+i)、*(p+i)
地址,要表示数组x下标为6的元素的地址可以有&x[6],x+6, ③a[i]的地址等价引用方法:&a[i]、&p[i]、a+i、p+i
p+6,&p[6],scanf后面的参数列表必须是地址列表,B中*(x+6)例1.(09-03—29)若有以下定义
int x[10],*pt=x;
D中p[6]都是取数组x下标为6的元素的值,A中格式控制符%f
则对x数组元素的正确应用是 B
A)*&x[10] B)*(x+3) C)*(pt+10) D)pt+3 与double类型不匹配,所以选C。
【解析】引用数组元素时,注意取地址运算符&与指针运算符
6.知识点:用指针访问数组元素
t的作用;指针运算符+用来取得指针变量所指存储空间的内
? 通过指针引用数组元素
容,取地址运算符&用来取得变量的地址值;A选项数组下标
例如:int *p,a[5]; p=&a[0];
越界;B选项中+(x+3)等价于元素X[3];C选项中。(pt+10)等
说明:①指针变量p指向了数组元素a[0],可以使用访问
价于x[10],数组下标越界;D选项pt+3是元素x[3]的地址,
运算符“*”来引用变量a[0];
与&x[3]等价;故正确答案是B。正确答案:B
例:*p=18;等价于a[0]=18;
例1.(2011-09-27)有以下程序
②*(p+1)表示a[1] p+1表示&a[1]
#include
? 通过数组的首地址引用数组元素
void fun(int *p)
例如:int a[5];
{printf(“%d\\n”,p[5]);}
说明:①a是数组名,表示收地址,可以把a当做一个指针
main()
常量。
{int a[10]={1,2,3,4,5,6,7,8,9,10};
②*a等价与a[0],*(a+1)等价与a[1];a等价于&a[0], fun(&a[3]);
a+1等价与&a[1];
}程序运行后的输出结果是 (D)
? 用带下标的指针变量引用一维数组元素
C)scanf(\ D)scanf(\
第 39 页 共 78 页
A.5 B.6 C.8 D.9 语句正确的是(B) 【解析】fun函数被调用时将&a[3]通过传递付给了形参指针变 A)pk=k; B)pk[0]=&k[1][2]; C)pk=k[0]; D)pk[1]=k; 量p,此时可用*p或p[0]来表示a[3],因此p[5]亦可表示a[8],【解析】题目中定义了一个二维数组和一个指针数组,pk是所以输出结果为9 指针数组名,不能被赋值,指针数组pk中的元素是指针,并7.知识点:指针与二维数组 且二维数组名是指向一维数组的指针常量,相当于行指针,二? 任何一个二维数组均由若干个一维数组组成,a[0]、a[1]和者不可转换,所以A、C、D选项均有误,本题答案选B。 a[2]是一维数组名,数组名代表数组的首地址,因此a[0]例2.(09-09-27) 若有定义语句: int a[4][10],*p,*q[4];且0<=i<4,就代表数组元素a[0][0]的地址,也即&a[0][0]。 则错误的赋值是 (A)
注意:a的值与a[0]相同,但它们的基类型不同,a可以等价A)p=a B)q[i]=a[i] C)p=a[i] D)p=&a[2][1] 于一个二维指针,而a[0]是一维指针。因此 int a[3][4],*p=a;【解析】p为基类型为int的指针,指向一个整形数据,也就错误 可以指向一个数组元素,所以D正确。指针数组q的每个数 取数组元素a[i][j]的地址的几种方法:&a[i][j];a[i]+j; 组元素q[i]的基类型也为int,所以p、a[i]、a[i]的基类型一致,*(a+i)+j; 选项B、C也是正确的。 ? 指针数组的定义方式: 8.知识点:指针与函数
*指针数组名[常量表达式];如:int *p[3]; 例1.(08—04—40)设有定义语句int(*f)(int);,则以下叙述正确? 行指针的一般定义形式如下: 的是__B_______。
类型名 (*指针数组名)[常量表达式]; 如:int (*p)[2]; A)f是基类型为int的指针变量 ? 指针数组与行指针的区别 B)f是指向函数的指针变量,该函数具有一个int类型的形1、int *p[3];定义的是指针数组,表示一个数组,含有3个元态
素p[0]、p[1]、p[2],且这3个元素只能存放整型元素的地址 C)f是指向int类型一维数组的指针变量
2、int (*p)[3];定义的是行指针,表示一个指针变量,它仅有 D)f是函数名,该函数的返回值是其类型为int类型的地一个存储空间,只能存放一个长度为2的一维数组指针。 址
例1.(06—09—33)若有定义语句:int k[2][3],*pk[3];则以下 【解析】在c语言中,函数名代表此函数的入口地址,所
第 40 页 共 78 页