聪智学校
4.知识点:指针的运算
?
--p;y=*p;printf(\%d\\n\;
*p++和(*p)++之间的差别:*p++是地址变化,(*p)++是指针变量所指的数据变 } 程序的运行结果是(D) 化。一个指针变量加一个整数不是简单的数学相加,而是连续移动若干地址。 A)y=0 B)y=l C)y=2 D)y=3 当两个指针指向同一数组时,它们可以比较大小进行减法运算。
【解析】程序中定义一个一维数组,并初始化,再一定义了一变量和一个指针(将
例如:int a[10],*p; p=a; p++;表示p移动一个存储单元,p指向a[1],只有当指着指指针指向数组下标为3的一个元素),执行--p;(注意,当指针指一个元素后,指针向数组元素时,指针的运动才有意义。
变量加上“*”时,表示引用的是元素的值,当不加“*“时表示引用的是地址),向前移动一个位置,指向a[2],y=+p;(将p指针指向的值3赋给变量y),输出y
5:知识点:指针与数组
?
指针与一维数组
的值为3。
double x[10],*p=x;,以下能给数组x下标为6的元素读入数组名代表数组的首地址。一维数组中,第一个元素的地址即为该数组的起例2.(11-03-24)设有定义:
数据的正确语句是( C )
始地址。建立指针变量与一维数组的联系:
A)scanf(\ B)scanf(\
例如: int a[6],*pa; pa=a;或pa=&a[0]; C)scanf(\ D)scanf(\
【解析】数组名是数组的首地址,p=x,指针p指向数组的首地址,要表示数组x说明:①数组名a代表该数组的首地址,也即a[0]的地址。
下标为6的元素的地址可以有&x[6],x+6,p+6,&p[6],scanf后面的参数列表必须是
② pa=a;或pa=&a[0];使pa保存了数组a的首地址,pa,a,&a[0]都指向一
地址列表,B中*(x+6)D中p[6]都是取数组x下标为6的元素的值,A中格式控
个地址。 制符%f与double类型不匹配,所以选C。
③以上操作可等价于 int a[6],*pa=a; 6.知识点:用指针访问数组元素
④如果pa=&a[3];表示*pa的值就是a[3]的地址。
?
通过指针引用数组元素 例如:int *p,a[5];
p=&a[0];
注意:数组a是一个地址常量,它永远指向数组的首地址,不能重新赋值。因此 a=&i;或a++都是错误的。 例1.(08—04—23)有以下程序 #include
{int a[]={1,2,3,4),y,*p=&a[3];
?
说明:①指针变量p指向了数组元素a[0],可以使用访问运算符“*”来引用变量a[0];
例:*p=18;等价于a[0]=18;
②*(p+1)表示a[1] p+1表示&a[1]
通过数组的首地址引用数组元素
第 31 页 共 61 页
聪智学校
例如:int a[5];
说明:①a是数组名,表示收地址,可以把a当做一个指针常量。
{int a[10]={1,2,3,4,5,6,7,8,9,10}; fun(&a[3]);
②*a等价与a[0],*(a+1)等价与a[1];a等价于&a[0],a+1等价与&a[1]; }程序运行后的输出结果是 (D)
?
用带下标的指针变量引用一维数组元素 例如:int *p,a[5]; p=a;
说明:①p[0]表示p指针指向的内存单元,p[1]表示p指向的内存单元
②a[i]的等价引用方法:a[i]、p[i]、*(a+i)、*(p+i)
A.5
B.6 C.8
D.9
【解析】fun函数被调用时将&a[3]通过传递付给了形参指针变量p,此时可用*p或p[0]来表示a[3],因此p[5]亦可表示a[8],所以输出结果为9
7.知识点:指针与二维数组
?
任何一个二维数组均由若干个一维数组组成,a[0]、a[1]和a[2]是一维数组名,数组名代表数组的首地址,因此a[0]就代表数组元素a[0][0]的地址,也即&a[0][0]。
注意:a的值与a[0]相同,但它们的基类型不同,a可以等价于一个二维指针,而a[0]是一维指针。因此 int a[3][4],*p=a;错误
取数组元素a[i][j]的地址的几种方法:&a[i][j];a[i]+j; *(a+i)+j; 指针数组的定义方式:
*指针数组名[常量表达式];如:int *p[3]; 行指针的一般定义形式如下:
类型名 (*指针数组名)[常量表达式]; 如:int (*p)[2]; ?
指针数组与行指针的区别
③a[i]的地址等价引用方法:&a[i]、&p[i]、a+i、p+i 例1.(09-03—29)若有以下定义 int x[10],*pt=x;
则对x数组元素的正确应用是 B A)*&x[10] B)*(x+3) C)*(pt+10) D)pt+3
【解析】引用数组元素时,注意取地址运算符&与指针运算符t的作用;指针运算 符+用来取得指针变量所指存储空间的内容,取地址运算符&用来取得变量的地址值;A选项数组下标越界;B选项中+(x+3)等价于元素X[3];C选项中。(pt+10)等价于x[10],数组下标越界;D选项pt+3是元素x[3]的地址,与&x[3]等价;故? 正确答案是B。正确答案:B 例1.(2011-09-27)有以下程序 #include
?
1、int *p[3];定义的是指针数组,表示一个数组,含有3个元素p[0]、p[1]、p[2],且这3个元素只能存放整型元素的地址
2、int (*p)[3];定义的是行指针,表示一个指针变量,它仅有一个存储空间,只能存放一个长度为2的一维数组指针。
第 32 页 共 61 页
聪智学校
例1.(06—09—33)若有定义语句:int k[2][3],*pk[3];则以下语句正确的是(B) A)pk=k; B)pk[0]=&k[1][2]; C)pk=k[0]; D)pk[1]=k;
【解析】题目中定义了一个二维数组和一个指针数组,pk是指针数组名,不能被
存字符串\的那段内存的首地址赋值给指针p,使得指针p指向了字符串,这样就可以通过指针来操作字符串了。
【注意】char str[10] ; str=\是错误的!数组名是地址常量,不能进行赋值
赋值,指针数组pk中的元素是指针,并且二维数组名是指向一维数组的指针常量,操作! 相当于行指针,二者不可转换,所以A、C、D选项均有误,本题答案选B。
?
“三名主义”(考试的重点)
例2.(09-09-27) 若有定义语句: int a[4][10],*p,*q[4];且0<=i<4,则错误的赋值是 (A) 数组名:表示第一个元素的地址。数组名是地址常量名,不能进行赋值和自加(减)A)p=a
B)q[i]=a[i]
C)p=a[i]
D)p=&a[2][1]
等运算。(考了很多次) 【解析】p为基类型为int的指针,指向一个整形数据,也就可以指向一个数组元 函数名:表示该函数的入口地址。 素,所以D正确。指针数组q的每个数组元素q[i]的基类型也为int,所以p、a[i]、 字符串常量名:表示第一个字符的地址。 a[i]的基类型一致,选项B、C也是正确的。
例11.(2011-09-22)有以下程序(注:字符a的ASCII码值为97) #include
{ char *s={“abc”}; do
{printf(“%d”,*s);++s;} while(*s);
8.知识点:指针与函数
例1.(08—04—40)设有定义语句int(*f)(int);,则以下叙述正确的是__B_______。 A)f是基类型为int的指针变量
B)f是指向函数的指针变量,该函数具有一个int类型的形态 C)f是指向int类型一维数组的指针变量
D)f是函数名,该函数的返回值是其类型为int类型的地址
【解析】在c语言中,函数名代表此函数的入口地址,所因此,可以定义一种}程序运行后的输出结果是 (B) 指向函数的指针来存放函数的入口地址,定义方式是:函数返回值类型(*函数指针 名)(参数类型列表);本题答案选B。
A.abc
B.789
C.7890
D.979898
例11.(2011-09-30)若有定义语句:char *s1=”OK”;*s2=”ok”;,以下选项中,能够输出“OK”的语句是 (D) A.if(strcmp(s1,s2)==0) puts(s1);
9.知识点:指针与字符串
?
可以通过字符指针来处理字符串
例如:char *p=\或者char *p;p=\把字符串赋值给指针p,实质是把保B.if(strcmp(s1,s2)!=0) puts(s2);
第 33 页 共 61 页
聪智学校
C.if(strcmp(s1,s2)==1) puts(s1); D.if(strcmp(s1,s2)!=0) puts(s1);
【解析】strcmp函数作为字符串比较函数,当s1等于s2所指字符串时结果为0, 当s1大于s2所指字符串时结果为 >0,当s1小于s2所指字符串时结果为 <0 例11.(07—04—44)有下列程序: main()
{char ch[]=“uvwxyz”,*pc; pc=ch;printf(”%c\n”,*(pc+5)); } 程序运行后的输出结果是(A)
A)Z B)0 C)元素ch[5]的地址 D)字符Y的地址
【解析】指针P指向了字符数组ch,*(pc+5)-->ch[5]-->?z?,printf函数要求以%c形式输出,故输出字符Z。
例12.(09-09-37)设有定义:char *c;.以下选项中能够使字符型指针c正确指向一个字符串的是(A)
A)char str[]=”string”; c=str; B)scanf(“%s”,c); C)c=getchar();
D)*c=”string”;
【解析】选项A为正确用法。先将字符串存于字符数组中,然后将数组名赋给字符指针。选项B为无语法错误,但运行时可能会出现问题。原因是字符指针没有
被赋值,是一个不确定的值,指向一个不确定的内存区域,这个区域可能存放有用的指令或数据。在这个不确定的区域重新存放输入的字符串,可能会发生无法预知的错误。选项C错误。getchar()函数输入一个字符给字符型变量,而不应该是字符指针。选项D错误。*c=”string”应该改为c=”string”才是正确的。
第 34 页 共 61 页
聪智学校
第五课 函数
第 35 页 共 61 页