版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
全国计算机等级考试二级Email:huxiaoli@C语言程序设计主讲:胡晓丽高频考点CompanyLogo第8章地址和指针Top45:指针变量的定义与初始化Top46:对指针变量赋值Top47:通过指针引用一个存储单元Top48:指针的移动Top49:指针的比较Top51:指针作为函数的返回值Top50:指针作为函数的参数CompanyLogo1、变量:实质是代表了“内存中的某个存储单元”。若在内存中定义了一个变量,则这个变量的内存的地址也就确定了。例:
shortinta,b=4;floatx;010010011100110100000000000001000100100111001101010010011100110110121013101510161201120212031203&a=1012&b=1015&x=1201我们在程序中只需要指出变量名,无需知道每个变量在内存中的具体地址,每个变量与具体地址的联系是由C编译系统来完成的。对变量的存取操作就是对某个存储单元进行操作。这种直接按变量的地址存取变量值的方式称为“直接存取”。Top45指针变量的定义与初始化CompanyLogo程序中:inti;
floatk;
内存中每个字节有一个编号-----地址…...…...2000200120022005内存02003ik
编译或函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象Top45指针变量的定义与初始化CompanyLogo2、指针:也是一种变量,这种变量是用来存放内存地址的。&a2001p=&a;1011
间接存取:这种通过变量p到变量a的地址,然后再存取
变量a的值的方式称为“间接存取”。指针变量p指向了变量a的含义是:指针p中存放了变量a的地址。ap例:int*p;
inta=3;10122002Top45指针变量的定义与初始化0000001100000000CompanyLogo定义指针变量的形式:类型名*指针变量名1,*指针变量名2,…例:
int*pi,*pj;(1)*是一个说明符,说明该变量是指针变量。(2)*不可省略,否则就变成了intpi,pj(定义两个整型变量)。例:
double*pd;char*s1,*s2;只能是指向double型的变量,即存放double变量的地址。只能是指向char型的变量,即存放char型变量的地址。Top45指针变量的定义与初始化CompanyLogo例:int**p,*s,k=20;s=&k;p=&s;…...…...2000200420062005整型变量k变量s200120022003变量p20072008202000200020042004s=*pk=*s所以:k=**p说明:(1)指针p的基类型是int类型的指针。(2)&是求地址运算符。(3)因为基本数据类型int、float、char等所需存储空间不同,所以需要定义指针变量的基类型。Top45指针变量的定义与初始化CompanyLogo例:指针的概念main(){inta;
int*pa=&a;a=10;printf("a:%d\n",a);printf("*pa:%d\n",*pa);printf("&a:%x(hex)\n",&a);printf("pa:%x(hex)\n",pa);printf("&pa:%x(hex)\n",&pa);}运行结果:a:10*pa:10&a:f86(hex)pa:f86(hex)&pa:f88(hex)…...…...f86f8af8cf8b整型变量a10指针变量paf87f88f89f86Top45指针变量的定义与初始化CompanyLogoTop45指针变量的定义与初始化考点指针变量定义的形式:存储类型类型名*指针变量名1,*指针变量名2,…也可以定义的同时赋初值:存储类型类型名*指针变量名1=[初值],…“存储类型”可以缺省,缺省时的存储类型为自动型aoto定义指针变量时,指针变量名前必须有一个*,在此它是定义指针变量的标志,不同于后面所说的“指针运算符”初值的形式通常有三种:“&普通变量名”、“&数组元素”和“数组名”C语言规定:数组名代表的是数组的首地址,即第一个元素的地址。CompanyLogoTop45指针变量的定义与初始化真题分析(2013年3月)DCompanyLogoTop45指针变量的定义与初始化真题分析(2007年4月)floatx;则以下对指针变量p进行定义且赋初值的语句中正确的是——A、float*p=1024;B、int*p=(float)xC、floatp=&xD、float*p=&aDCompanyLogoTop45指针变量的定义与初始化真题分析(2004年4月)设有定义:intn=0,*p=&n,**q=&p;则以下选项中,正确的赋值语句是:——A、p=1B、*q=2C、q=p;D、*p=5…...…...f86f8af8cf8bf87f88f89整型变量n指针变量p指针变量q0f86f88*q=p*p=n*q=pn=**DCompanyLogoTop46给指针变量赋值一、给指针变量赋地址值指针变量可以通过不同的方式获得地址值,从而指向一个具体的对象。指针变量获得地址通过取地址运算符&通过指针变量通过标准函数CompanyLogoTop46给指针变量赋值&:表示求出变量的地址。例:intk=1,*q,*p;q=&k;1、通过取地址运算符&…...…...2000200420062005整型变量k变量q200120022003变量p20072008120002000无具体地址值*q1说明:(1)求地址运算符&只能用于变量和数组元素。不能用于常量、表达式和register变量。
q=&(k+1)×(2)&必须放在运算对象的左边,而且运算对象的基类型要与指针变量的基类型相同。CompanyLogoTop46给指针变量赋值(3)在scanf函数中,输入的各变量之前都必须加符号&,就是把从终端读入的数据依次放到这些地址所代表的存储单元中。所以,以下语句是等价的。
scanf(“%d”,&k);
q=&k;
scanf(“%d”,q);2、通过指针变量获得地址值通过赋值运算把一个指针变量中的地址赋给另外一个指针变量,从而使两个指针指向同一个地址。CompanyLogo例:
intk=1,*p,*q;q=&k;p=q;…...…...2000200420062005整型变量k变量q200120022003变量p20072008120002000*q120002000Top46给指针变量赋值CompanyLogo3、通过标准函数获得地址通过调用库函数malloc和calloc在内存中开辟动态存储单元,并把所开辟的动态存储单元的地址赋给指针变量。二、给指针变量赋空值NULL是在stdio.h中定义的预定义符,代码值为0。
p=NULL;执行该语句后,p就称为空指针。上述代码等价于:
p=‘\0’;或p=0;说明:(1)这时p是具有一个确定的值--“空”,而不是指向地址为0的存储单元。(2)不能通过一个空指针去访问一个存储单元时,否则会得到一个出错信息。Top46给指针变量赋值CompanyLogo指针变量必须先赋值,再使用例main(){inti=10;int*p;*p=i;printf(“%d”,*p);}危险!例
main(){inti=10,k;int*p;
p=&k;*p=i;printf(“%d”,*p);}…...…...2000200420062005整型变量i10指针变量p200120022003随机Top46给指针变量赋值CompanyLogo考点: 一个指针可以通过以下三种方式获得一个确定的地址,从而指向一个具体的对象:通过求地址运算(&)通过指针变量获得地址值通过标准函数获得地址值Top46给指针变量赋值求地址运算符&只能用于变量和数组元素,不能用于表达式、常量或者被说明为register的变量。且&必须放在运算对象的左边,而且运算对象的类型必须与指针变量的基类型相同。CompanyLogo真题分析:(2013年3月)Top46给指针变量赋值CCompanyLogo真题分析:(2013年3月)Top46给指针变量赋值DCompanyLogo真题分析:(2005年9月)设有定义:intn1=0,n2,*p=&n2,*q=&n1;,以下赋值语句中与n2=n1;语句等价的是——A、*p=*q;B、p=q;C、*p=&n1;D、p=*q;Top46给指针变量赋值ACompanyLogoTop47通过指针来引用一个存储单元*:间接访问运算符(间址运算符)例:
int*p,i=10,j;p=&i;j=*p;
/*等价于j=*(&i)*/…...…...2000200420062005整型变量i变量j200120022003变量p20072008102000*p10200010上述语句等价于:
j=i;说明:(1)*的运算对象必须是地址或者是存放地址的指针变量。(2)*的含义是取地址中的内容CompanyLogo例:
int**p,*s,k=20;s=&k;p=&s;*s代表存储单元k*p代表存储单元s*(*p)代表存储单元k20pskTop47通过指针来引用一个存储单元…...…...f86f8af8cf8bf87f88f89整型变量k指针变量s指针变量p20f86f88*p=s*s=k*p=sk=**CompanyLogo200010i_pointer*i_pointer&i_pointeri…...…...2000200420062005整型变量i10变量i_pointer2001200220032000指针变量i_pointer-----指针变量,它的内容是地址量*i_pointer----指针的目标变量,它的内容是数据&i_pointer---指针变量占用内存的地址i_pointer&i&(*i_pointer)i*i_pointer*(&i)i_pointer
=
&i
=
&(*i_pointer)i
=
*i_pointer
=
*(&i)Top47通过指针来引用一个存储单元&与*运算符含义两者关系:互为逆运算理解含义:取变量的地址单目运算符优先级:2结合性:自右向左含义:
取指针所指向变量的内容单目运算符优先级:2结合性:自右向左CompanyLogoTop47通过指针来引用一个存储单元考点 指针运算符“*”:其作用是返回以操作对象的值作为地址的变量的内容。指针运算符“*”是单目运算符,优先级高于所有的双目运算符,结合性是自右向左。CompanyLogoTop47通过指针来引用一个存储单元真题分析(2007年4月)有以下程序,该程序试图通过指针p为变量n读入数据并输出,但程序有多处错误,以下语句正确的是:——A、intn,*p=NULL;B、*p=&n;C、scanf(“%d”,&p);D、printf(“%d\n”,p);#include“stdio.h”main(){intn,*p=null;*p=&n;printf(“inputn:”);scanf(“%d”,&p);printf(“outputn:”);printf(“%d\n”,p);}ACompanyLogoTop47通过指针来引用一个存储单元真题分析(2007年4月)以下程序的功能是:利用指针指向三个整型变量,并通过指针运算找出三个数中的最大值,输出到屏幕上,请填空:main()
{
intx,y,z,max,*px,*py,*pz,*pmax;
scanf("%d%d%d",&x,&y,&z);
px=&x;py=&y;pz=&z;pmax=&max;
_______;
if(*pmax<*py)*pmax=*py;
if(*pmax<*pz)*pmax=*pz;
printf("max=%d\n",max);
}*pmax=*px或*pmax=x或max=x或max=*pxCompanyLogoTop47通过指针来引用一个存储单元真题分析(2005年9月)若有定义:intx=0,*p=&x;,则语句printf("%d\n",*p);的输出结果是——A、随机值B、0C、x的地址D、p的地址BCompanyLogo考点:所谓移动指针就是对指针变量加上或减去一个整数,或通过赋值运算,使指针指向相邻的存储单元。只有当指针指向一串连续的存储单元时,还可以和指向同一串连续存储单元的指针进行相减的运算,除此之外,不可以对指针进行任何其它的算术运算。Top48指针的移动指针变量只能进行逻辑运算和相减的算术运算。不是指向同一数组的指针变量运算是无意义的。指针变量的值加1或减1,并不能地址加1中减1,而是加上或减去该变量在内存中所占的字节数,该字节数由指针的基类型决定。CompanyLogo111122334455a0a1a2a3a4pqDD00DD02DD04DD06DD08DD0ADD0CDD0EDD10ijDD12DD14DD16p=&a0;DD00q=p+2;DD04q++;DD06q--;DD04i=*p; 11j=*q; 33k=*p-*q;k-22Top48指针的移动例:CompanyLogoTop48指针的移动真题分析(2013年3月)BCompanyLogoTop48指针的移动真题分析(2004年9月)设有定义语句intx[6]={2,4,6,8,5,7},*p=x,i;要求依次输出x数组中6个元素的值,不能完成此操作的语句是——A、for(i=0;i<6;i++)printf(“%2d”,*(p++));B、for(i=0;i<6;i++)printf(“%2d”,*(p+i));C、for(i=0;i<6;i++)printf(“%2d”,*p++));D、for(i=0;i<6;i++)printf(“%2d”,*(p)++);DCompanyLogo考点: 在关系表达式中,可以对指针进行比较。即两个变量地址的比较。例:if(p<q)printf(“ppointstolowermemorythanq”);if(p==‘\0’)printf(“ppointstoNULL.”);
通常两个或多个指针指向同一目标时(一串连续的存储单元),比较才有意义。Top49指针的比较CompanyLogoTop49指针的比较真题分析(2007年4月)有以下函数,该函数的功能是——A、比较两个字符串的大小B、计算s所指字符串所占内存字节的个数C、计算s所指字符串的长度D、将s所指字符串复制到字符串t中intfun(char*s){char*t=s;while(*t++);return(t-s);}BCompanyLogoTop50指针作为函数的参数考点:
指针可以作为参数在主调函数和被调用函数之间传递数据,通过指针可以在被调用函数中地调用中的变量进行引用,这也就使得通过形参改变对应实参的值有了可能,利用此形式就可以把两个或两个以上的数据从被调用的函数返回到调用函数。CompanyLogo#include“stdio.h”intmyadd(int*a,int*b){intsum;sum=*a+*b;returnsum;}main(){intx,y,z;printf(“Enterx,y:”);scanf(“%d%d”,&x,&y);z=add(&x,&y);printf(“%d+%d=%d\n”,x,y,z);}通过传送地址值,可以在被调用函数中对调用函数中的变量进行引用。Top50指针作为函数的参数例:编写函数myadd(int*a,int*b)函数中把两个指针a和b所指的存储单元中的两个值相加,然后将和值作为函数值返回。在主函数中输入两个数给变量,把变量地址作为实参,传递给对应形参。abxyzsum…...…...20002008200A200220042006200C200E69200A20081515CompanyLogoswap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta,b;scanf("%d,%d",&a,&b);if(a<b)swap(a,b);printf("\n%d,%d\n",a,b);}例
将数从大到小输出值传递…...…...20002008200A2002200420065变量a
变量b(main)9运行结果:5,9变量x
变量y(swap)
变量t59595Top50指针作为函数的参数CompanyLogoswap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}main(){inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("\n%d,%d\n",a,b);}…...20002008200A200220042006200C200E2010...59整型变量a
整型变量b(main)指针pointer_1指针pointer_220002002(swap)指针p1指针p2整型p5920002002COPY5例
将数从大到小输出Top50指针作为函数的参数运行结果:9,5地址传递通过传送地址值,可以在被调用函数中直接改变调用函数中的变量的值CompanyLogoswap(intx,inty){intt;t=x;x=y;y=t;}main(){inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;if(a<b)swap(*pointer_1,*pointer_2);printf("\n%d,%d\n",a,b);}运行结果:5,9例
将数从大到小输出值传递…...20002008200A200220042006200C200E2010...59整型a
整型b(main)pointer_1pointer_2200020029COPY(swap)整型x整型b整型t5559Top50指针作为函数的参数CompanyLogo真题分析(2013年3月)Top50指针作为函数的参数CCompanyLogo真题分析(2006年4月)有以下程序,程序运行后的输出结果是——A、123,abcB、abc,123C、1bc,a23D、321,cbaTop50指针作为函数的参数voidswap(char*x,char*y){chart;t=*x;*x=*y;*y=t;}main(){char*s1="abc",*s2="123";swap(s1,s2);printf("%s,%s\n",s1,s2);}CCompanyLogo真题分析(2005年4月)有以下程序,程序运行后的输出结果是——A、8,2,3,4,5,6,7,1 B、5,6,7,8,1,2,3,4C、1,2,3,4,5,6,7,8 D、8,7,6,5,4,3,2,1Top50指针作为函数的参数voidf(int*x,int*y){intt;t=*x,*x=*y;*y=t;}main(){inta[8]={1,2,3,4,5,6,7,8},i,*p,*q;p=a;q=&a[7];while(p<q){f(p,q);p++;q--;}for(i=0;i<8;i+)printf("%d,",a[i]);}DCompanyLogoTop51指针作为函数返回值考点指针作为函数的返回值的一般形式为:
类型名*函数名(形式参数说明列表)存储类型有两种:static和extern,默认为extern“*函数名”不能写成“(*函数名)”否则就成了指向函数的指针。此类型函数的调用形式通常是:
p=函数名(实参列表)其中p通常是主调函数中定义的一个指针变量。CompanyLogoTop51指针作为函数返回值真题分析(2005年9月)有以下程序,程序运行后的结果是——A、8,16 B、8,8C、16,16D、4,8main(){float(*p1)(float),(*p2)(float),(*t)(float),y1,y2;p1=f1;p2=f2;y1=p2(p1(2.0));t=p1;p1=p2;p2=t;y2=p2(p1(2.0));printf("%3.0f,%3.0f\n",y1,y2);}floatfl(floatn){returnn*n;}floatf2(floatn){return2*n;}ACompanyLogoTop51指针作为函数返回值真题分析(2013年3月)CCompanyLogo第9章数组Top52:一维数组的定义与初始化Top53:一维数组的引用Top54:指向数组的指针变量的运算Top55:数组元素作为参数Top56:数组名作为函数的实参Top58:二维数组元素的一般引用Top57:二维数组的定义与初始化CompanyLogo第9章数组Top59:通过地址引用二维数组元素Top60:通过建立行指针引用二维数组元素Top61:二维数组名作为实参时函数的调用Top63:指针数组作为实参时函数的调用Top62:通过建立指针数组引用二维数组元素CompanyLogo什么是数组??数组是C提供的一种最简单的构造类型。每个数组包含一组具有同一类型的变量,这些变量在内存中占有连续的存储单元。在程序中,这些变量具有相同的名字,但具有不同的下标。如a[0],a[1],a[2]等。CompanyLogoTop52一维数组的定义和初始化一维数组:数组中的每个元素只带有一个下标。形式如下:类型名数组名[整型常量表达式],…例:
inta[6];合法标识符表示元素个数下标从0开始[]:数组运算符单目运算符不能用()a[0]0145a[1]a[2]a[3]a[4]a[5]23a编译时分配连续内存内存字节数=数组维数*
sizeof(元素数据类型)数组名表示内存首地址,是地址常量例inti=15;intdata[i];(不能用变量定义数组维数)例intdata[5];data[5]=10;//C语言对数组不作越界检查,使用时要注意CompanyLogoTop52一维数组的定义和初始化初始化方式
在定义数组时,为数组元素赋初值(在编译阶段使之得到初值)inta[5]={1,2,3,4,5};等价于:a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5;说明:数组不初始化,其元素值为随机数对static数组元素不赋初值,系统会自动赋以0值当全部数组元素赋初值时,可不指定数组长度如inta[5]={6,2,3};
等价于:a[0]=6;a[1]=2;a[2]=3;a[3]=0;a[4]=0;如inta[3]={6,2,3,5,1};()staticinta[5];等价于:a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;只给部分数组元素赋初值
inta[]={1,2,3,4,5,6};编译系统根据初值个数确定数组维数
charc[]={‘a’,’\0’,’\0’,’\0’};编译系统根据初值个数确定数组维数等价于:charc[4]={‘a’};CompanyLogoTop52一维数组的定义和初始化真题分析(2013年3月)BCompanyLogoTop52一维数组的定义和初始化真题分析(2005年4月)下列能正确定义一维数组的选项是A、inta[5]={0,1,2,3,4,5};B、chara[]={0,1,2,3,4,5};C、chara={'A','B','C'};D、inta[5]="0123";BCompanyLogoTop52一维数组的定义和初始化真题分析(2005年4月)下列叙述中错误的是——A、对于double类型数组,不可以直接用数组名对数组进行整体输入或输出B、数组名代表的是数组所占存储区的首地址,其值不可改变C、在程序执行中,数组元素的下标超出所定义的下标范围时,系统将给出“下标越界”的出错信息D、可以通过赋初值的方式确定数组元素的个数CCompanyLogoTop52一维数组的定义和初始化练习题1、以下能正确定义一维数组的是——A、intnum[];B、#defineN100 intnum[N];C、intnum[0…100]D、intN=100; intnum[N];CCompanyLogoTop53一维数组元素的引用一维数组的引用数组必须先定义,后使用只能逐个引用数组元素,不能一次引用整个数组数组元素表示形式:数组名[下标]其中:下标可以是常量或整型表达式例inta[10];printf(“%d”,a);()必须
for(j=0;j<10;j++)printf(“%d\t”,a[j]);()CompanyLogo通过数组的首地址引用数组元素间接访问运算符*:引用地址所在存储单元。a=&a[0]*&a[0]=*(a+0)=*a地址内容例:以下语句的功能是逐个输出a数组元素中的值for(k=0;k<10;k++) printf(“%d”,a[k]);Top53一维数组元素的引用for(k=0;k<10;k++) printf(“%d”,*(a+k));CompanyLogo通过指针引用一维数组元素floatarray[10],*p,k;p=a;for(k=0;k<10;k++)printf(“%4d”,*(p+k));并没有移动指针。相当于:for(k=0;k<10;k++)printf(“%4d”,a[k]);Top53一维数组元素的引用array[0]array[1]array[2]array[3]array[9]...整型指针p&array[0]整型变量kCompanyLogoint*p,a[10],i;p=a;用带下标的指针变量引用一维数组元素&a[i]可以用三种表达式来表示a[i]的地址a+ip+ia[i]*(a+i)*(p+i)也可以用四种表达式来表示数组元素a[i]p[i]1234注意:p[i]和a[i]均可表示数组中的第i个元素,但是a和p有着明显的区别,a是不可变的,而p中的地址却是可以改变的。a++a=p×p++p=ap=&a[i]√Top53一维数组元素的引用CompanyLogoa[0]a[1]a[2]a[3]a[9]...aa+9a+1a+2地址元素下标法a[0]a[1]a[2]a[9]a[0]a[1]a[2]a[3]a[9]...pp+9p+1p+2地址元素指针法*p*(p+1)*(p+2)*(p+9)[]变址运算符a[i]
*(a+i)a[i]p[i]*(p+i)*(a+i)*a*(a+1)*(a+2)*(a+9)p[0]p[1]p[2]p[9]Top53一维数组元素的引用CompanyLogoTop52一维数组的定义和初始化真题分析(2013年3月)CompanyLogo真题分析(2013年3月)Top53一维数组元素的引用CCompanyLogo真题分析(2005年4月)有定义语句:intb;charc[10];则正确的输入语句是_____A、scanf("%d%s",&b,&c);B、scanf("%d%s",&b,c)C、scanf("%d%s",b,c);D、scanf("%d%s",b,&c);Top53一维数组元素的引用BCompanyLogo真题分析(2006年4月)下列程序,运行后输出结果是——Top53一维数组元素的引用main(){inti,s=0,t[]={l,2,3,4,5,6,7,8,9};for(i=0;i<9;i+=2)s+=*(t+i);printf("%d\n",s);}A、45B、20C、25D、36CCompanyLogo真题分析(2005年4月)有以下程序,程序运行后的输出结果是——A、42 B、45 C、56 D、60Top53一维数组元素的引用main(){intp[8]={11,12,13,14,15,16,17,18},i=0,j=0;while(i++<7)if(p[i]%2)j+=p[i];printf("%d\n",j);}BCompanyLogo真题分析(2006年9月)有以下程序,程序运行后的输出结果是——A、10 B、11 C、14 D、15Top53一维数组元素的引用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);}CCompanyLogoTop54指向数组的指针变量的运算一维数组和数组元素的地址数组名可认为是一个存放地址值的指针变量名,其中的地址值是数组第一个元素的地址,也就是数组所占一串存储单元的起始地址,定义数组时的类型即是此指针变量的基类型。注意:这个指针变量中的地址值不可改变,即不可以给数组名重新赋值!也可认为数组名是一个地址常量。例:floata[10],*p,x;a=&x; a++;××CompanyLogo例intarray[10];int*p;p=&array[0];//p=array;或int*p=&array[0];或int*p=array;array[0]array[1]array[2]array[3]array[9]...整型指针p&array[0]p数组名是表示数组首地址的地址常量Top54指向数组的指针变量的运算CompanyLogo可以用对数组名加一个整数的办法,来依次表达上不同元素的地址。例:
floata[10],*p,k; for(k=0;k<10;k++) p=a+k;
array[0]array[1]array[2]array[3]array[9]...整型指针p&array[0]pTop54指向数组的指针变量的运算CompanyLogo可用以下语句输入数组元素。例:for(k=0;k<10;k++) scanf(“%d”,a+k);下面的语句功能均是从键盘读入数放入数组中for(p=a,k=0;k<10;k++) {scanf(“%d”,p);p++;}for(p=a;p-a<10;p++) scanf(“%d”,p);for(p=a,k=0;k<10;k++) scanf(“%d”,p++)Top54指向数组的指针变量的运算CompanyLogoTop54指向数组的指针变量的运算考点算术运算:p++,p--,++p,--p,p+N,p-N指针变量与指针变量的相减运算CompanyLogoTop54指向数组的指针变量的运算真题分析(2006年9月)在16位编译系统上,若有定义inta[]={10,20,30},*p=&a;当执行p++后,下列说法错误的是——A、p向高地址移动了一个字节B、p向高地址移动了一个存储单元C、p向高地址移动了两个字节D、p与a+1等价ACompanyLogoTop54指向数组的指针变量的运算真题分析(2005年4月)有以下程序,程序运行后的输出结果是——A、1,2,3,4,5,6,7,8,9,0B、2,3,4,5,6,7,8,9,10,1C、0,1,2,3,4,5,6,7,8,9D、1,1,1,1,1,1,1,1,1,1main(){inta[]={1,2,3,4,5,6,7,8,9,0},*p;for(p=a;p<a+10;p++)printf(“%d”,*p);}ACompanyLogoTop55数组元素作为函数的参数考点 在调用函数时,数组元素作为实参传递给形参,每个数组元素实际上代表内存中的一个存储单元,和普通变量一样,对应的形参必须是类型相同的变量。数组元素的值可以传递给对应的形参变量,在函数中只能对该变量进行操作,而不能直接引用对应的数组元素,更不可能在函数中改变对应数组元素的值。CompanyLogoTop55数组元素作为函数的参数真题分析(2006年9月)有以下程序,程序运行后的输出结果是——A、678910B、13579C、12345D、62345voidchange(intk[]){k[0]=k[5];}main(){intx[10]={1,2,3,4,5,6,7,8,9,10},n=0;while(n<=4){change(&x[n]);n++;}for(n=0;n<5;n++)printf("%d",x[n]);printf("\n");}ACompanyLogo说明:(1)当数组名作为实参时,对应的形参除了是指针外,还可以用另外两种形式。
arrin(int*a)
arrin(inta[])arrin(inta[M])对于后两种形式,虽然说明的形式与数组的说明相同,但C编译程序都将a处理成第一种的指针形式。(2)当传递数组名时,在被调用函数中也同样可以用数组元素的形式来引用调用函数中对应的数组元素。这种只是形式上的相似,并不是整个数组可以传递给被调用函数。(3)在被调用函数中,并没有为与数组名对应的形参开辟一串连续的空间,只是开辟了一个指针变量的存储单元。在被调用函数中所引用的数组元素就是实参数组中的元素。调用函数只是把数组的首地址传递给了形参指针,仍是遵循按“值”传递。Top57数组名作为函数的参数CompanyLogoTop57数组名作为函数的参数考点数组名作为函数的参数,在函数间传递的并不是整个数组,而是数组的首地址,换句话说,就是形参数组与实参数组指向的是同一个数组。因此,在调用函数中改变了形参数组的某元素的值,其对应的实参数组元素的值也跟着变化。当数组名作为形参时,其对应的实参可以是指针变量,也可以是数组名,或是地址表达式。CompanyLogoTop57数组名作为函数的参数真题分析(2013年3月)CCompanyLogoTop58二维数组的定义和初始化真题分析(2013年3月)ACompanyLogoTop57数组名作为函数的参数真题分析(2013年3月程序填空题)CompanyLogoTop57数组名作为函数的参数真题分析(2013年3月程序填空题)#include<stdlib.h>#include<stdio.h>#defineN10doublefun(doublex[],double*av){inti,j;doubled,s;s=0;for(i=0;i<N;i++)s=s+x[i];/**********found**********/__1__=s/N;d=32767;for(i=0;i<N;i++)if(x[i]<*av&&*av-x[i]<=d){/**********found**********/d=*av-x[i];j=__2__;}/**********found**********/return__3__;}main(){inti;doublex[N]={46,30,32,40,6,17,45,15,48,26};doubleav,m;for(i=0;i<N;i++)printf("%4.0f",x[i]);printf("\n");m=fun(x,&av);printf("\nTheaverageis:%f\n",av);printf("m=%5.0f",m);printf("\n");}CompanyLogoTop57数组名作为函数的参数真题分析(2013年3月)DCompanyLogoTop57数组名作为函数的参数真题分析(2007年4月)有以下程序,程序运行后的输出结果是——A、1,2,3,4,5,6,7,8,9,10B、1,2,6,8,10,12,7,8,9,10C、1,2,3,4,10,12,14,16,9,10D、1,2,6,8,10,12,14,16,9,10#include“stdio.h”voidf(intb[]){inti;for(i=2;i<6;i++)
b[i]*=2;}main(){inta[10]={1,2,3,4,5,6,7,8,9,10},i;f(a);for(i=0;i<10;i++) printf(“%d”,a[i]);}BCompanyLogoTop57数组名作为函数的参数真题分析(2005年9月)有以下程序,程序运行后的输出结果是:A、3553B、5335C、3535D、5353voidswap1(intc0[],intc1[]){intt;t=c0[0];c0[0]=c1[0];c1[0]=t;}main(){inta[2]={3,5},b[2]={3,5};swap1(a,a+1);swap2(&b[0],&b[1]);printf("%d%d%d%d\n",a[0],a[1],b[0],b[1]);}voidswap2(int*c0,int*cl){intt;t=*c0;*c0=*c1;*c1=t;}DCompanyLogoTop57数组名作为函数的参数真题分析(2005年4月)有以下程序,程序运行后的输出结果是:A、1,2,3,4,5 B、2,3,4,5,6C、3,4,5,6,7 D、2,3,4,5,1prt(int*m,intn){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]);}BCompanyLogoTop57数组名作为函数的参数真题分析(2005年4月)下列程序的输出结果是——A、10234 B、12344C、12334 D、12234#defineN20fun(inta[],intn,intm){inti,j;for(i=m;i>n;i--) a[i+1]=a[i]}main(){inti,a[N]={1,2,3,4,5,6,7,8,9,10};fun(a,2,9);for(i=0;i<5;i++)printf("%d",a[i]);}CCompanyLogo二维数组的定义定义方式:
数据类型数组名[常量表达式][常量表达式];数组元素的存放顺序原因:内存是一维的二维数组:按行序优先多维数组:最右下标变化最快例inta[3][4];floatb[2][5];intc[2][3][4];
inta[3,4];()行数列数元素个数=行数*列数inta[3][2]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]014523a[0][0]a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]
Top58二维数组的定义和初始化CompanyLogoTop58二维数组的定义和初始化真题分析(2013年3月)BCompanyLogoTop58二维数组的定义和初始化真题分析(2013年3月)CCompanyLogoTop58二维数组的定义和初始化真题分析(2013年3月)ACompanyLogoTop58二维数组的定义和初始化真题分析(2007年4月)设有定义语句:inta[][3]={{0},{1},{2}};,则数组元素a[1][2]的值为_______。0001002000CompanyLogoTop58二维数组的定义和初始化真题分析()有以下程序,若运行时输入:246,则输出结果是——A、200 B、204 C、240 D、246main(){intx[3][2]={0};for(i=0;i<3;i++)scanf(“%d”,&x[i]);printf(“%3d%3d%3d”,x[0][0],x[0][1],x[1][0]);}BCompanyLogoTop58二维数组的定义和初始化真题分析(2006年4月)下列数组定义中错误的是——A、intx[][3]={0};B、intx[2][3]={{l,2},{3,4},{5,6}};C、intx[][3]={{l,2,3},{4,5,6}};D、intx[2][3]={l,2,3,4,5,6};BCompanyLogoTop59二维数组元素的一般引用二维数组元素的引用形式:数组名[下标][下标]例:
doublew[4][2];w[0][2]w[i][j]w[i+k][j+k]w[0,2]w[ij]w(i+k)(j+k)√×CompanyLogo五、二维数组的定义和数组元素引用举例例:通过键盘给2*3的二维数组输入数据,第一行赋1,2,3,第二行赋10,20,30,然后按行输出此二维数组。通过二重循环来输入/输出二维数组。变量i控制行,变量j控制列。#include"stdio.h"main(){inta[2][3],i,j;printf("\nEnterdatabyline:\n");for(i=0;i<2;i++) for(j=0;j<3;j++) scanf("%d",&a[i][j]);printf("\nOutputa2-dimensionarray:\n");for(i=0;i<2;i++) for(j=0;j<3;j++) {printf("%4d",a[i][j]); if((j+1)%3==0) printf("\n"); }}Top59二维数组元素的一般引用CompanyLogoTop59二维数组元素的一般引用考点二维数组的一般引用方式: 数组名[下标1][下标2]其中下标可以是整型常量,也可以是整型表达式。Top59二维数组元素的一般引用真题分析(2013年3月)DTop59二维数组元素的一般引用真题分析(2013年3月)DCompanyLogoTop59二维数组元素的一般引用真题分析(2006年4月)下列程序执行后的输出结果是A、1 B、2 C、3 D、0Bfun(charp[][10]){intn=0,i;for(i=0;i<7;i++)if(p[i][0]=='T')n++;returnn;}main(){charstr[][10]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};printf("%d\n",fun(str));}CompanyLogoTop59二维数组元素的一般引用真题分析(2006年4月)下列程序的输出结果是——main(){inta[3][3]={{1,2,9},{3,4,8},{5,6,7}},i,s=0;for(i=0;i<3;i++)s+=a[i][i]+a[i][3-i-1];printf("%d\n",s);}30CompanyLogoTop59二维数组元素的一般引用真题分析(2005年4月)有以下程序,CompanyLogoTop59二维数组元素的一般引用
若要按下列形式输出数组右上半三角,则在程序下划线处应填入的是1234678111216BA、i-1B、iC、i+1D、4-iCompanyLogo
Top60通过地址引用二维数组元素一、二维数组和数组元素的地址
inta[3][4],*p;1.二维数组a由若干个一维数组组成(1)a[3][4]可视为由a[0],a[1],a[2]这三个元素组成。其中a[0],a[1],a[2]又是由四个整型数组成的一维数组,可用a[0][0],a[0][1]等来引用a[0]中的某个元素,其它以此类推。(2)一维数组名代表了一个不可变的地址常量,所以a[0],a[1],a[2]也代表了一个地址常量,其值依次为二维数组每行第一个元素的地址,基类型就是数组元素的类型。所以a[0]++是非法的,而a[0]+1表示第一行第二个元素,即a[0][1](3)指针p的基类型与a[i]相同,所以p=a[i]是合法的。因为a[i]==*(a+i),所以p=*(a+i)CompanyLogoa[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0]a[1]a[2]第0列第1列第2列第3列ppp2.二维数组名也是一个地址常量(可理解为一个行指针) (1)二维数组名是一个存放地址常量的指针,其值为二维数组第一个元素的地址。 (2)a的值和a[0][0]相同,不过基类型不同。a的基类型为具有4个整型元素的数组类型,即a+0的值与a[0]相同,a+1的值与a[1]相同。 (3)a+1中的数值1是4*2个字节 (4)赋值语句p=a;是不合法的,因为p和a的基类型不同。
Top60通过地址引用二维数组元素CompanyLogo3、二维数组元素的地址元素的地址有以下几种表示方式:(1)&a[i][j](2)a[i]+j(3)*(a+i)+j(4)&a[0][0]+i*4+j(5)a[0]+4*i+j注意:
&a[i][j],a[i]都是基类型为int类型,而a的基类型为具有四个元素的一维数组,所以a+i*4+j是错误的。
Top60通过地址引用二维数组元素CompanyLogointa[3][4],i,j;其中0<=i<=3,0<=j<=4则数组a中的元素a[i][j]有以下五种表达方式:(1)a[i][j](2)*(a[i]+j)(3)*(*(a+i)+j)(4)(*(a+i))[j](5)*(&a[0][0]+4*i+j)
Top60通过地址引用二维数组元素CompanyLogoTop60通过地址引用二维数组元素考点 让指针指向二维数组首地址,可以采用赋初值和赋值两种方式使指针变量指向二维数组的首地址。定义同时赋初值数据类型符 *指针变量=&二维数组名[0][0]或数据类型符*指针变量=二维数组名先定义后,再赋值指针变量=&二维数组名[0][0]指针变量=二维数组名CompanyLogoTop60通过地址引用二维数组元素真题分析(2006年9月)若有定义语句:intk[2][3],*pk[3];,则下列语句中正确的是A、pk=k;B、pk[0]=&k[1][2];C、pk=k[0];D、pk[1]=k;BCompanyLogoTop61通过建立行指针引用二维数组元素a[0]a[1]a[2]prtprt+1prt+2若有以下定义:
inta[3][2],(*prt)[2]说明:(1)*号先与prt结合,说明prt是指针变量aa+1a+2(2)然后*prt再与[2]结合,说明指针变量的基类型是包含2个元素的数组。(3)*prt的基类型与a相同所以:prt=a是合法的赋值。prt+1相当于a+1相当于a[1]a[i][j]*(prt[i]+j)(*(prt+i))[j]p[i][j]这里prt是一个指针变量,值可变,而a的值不可变。CompanyLogoTop61通过建立行指针引用二维数组元素真题分析(2013-3)BCompanyLogoTop61通过建立指针数组引用二维数组元素真题分析(2013-3)DCompanyLogoTop61通过建立指针数组引用二维数组元素真题分析若有以下说明语句,intc[4][5],(*p)[5];p=c;则能够正确引用c数组元素的是:A、p+1B、*(p+1)C、*(p+1)+3D、*(p[0]+2)DCompanyLogoTop62通过建立指针数组引用二维数组元素真题分析(2005年9月)若有语句:char*line[5];下列叙述中正确的是A、定义line是一个数组,每个数组元素是一个基类型为char的指针变量B、定义line是一个指针变量,该变量可以指向一个长度为5的字符型数组C、定义line是一个指针数组,语句中的*号称为间址运算符D、定义line是一个指向字符型函数的指针ACompanyLogoTop62通过建立指针数组引用二维数组元素真题分析(2005年4月)运行下列程序时,输入:123<CR>的输出结果为产生错误信息A.102000B.C.D123000102030BCompanyLogoTop63二维数组名作为实参时函数的调用当二维数组作实参时,形参必须是一个行指针变量。例如主函数中有以下定义和函数调用语句:#include<stdio.h>#defineM5#defineN3main(){doubles[M][N];…fun(s);…}则fun的首部可以是:(1)fun(double(*a)[N])(2)fun(doublea[M][N])(3)fun(doublea[][N])注意:(1)列下标不可少(2)系统把a处理成一个行指针(3)系统只为形参开辟一个存放地址的存储单元,而不是一系列单元CompanyLogoTop63二维数组名作为实参时函数的调用真题分析(2013年3月程序设计题)CompanyLogoTop63二维数组名作为实参时函数的调用真题分析(2013年3月程序设计题)include<stdio.h>#include<stdlib.h>#defineN5voidfun(inta[][N],intm){}main(){inta[N][N],m,i,;printf("*****Thearray*****\n");for(i=0;i<N;i++){for(j=0;j<N;j++){a[i][j]=rand()%20;printf("%4d",a[i][j]);}printf("\n");}dom=rand()%10;while(m>=3);printf("m=%4d\n",m);fun(a,m);printf("THERESULT\n");for(i=0;i<N;i++){for(j=0;j<N;j++)printf("%4d",a[i][j]);printf("\n");}}CompanyLogoTop63二维数组名作为实参时函数的调用真题分析(2004年9月)以下程序中,函数SunColumMin的功能是,求出M行N列数组中每列元素中的最小值。并计算它们的和值。和值通过形参传给主函数。请填空。#defineM2#defineN4CompanyLogoTop63二维数组名作为实参时函数的调用voidSumColumMin(inta[M][N],int*sum){inti,j,k,s=0;for(i=0;i<N;i++) {k=0; for(j=1;j<M;j++) if(a[k][i]>[j][i]) k=j; s+=____; }______=s;}a[k][i]*sumCompanyLogoTop63二维数组名作为实参时函数的调用main(){intx[M][N]={3,2,5,1,4,1,8,3},s;SumColumMin(___);printf(“%d”,s);}x或&sCompanyLogoTop63指针数组作为实参时函数的调用真题分析(2005年4月)下列程序中,fun()函数的功能是求3行4列二维数组每行元素中的最大值。请填空。voidfun(int,int,int(*)[4],int*);main(){inta[3][4]={{12,41,36,28},{19,33,15,27},{3,27,19,1}},b[3],i;fun(3,4,a,b);for(i=0;i<3;i+)printf("%4d",b[i]);printf("\n");}br[i]CompanyLogoTop63指针数组作为实参时函数的调用voidfun(intm,intn,intar[][4],int*br){inti,j,x;for(i=0;i<m;i++){x=ar[i][0];for(j=0;j<n;j++)if(x<ar[i][j])x=ar[i][j];——————=x;}}CompanyLogo第10章字符串Top64字符串常量Top65字符数组的定义Top66通过赋初值给字符数组赋字符串Top67字符串数组Top68指针指向字符串的两种方式T
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 纸制蛋糕顶饰商业机会挖掘与战略布局策略研究报告
- 裘皮外套细分市场深度研究报告
- 河南省开封市金科新未来2024-2025学年高三上学期10月联考数学试题 含解析
- 人流控制栅栏出租行业营销策略方案
- 制罐头用非电压力锅产业链招商引资的调研报告
- 写字台产品供应链分析
- 美容乳液市场发展前景分析及供需格局研究预测报告
- 球棒市场发展前景分析及供需格局研究预测报告
- 电动碾磨机产品供应链分析
- 不间断电源产品供应链分析
- 高考热点作文素材:《黑神话:悟空》
- DL-T5024-2020电力工程地基处理技术规程
- 声幅_变密度测井原理及测井解释方法_图文
- 郎毛公路跟踪审计日志20160710
- 资产 评估 质量保证措施
- 小学二年级上册道德与法治-9这些是大家的-部编ppt课件
- 《矿山机械设备》复习题
- 中国古代楼阁PPT课件
- 排舞教案_图文
- 简单趋向补语:V上下进出回过起PPT课件
- 超声检测工艺卡
评论
0/150
提交评论