版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本章考点:(1)指针与指针变量的概念(2)指针的定义、类型、赋值(3)指针运算符(4)指针与数组关系(5)用指针作函数参数(6)指针数组、数组指针、指针函数、指向指针的指针(7)main()函数的命令行参数第8章指针7.1指针的概念简单地说,指针就是地址。如:inta=3,b=5,s;编译时就会随机分别给变量分配地址。变量地址内容
a2003
b2025执行printf(“%d”,a);先找到a的地址200201从中输出3。执行s=a+b;
s204先从200201中取出3,再从202203中取出5相加后把8送入204205中这种按地址存取值的方式叫“直接访问”。C语言除了“直接访问”还有一种“间接访问”。定义一种特殊的变量如p用来存放变量地址,通过p=&a来把a的地址200201存放到p中,把p叫指针变量。用来存放把变量地址的变量叫指针变量。一、指针变量的定义:
基本类型*指针变量名int*p1,*p2;inti,j;
float*a,*b;(1)&(取地址运算符)
如:inta=5,b=6;int*p,*q;p=&a;q=&b;(2)*(取指针所指地址中内容)二、指针运算符把a的地址给p把b的地址给q如以上*p=?*q=?1.指针变量只能存放地址,不能将非地址数据赋给指针变量如:p=103.指针变量的赋值必须在同类型之间,进行比较、赋值、减等运算。2.p=NULL或’\0’或0,表示空地址,NULL是在stdio.h头文件中预定义符。其值为0。
=a=5=b=6
&*p=,*&a=&a*pfloata[4]={5,6,1,2};float*p,;p=&a[0];或p=a把数组元素的首地址给指针变p4.&只能操作在变量和数组元素上,不能用在表达式、常量或被说明为register的变量。例1通过指针变量访问整型变量main(){inta=100,b=200;int*p1,*p2;p1=&a;p2=&b;printf(“%d,%d”,a,b);printf(“%d,%d”,*p1,*p2);}100200100200例4设有定义:intn1=0,n2,*p=&n2,*q=&n1;,以下赋值语句中与n2=n1;语句等价的是
A)*p=*q;B)p=q;C)*p=&n1;D)p=*q;例3对于基类型相同的两个指针变量之间,不能进行的运算是A)<B)=C)+D)-(2)以下叙述中错误的是A)改变函数形参的值,不会改变对应实参的值B)函数可以返回地址值C)可以给指针变量赋一个整数作为地址值D)当在程序的开头包含头文件stdio.h时,可以给指针变量赋NULL(1)设有定义:intn,*k=&n;以下语句利用指针变量k读写变量n中的内容,请将语句补充完整。scanf(“%d,”[1]);printf(“%d\n”,[2]。);k*k利用指针变量来给数组变量赋值或访问数组的值:进一步简化:for(p=a,k=0;k<10;k++)scanf(“%d”,p++);再进一步简化:for(p=a,p-a<10;p++)scanf(“%d”,p);以上三种写法是等价的,要掌握,能看懂。例.有以下程序运行后的输出结果是
main()
{
int
a[]={1,2,3,4,5,6,7,8,9,0},*p;
for(p=a;p<a+10;p++)
printf(“%d,”,*p);}
A)1,2,3,4,5,6,7,8,9,0,
B)2,3,4,5,6,7,8,9,10,1,
C)0,1,2,3,4,5,6,7,8,9,
D)1,1,1,1,1,1,1,1,1,,1,for(p=a,k=0;k<10;k++){scanf(“%d”,p);p++;}如有:inta[10],*p;6、以下程序的输出结果是:#include<stdio.h>main(){printf(“%d\n”,NULL);}A)因变量无定义输出不定值B)0C)-1D)17、若程序中已包含头文件stdio.h,以下选项中,正确运用指针变量的程序段是A)int*i=NULL;scanf(“%d”,i);B)float*f=NULL;*f=10.5;C)chart=‘m’,*c=&t;D)long*L;L=‘\0’;8若有定义语句:double
x,y,*px,*py,执行了px=&x,
py=&y;之后,正确的输入语句是
A)scanf(“%f%f”,x,y);
B)
scanf(“%f%f”,&x,&y);
C)scanf(“%lf%le”,px,py);
D)
scanf(“%lf%lf”,x,y);
(9)有以下程序
#include<stdio.h>
main()
{char
*s=“ABC”;
do
{printf(“%d”,*s%10);s++;
}while(*s);}
A).5670
B).656667
C.)567
D)ABC指针有四个算术运算符“++--+-”三、指针的算术运算符(1)++或--表示指针往前或往后移动一个位置。
如:int*p;inta[10]={1,2,3,4,5,6,7,8,9};p=&a[2]*p++;*++p;*--p;(*p)++;*p;*p++*++p*--p*p--
(*p)++++(*p)(*p)----(*p)指针都会向前或向后移动指针不动,内容加一*p++*(p++)结合方向从右往左(2)p1+n或p1-nn是一个整数p1+n表示从当前指针开始第n个元素的地址。但是指针不会移动。
int*p;inta[10]={1,2,3,4,5,6,7,8,9};p=a;则p+3表示是元素a[3]的地址&a[3]。*(p+3)=p+5表示元素a[5]的地址&a[5]。*(p+5)=main(){inta[10]={9,7,6,5,4,3,2,1,0},*p;p=a;p++;printf(“%d”,*p++);printf(“%d”,*(p+5));printf(“%d”,(*p++,*++p));printf(“%d”,(*p)++);printf(“%d”,*p);}a[3]=4a[5]=671445(1)若有inta[10]={1,2,3,4,5,6,7,8,9,10},*p=a;则值为6的表达式是A)*p+6B)*(p+5)C)*p+=6D)p+5(2)以下程序输出的结果是main(){intarr[]={6,7,8,9},*ptr=arr;*(ptr+2)+=2;printf(“%d,%d\n”,*ptr,*(ptr+2));}
A)3,7B)4,8C)5,9D)6,10(3)有以下程序运行后的输出结果是
main()
{inta[10]={1,2,3,4,5,6,7,8,9,10},*p=&a[3],*q=p+2;
printf("%d\n",*p+*q);}
A)16B)10C)8D)6
(4)有以下程序运行后的输出结果是main(){chars[]="159",*p;p=s;pintf("%c",*p++);printf("%c",*p++);}A)15B)16C)12D)59五、指针变量作为函数参数对以下程序:int*f(int*x,int*y)
{if(*x<*y)
returnx;
else
returny;}main()
{inta=7,b=8,*p,*q,*r;
p=&a;q=&b;
r=f(p,q);printf("%d,%d,%d\n",*p,*q,*r);}执行后输出结果是
传递地址7,8,71、下列程序的输出结果是【】。voidfun(int*n){while((*n)--);printf(“%d”,++(*n));}main(){inta=100;fun(&a);}答案:02、有以下程序voidfun(char*c,intd){*c=*c+1;d=d+1;printf(“%c,%c,”,*c,d);}main(){chara=’A’,b=’a’;fun(&b,a);printf(“%c,%c\n”,a,b);}程序运行后的输出结果是A)B,a,B,a B)a,B,a,B C)A,b,A,b D)b,B,A,b答案D例3有以下程序输出结果是:
swap(int*p1,int*p2)
{int*t;
t=p1;p1=p2;p2=t;}
main()
{inta=5,b=7,*b1,*b2;
b1=&a;b2=&b;
printf(“%d,%d”,a,b);swap(b1,b2);
printf("%d,%d,%d\n",*b1,*b2);}例4有以下程序输出结果是:
swap(int*p1,int*p2)
{intt;
t=*p1;*p1=*p2;*p2=t;}
main()
{inta=5,b=7,*b1,*b2;
b1=&a;b2=&b;
printf(“%d,%d”,a,b);swap(b1,b2);
printf("%d,%d,%d\n",*b1,*b2);}答案:5,7答案:5,7答案:5,7答案:7,5例5有以下程序运行后的输出结果是
#include
<stdio.h>
void
fun(
int
*a,int
*b)
{int
*c;
c=a;a=b;b=c;}
main()
{int
x=3,y=5,*p=&x,*q=&y;
fun(p,q);printf(“%d,%d,”,*p,*q);
fun(&x,&y);printf(“%d,%d\n”,*p,*q);}A).3,5,5,3
B.)3,5,3,5
C).5,3,3,5
D).5,3,5,36、有以下程序voidfun(char*a,char*b){a=b;(*a)++;}main(){charc1=‘A’,c2=‘a’,*p1,*p2;p1=&c1;p2=&c2;fun(p1,p2);printf(“%c%c\n”,c1,c2);}程序运行后的输出结果是:A)AaB)aaC)AbD)Bb7、以下函数用来求出两个整数之和,并通过形参将结果返回,请填空voidfunc(intx,inty,[]z){*z=x+y;}答案:CInt*8有以下程序输出结果是:voidswap(char*x,char*y)
{chart;
t=*x;*x=*y;*y=t;}
main()
{char*s1=”abc”,*s2=”123”;
swap(s1,s2);
printf(“%s,%s”,s1,s2);}A)123,abcB)abc,123C)1bc,a23D)321,cba答案:C8.2指针与一维数组:指向一维数组的指针变量:inta[10],*p=a;
(1)c规定数组名是代表数组的首地址,是常量,不可以重新给数组名赋值。如:inta[10],x;则:a=&x或a++都是非法的。
(2)c规定可以用数组名加一个整数的办法,来依次表达数组不同元素地址,如a=a+0等价&a[0]a+1等价&a[1]等价a+2&a[2](3)对有inta[10],*p=a则p=p+0等价&a[0],p+1等价&a[1],因此:p+1与a+1p+2与a+2p+i与a+i等价
(4)表达一个数组元素a[i]的地址有三种方法:&a[i],a+i,p+i(5)如有:inta[10],*p=a;则引用数组元素a[i]有四种方法:a[i]*(a+i)*(p+i)p[i]指向一维数组的指针变量:inta[10],*p=a;(6)这里p与a有明显的区别,p是指针变量,p++可以移动指针,使p的值改变,a是指针常量,值不变。a++,a=&a[i]是非法的运算,而p++,p=&a[i]是合法的如有charc[20],*p;c=“howareyou”是非法的p=“howareyou”是合法的p指针变量,代表h的地址C是数组名,是常量,不能赋值charc[20]=“howareyou”这是合法的,定义与赋值(1)以下语句或语句组中,能正确进行字符串赋值的是A)char*sp;*sp="right!";B)chars[10];s="right!";C)chars[10];*s="right!";D)char*sp="right!";
(2)设已有定义:char*st="howareyou";下列程序段中正确的是
A)chara[11],*p;strcpy(p=a+1,&st[4]);
B)chara[11];strcpy(++a,st);
C)chara[11];strcpy(a,st);
D)chara[],*p;strcpy(p=&a[1],st+2)(7)用一维数名作实参时aa(s)(假设aa(int*)为定义好的函数,s为一维数组),对应的形参可以为:aa(int*s),aa(ints[]),aa(ints[M]),实质上C都是把其按第一种指针形式理。
(3)下面判断正确的是A)char*a="china";等价于char*a;*a="china";B)charstr[5]={"china"};等价于charstr[]={"china"};C)char*s="china";等价于char*s;s="china";D)charc[4]="abc",d[4]="abc";等价于charc[4]=d[4]="abc";(1)有以下程序
#include<stdio.h>
void
fun(char
*s)
{while(*s)
{
if(*s%2==0)
printf(“%c”,*s);
s++;}
}
main()
{
char
a[]={“good”};
fun(a);printf(“\n”);}
A.)d
B).go
C).god
D).good
(3)有以下程序执行后输出结果是main(){intx[8]={8,7,6,5,0,0},*s;s=x+3;printf("%d\n",s[2]);}A)随机值 B)0 C)5 D)6(2)下列程序是给数组所有元素输入数据,则下划线处应填入main(){inta[10],i=0;while(i<10)scanf(“%d”,
);
A)a+(i++)B)&a[i+1]C)a+iD)&a[++i](1)下列程序的输出结果是main(){chara[10]={9,8,7,6,5,4,3,2,1,0},*p=a+5;printf(“%d”,*--p);}A)非法B)a[4]的地址 C)5D)3(4)有以下程序运行后的输出结果是
main()
{inta[]={2,4,6,8,10},y=0,x,*p;
p=&a[1];
for(x=1;x<3;x++)y+=p[x];
printf("%d\n",y);}
A)10B)11C)14D)15C若有定义:int*p,a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};913511a[0]a[1]a[2]a1371517192123说明:a是一个数组名,它包含三个(行)元素:a[0]、a[1]、a[2]。而每个元素又是一个一维数组。8.3指针与二维数组每行包含4个元素。用a[0][0]、a[0][1]、a[0][2]等来引用a[0]中元素。a[0]、a[1]、a[2]是二维数组中的三个一维数组名。二维数的地址(1)二维数组名a也是指针,代表数组的首地址&a[0][0],是常量。(2)对二维数组a[3][4]来说,它是由三个一维a[0],a[1],a[2]组成a[0],a[1],a[2]为一维数组名,分别代表二维数a[3][4]每行的首地址&a[0][0],&a[1][0],&a[2][0]是常量。a[0]++非法。
(3)C规定可用二维数名加一个整数表示代表每行的首地址:a+i
a+0与a[0]、a相同,表示是地址&a[0][0]a+1与a[1]相同,表示是地址&a[1][0]a+2与a[2]相同,表示是地址&a[2][0]a+1移动了一行,移动了4元素假设&a[0][0]为2000,则a+1的地址为2008。若有:inta[3][4],*pp+1移动几个元素?p=a?p与a的基类型不一样,表达式a+1中的数值1的单位应是4x2个字节,表示跨越一行有4个元素,而不是2个字节,指针p只能存放2个字节的地址,p+1中的1是1x2个字节表示下1个元素。p=a[1],或p=&a[1][0]是合法的。在二维数组中a[3][4],*(a+1)是表示地址还元素内容?在一维数组中,a[0]等价与*(a+0),a[1]等价与*(a+1)(4)在二维数组中,*(a+i)是指一个地址,就是一维数组名a[i]。所以二维数组元素a[i][j]的地址可以通过以下方式表示:&a[i][j]a[i]+j*(a+i)+j所以二维数组元素a[i][j]的内容可以通过以下方式表示:&a[i][j]*(a[i]+j)*(*(a+i)+j)用二维数名作实参时aa(s)(假设aa(int*)为定义好的函数,s为一维数组),对应的形参可以为:aa(int(*s)[N]),aa(ints[][M]),aa(ints[N][M]),实质上C都是把其按第一种指针形式理。例3.有以下程序main(){inta[3][3],*p,i;p=&a[0][0];for(i=0;i<9;i++)p[i]=i;for(i=0;i<3;i++)printf("%d",a[1][i]);}程序运行后的输出结果是______。A)012B)123C)234D)345例1.若有以下的定义:intt[3][2];能正确表示t数组元素地址的表达式是A)&t[3][2]B)t[3]C)&t[1][1]D)&t[2]例2.若有以下的定义:inta[3][2],*p;能正确赋值的是:A)p=aB)p=&(a[0]+1)C)p=&a[2][1]D)p=&a[2]8.4数组指针可以通过建立一个数组指针来引用二维数组的元素。如有定义inta[3][4],(*p)[4];p是一个指针变量,其基类型是一个包含4个整型元素的数组,它的基类型与二维数组a相同,因此p=a合法,a+0与p+0、a[0]等价,a+1与p+1、a[1]等价,表示跨越一行4个元素地址,且数组元素a[i][j]与p[i][j]等价。例1若有定义:int(*a)[4];则标识符A)是一个指向整型变量的指针B)是一个指针数组名C)是一个指针,它指向一个含有四个整型元素的一维数组D)说明不合法例2若有以下定义,且0<=i<6,则正确赋值的语句是ints[4][6],t[6][4],(*p)[6];A)p=t;B)p=s;C)p=s[i];D)p=t[i];例3若有以下定义和语句:
ints[4][5],(*ps)[5];
ps=s;
则对s数组元素正确引用形式是
A).ps+1B).*(ps+3)C.)ps[0][2]D).*(ps+1)+38.5指针数组
若有定义:int*p[3],a[3][2];
在*p[3]中,根据运算符的优先级,p首先与[]结合,构成p[3],说明了p是一个数组名,相当于有3个一维数组,在它前面的*则说明了数组p是指针类型,它的每个元素都是基类型为int的指针。指针数组的最大好处是不必要指定列的宽度。则*p[3]为指针数组
charcc[][12]={“fow”,“basic”,“great”,“comp”}char*p[4]={“folrme”,“basic”,“greatwall”,“comp”}a数组元素a[i][j]的引用形式*(a[i]+j)和*(p[i]+j)是等价的区别是:p[i]的值可以改变,而a[i]的值不可以改变for(i=0;i<3;i++)p[i]=a[i];//p[i]和a[i]的基类型相同的条件下,才可以赋值p[0]、p[1]、p[2]分别指向a数组每行的开头例1若有语句:char*a[5];,以下叙述中正确的是
A)a是一个数组,每个元素是一个基类型为char的指针变量
B)a是一个指针变量
C)a是一个指针数组,语句中的*号称为间址运算符
D)a是一个指向字符型函数的指针例3有以下程序执行后输出结果是
main()
{char*s[]={"one","two","three"},*p;
p=s[1];
printf("%c,%s\n",*(p+1),s[0]);}
A.)n,twoB.)t,oneC).w,oneD.)o,tw例4有以下定义和语句()inta[3][2]={1,2,3,4,5,6,},*p[3];p[0]=a[1];则*p[0]+1)所代表的数组元素是A.)a[0][1]B.)a[1][0]C).a[1][1]D.)a[1][2]main()可以带两个形参8.6指针数组的重要应用格式为:main(intargcchar*argv[])其中argc,*argv[]是两个参数名,名称可由自已取,但类型是固定的,第一个整型,第二个是指针数组。通过命令行执行程序来获得参数。程序file.c经过编译生成file.obj文件,再通过连接生成file.exe的可执行文件。在DOS提示符下:输入file就可执行程序如在命令提示下输入fileokgood这时argc的值为3argv[0]为字符串“file”argv[1]为字符串“ok”argv[2]为字符串“good”为了执行程序:字符串argv[0]不可少,argc值为1如在命令提示下输入file这时argc的值为1,
argv[0]为字符串“file”(1)下面程序的文件名为t.exe,在DOS下输入的命令行参数为:ttomeetme<回车>则程序输出的结果是#include"stdio.h"main(argc,argv)intargc;char*argv[];{inti;printf("%d\n",argc);}A)3B)4C)2D)以上答案都不正确2有以下程序,假设程序编译,连接后生成可执行文件my.exemain(intargc,char*argv[]){inti;printf(“argc=%d\n”,argc);for(i=0;i<argc;i+=2)printf(“%s”,argv[i]);printf(“\n”);}如在命令行中打入:thisisabigtable输出结果为:
A)thisatableB)bigtalbeC)abigtableD)thisisabigtable3有以下程序序编译连接后生成可执行文件exam.exe,若键入以下命令exam123(回车),则运行结果为main(intargc,char*argv[]){inti=0,n;while(argv[1][i]!='\0'){n=fun();i++;}printf("%d\n",n*argc)}intfun(){staticints=0;s+=1;returns;}A.)6B)8C)3D)4
8.7指向指针的指针(多级指针)如有int**p;则p是可以指向指针的指针变量5
100
200
300a
pq变量地址变量内容变量名例inta=5,*p,**qp=&a;q=&p;100200例1若有定义和语句,则输出结果是:int**pp,*p,a=10,b=20;pp=&p;p=&a;p=&b;printf("%d%d\n",*p,**pp);A)10,20B)10,10C)20,10D)20,20例2设有如下程序的输出结果是:main(){intx[5]={2,4,6,8,10},*p1,**p2;p1=x;p2=&p1;printf(“%d”,*(p1++));printf(“%d”,**p2);A)44B)24C)22D)468.8
指向函数的指针变量在c语言中函数名代表该函数的入口地址,因址可以定义一种指向函数的指针来存放这种地址。定义格式:返回类型(*fp)()doublefun(inta,int*p){……………..}main(){intn;double(*fp)(int,int*),y;fp=fun;y=(*fp)(56,&n);……}{……………..}main(){intn;doubley;y=fun(56,&n);……}在这里:y=(*fp)(56,&n)与y=fun(56,&n)等价。(*fp)的括号不能省,*fp(intint*)则fp不是指针变量,而说明fp是一个函数,该函数的返回值是基类型为double的指针类型。例1.说明语句int*f();中标识符f代表的是A)一个用于指向整型数据的指针变量B)一个用于指向一维组的行指针变量C)一个用于指向函数的针指变量D)一个返回值为指针型的函数名例2.设有如下定义:int(*ptr)();则以下叙述中正确的是
A)ptr是指向一维组数的指针变量
B)ptr是指向int型数据的指针变量
C)ptr是指向函数的指针,该函数返回一个int型数据
D)ptr是一个函数名,该函数的返回值是指向int型数据的指针例3程序中若有如下说明和定义语句charfun(char*);main(){char*s="one",a[5]={0},(*f1)()=fun,ch;......}以下选项中对函数fun的正确调用语句是______。A)(*f1)(a);B)*f1(*s);C)fun(&a);D)ch=*f1(s);1、有以下程序程序运行后的输出结果是prt(int
*m,int
n)
{inti;
for(i=0;i<n;i++)
m[i]++;}
main()
{
inta[]={1,2,3,4,5},i;
prt(a,5);
for(i=0;i<5;i++)
printf(“%d,”,a[i]);}
A).1,2,3,4,5,B.)2,3,4,5,6,C).3,4,5,6,7,D).2,3,4,5,1,B综合练习2、有以下程序执行后的输出结果是voidfun(int*a,inti,intj){intt;if(i<j){
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 职业学校泥水工程协议
- 学校建设防尘网施工合同
- 地震学校食堂员工劳动合同
- 农业企业股权登记策略
- 林地征用补偿协议范本
- 合同纠纷调解培训
- 摩托车交易合同模板
- 农药化肥知识产权认证管理办法
- 展厅多媒体使用规范
- 财务资质管理办法
- 《基因指导蛋白质的合成》(第 1课时)教学设计
- 绵阳市高中2022级(2025届)高三第一次诊断性考试(一诊)语文试卷(含答案)
- 自然资源调查监测劳动和技能竞赛
- 2 0 2 4 年 7 月 国开专科《法理学》期末纸质考试 试题及答案
- 6.1 我对谁负责 谁对我负责 课件-2024-2025学年统编版道德与法治八年级上册
- 2023-2024学年天津市经开区国际学校八年级(上)期末物理试卷
- DB23T 3842-2024 一般化工企业安全生产标准化评定规范
- 期中模拟押题卷(1-3单元)(试题)-2024-2025学年苏教版数学六年级上册
- 环氧树脂项目可行性研究报告项目报告
- 公共政策分析第一章
- 行业协会重大活动备案报告制度
评论
0/150
提交评论