前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >全国二级C知识点总结4-指针

全国二级C知识点总结4-指针

作者头像
用户6755376
发布2019-11-21 12:20:06
发布2019-11-21 12:20:06
9520
举报

本课重要知识点:

1.知识点:指针的概念与指针变量

l 指针就是地址指针变量是用来存储地址,而一般变量是用来存储数值

例1.(09-09-26)有如下程序输出结果为 1,2,2,1

#include <stdio.h>

main()

{ int m=1,n=2,*p=&m,*q=&n,*r;

r=p ;p=q ;q=r ;

printf(“%d,%d,%d,%d\n”,m,n,*p,*q) ;

}

【解析】p、q为指针,初始化时p指向m,q指向n。执行r=p ;p=q ;q=r ;p和q的值交换,从而p指向n,q指向m。指针的改变不会应用m、n的值,最后输出*p和*q的值分别为n、m的值。

2.知识点:指针的引用

l 指针的引用是通过两个运算符实现“&”和“*”实现的

&是取地址符号,它的一半格式是:&变量名。例如:int i ; &i表示取i的地址。

*是取值运算符,它的一般格式:*指针变量名。例如:inti=10,*p=&i; *p表示取i的值10

例1.(2011-09-25)若定义语句:intyear=2009,*p=&year;,以下不能使变量year中的值增至2010的语句是 (D)

A.*p+=1; B.(*p)++; C.++(*p); D.*p++;

【解析】*和++同级别,按自左向右的结合方向,因此D选项可转变为*(p++),从而只是使指针发生移动,而不能将p所指变量增1

例2.(06—04—24)若有说明语句:double *p,a;则能通过scanf语句正确给输入项读入数据的程序段是 (D)

A)*p=&a; scanf("%lf",p);

B)*p=&a; scanf("%f",p);

C)p=&a; scanf("%lf",*p);

D)p=&a; scanf("%lf",p);

【解析】对于scanf函数,输入数据列表必须是合法地址表达式(可以使地

址常量、指针),A选项、B选项*使用错误。

例3.(09-03-16)若有定义语句 doule x,y,*px,*py;执行了px=&x;py=&y;之后,正确的输入语句是(C)

A) scanf("%f%f",x,y); B) scanf("%f%f"&x,&y);

C)scanf("%f%le",px,py); D) scanf("%lf%lf",x,y);

【解析】A,D选项中的x,y缺少取地址符,B项中&x之前缺少逗号,格式不正确。

3.知识点:指针变量的初始化

l 指针变量在使用前必须要初始化,把一个具体的地址赋给它,否则引用时会出错,如果不指向任何数据就赋“空值”NULL。

l 指针变量两种初始化方法:方法一:int a=2,*p=&a;(定义的同时初始化)

方法二:int a=2,*p;p=&a;(先定义后初始化)

例1.(07—04—29)设已有定义:float x;则以下对指针变量P进行定义且赋初值的语句中正确的是 (D)

A)float *p=1034; B)int *p=(float)x; C)float p=&x; D)float *p=&x;

【解析】可以给一个指针赋值的只能是一个与该指针同类型的指针(或地址值);故A、B选项错误;C选项声明指针出错,P前面的指针说明符*不能省略。

4.知识点:指针的运算

l *p++和(*p)++之间的差别:*p++是地址变化,(*p)++是指针变量所指的数据变化。一个指针变量加一个整数不是简单的数学相加,而是连续移动若干地址。当两个指针指向同一数组时,它们可以比较大小进行减法运算。

例如:int a[10],*p; p=a; p++;表示p移动一个存储单元,p指向a[1],只有当指着指向数组元素时,指针的运动才有意义。

5:知识点:指针与数组

l 指针与一维数组

数组名代表数组的首地址。一维数组中,第一个元素的地址即为该数组的起始地址。建立指针变量与一维数组的联系:

例如: inta[6],*pa; pa=a;或pa=&a[0];

说明:①数组名a代表该数组的首地址,也即a[0]的地址。

② pa=a;或pa=&a[0];使pa保存了数组a的首地址,pa,a,&a[0]都指向一个地址。

③以上操作可等价于 int a[6],*pa=a;

④如果pa=&a[3];表示*pa的值就是a[3]的地址。

注意:数组a是一个地址常量,它永远指向数组的首地址,不能重新赋值。因此 a=&i;或a++都是错误的。

例1.(08—04—23)有以下程序

#include<stdio.h>

main()

{int a[]={1,2,3,4),y,*p=&a[3];

--p;y=*p;printf("y=%d\n",y);

} 程序的运行结果是(D)

A)y=0 B)y=l C)y=2 D)y=3

【解析】程序中定义一个一维数组,并初始化,再一定义了一变量和一个指针(将指针指向数组下标为3的一个元素),执行--p;(注意,当指针指一个元素后,指针变量加上“*”时,表示引用的是元素的值,当不加“*“时表示引用的是地址),向前移动一个位置,指向a[2],y=+p;(将p指针指向的值3赋给变量y),输出y的值为3。

例2.(11-03-24)设有定义:double x[10],*p=x;,以下能给数组x下标为6的元素读入数据的正确语句是( C )

A)scanf("%f",&x[6]); B)scanf("%lf",*(x+6));

C)scanf("%lf",p+6); D)scanf("%lf",p[6]);

【解析】数组名是数组的首地址,p=x,指针p指向数组的首地址,要表示数组x下标为6的元素的地址可以有&x[6],x+6,p+6,&p[6],scanf后面的参数列表必须是地址列表,B中*(x+6)D中p[6]都是取数组x下标为6的元素的值,A中格式控制符%f与double类型不匹配,所以选C。

6.知识点:用指针访问数组元素

l 通过指针引用数组元素

例如:int*p,a[5]; p=&a[0];

说明:①指针变量p指向了数组元素a[0],可以使用访问运算符“*”来引用变量a[0];

例:*p=18;等价于a[0]=18;

②*(p+1)表示a[1] p+1表示&a[1]

l 通过数组的首地址引用数组元素

例如:int a[5];

说明:①a是数组名,表示收地址,可以把a当做一个指针常量。

②*a等价与a[0],*(a+1)等价与a[1];a等价于&a[0],a+1等价与&a[1];

l 用带下标的指针变量引用一维数组元素

例如:int*p,a[5]; p=a;

说明:①p[0]表示p指针指向的内存单元,p[1]表示p指向的内存单元

②a[i]的等价引用方法:a[i]、p[i]、*(a+i)、*(p+i)

③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 <stdio.h>

void fun(int *p)

{printf(“%d\n”,p[5]);}

main()

{int a[10]={1,2,3,4,5,6,7,8,9,10};

fun(&a[3]);

}程序运行后的输出结果是 (D)

A.5 B.6 C.8 D.9

【解析】fun函数被调用时将&a[3]通过传递付给了形参指针变量p,此时可用*p或p[0]来表示a[3],因此p[5]亦可表示a[8],所以输出结果为9

7.知识点:指针与二维数组

l 任何一个二维数组均由若干个一维数组组成,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;

l 指针数组的定义方式:

*指针数组名[常量表达式];如:int *p[3];

l 行指针的一般定义形式如下:

类型名(*指针数组名)[常量表达式]; 如:int (*p)[2];

l 指针数组与行指针的区别

1、int *p[3];定义的是指针数组,表示一个数组,含有3个元素p[0]、p[1]、p[2],且这3个元素只能存放整型元素的地址

2、int (*p)[3];定义的是行指针,表示一个指针变量,它仅有一个存储空间,只能存放一个长度为2的一维数组指针。

例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是指针数组名,不能被赋值,指针数组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也是正确的。

8.知识点:指针与函数

例1.(08—04—40)设有定义语句int(*f)(int);,则以下叙述正确的是__B_______。

A)f是基类型为int的指针变量

B)f是指向函数的指针变量,该函数具有一个int类型的形态

C)f是指向int类型一维数组的指针变量

D)f是函数名,该函数的返回值是其类型为int类型的地址

【解析】在c语言中,函数名代表此函数的入口地址,所因此,可以定义一种指向函数的指针来存放函数的入口地址,定义方式是:函数返回值类型(*函数指针名)(参数类型列表);本题答案选B。

9.知识点:指针与字符串

l 可以通过字符指针来处理字符串

例如:char *p="China"或者char *p;p="China";把字符串赋值给指针p,实质是把保存字符串"China"的那段内存的首地址赋值给指针p,使得指针p指向了字符串,这样就可以通过指针来操作字符串了。

【注意】char str[10] ; str="China";是错误的!数组名是地址常量,不能进行赋值操作!

l “三名主义”(考试的重点)

数组名:表示第一个元素的地址。数组名是地址常量名,不能进行赋值和自加(减)等运算。(考了很多次)

函数名:表示该函数的入口地址。

字符串常量名:表示第一个字符的地址。

例11.(2011-09-22)有以下程序(注:字符a的ASCII码值为97)

#include <stdio.h>

main()

{ char *s={“abc”};

do

{printf(“%d”,*s%10);++s;}

while(*s);

}程序运行后的输出结果是 (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);

B.if(strcmp(s1,s2)!=0) puts(s2);

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”才是正确的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 计算机二级C语言 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档