计算机计算机二级C语言程序设计第 9讲-1_第1页
计算机计算机二级C语言程序设计第 9讲-1_第2页
计算机计算机二级C语言程序设计第 9讲-1_第3页
计算机计算机二级C语言程序设计第 9讲-1_第4页
计算机计算机二级C语言程序设计第 9讲-1_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9讲指针

指针是C语言中的重要概念,也是C语言的重要特色。使用指针,可以使

程序更加简洁、紧凑、高效。

9.1指针和指针变量的概念

9.2指针变量的定义与应用

9.3数3泅指针和指向数组的指针变量

9.4字符串的指针和指向和符串的指针变量

9.5。间指针侑的I函数

9.6指针数组与中I函数main()的形参

9.7函数的指针和指向函数的指针存量

9.1指针和指针变量的概念

1.内存地址--内存中存储单元的编号

1)计算机硬件系统的内存储器中,拥有大量的存储单元(容量为1字节)。

为了方便管理,必须为每一个存储单元编号,这个编号就是存储单元的“地址”。

每个存储单元都有一个惟一的地址。

2)在地址所标识的存储单元中存放数据。

注意:内存单元的地址与内存单元中的数据是两个完全不同的概念。

例:

a

inta;a=12;

变量a内的“内容”(变量值)是12;变量值可由键盘等方法录入12

a变量的地址&a,是3000,

3000

变量的地址&a是编译时系统统一编码赋予的。

图9-1

2.变量地址——系统分配给变量的内存单元的起始地址

假设有这样一个程序:

main()

{intnum;

scanf(〃%d〃,&num);

printf("num二%d\n〃,num);

}

C编译程序编译到该变量定义语句时,将变量num登录到“符号表”中。符号

表的关键属性有两个:一是“标识符名(id)”,二是该标识符在内存空间中的

“地址(addr)”o

为描述方便,假设系统分配给变量num的4字节存储单元为3000至3003,则起

始地址迦就是变量num在内存中的地址。

3.变量值的存取——通过变量在内存中的地址进行

系统执行“scanf("%da,&num)和“printf("num=%d\n",num)时,

存取变量num值的方式可以有两种:

(1)直挎访同一直接利用变量的地址进行存取

1)上例中scanf("%d”,&nuni)的执行过程是这样的:

用变量名num作为索引值,检索符号表,找到变量num的起始地址3000;然后

将键盘输入的值(假设为12)送到内存单元3000至3003中。此时,变量num在内存

中的地址和值,如图9T所示。

2)printf(〃nunF%d\n〃,num)的执行过程,与scanf()很相似:

首先找到变量num的起始地址3000,然后从3000至3003中取出其值,最后将它

输出。

(2)回挎访问一通过另一变量访问该变量的值

C语言规定:在程序中可以定义一种特殊的变量(称为指针变量),用来存

放其它变量的地址。

例如,假设定义了这样一个指针变量P,它被分配到4000至4003单元,其值可通

过赋值语句“P二#”得到。此时,指针变量p的值就是变量mini在内存中的起始

地升3000.如图9-2所示(见下一页)。

通过指针变量P存取变量num值的过程如下:

首先找到指针变量P的地址(4000),取出其值3000(正好是变量num的起始地

址);然后从3000至3003中取出变量num的值(3)。

(3)两种访问方式的比较

两种访问方式之间的关系,可以用某人甲(系统)要找某人乙(变量)来类比。

一种情况是,甲知道乙在何处,直接去找乙就是(即直接访问)。

另一种情况是,甲不知道乙在哪,但丙(指针变量)知道,此时甲可以这么做:

先找丙,从丙处获得乙的地址,然后再找乙(即间接访问)。

main()p=#

{intnum=12;num的首地址是3000

intP指向了(首地址为

地址的变量,(存放整型屣伽尊鹭1丽

P是专门用于存放其他变量(num)

p=#

/*P是变量,专门存放整形变量地址

scanf(“%d”,p);

scanf(“%d”,&num);

printf(“%d\n",*p);

printf("%d\n",num);

}

运行结果:

12(对应scanf("%d”,p);)

12(scanf(“%d“,&num);)

12(printf(“%d\n",num);)

12(printf(“%d\n",*p);)

4指针与指针变量

(1)指针一一即地址(指针变量的值,称为指针,这个值是其他变量的地址)

一个变量的地址称为该变量的指针。通过变量的指针能够找到该变量。

(2)指针变量一一专门用于存储其它变量地址的变量

指针变量P的值就是变量num的地址。指针与指针变量的区别/关系,就是变量值与变量

(名)的区另U/关系。

(3)为表示指针变量和它指向的变量之间的关系,用指针运算符“*”表示。

例如,指针变量P与它所指向的变量num的关系,(在上例中)表示为:

*P,即*P等价于变量num。而P等价于变量&num

因此,下面两个语句(nunrf;*p=3;)的作用相同:

int*p,num;/*定义p为指针变量,定义num为指普通变量*/

/*int表示p指向整型变量,表示p是

指针型变量*/

num=3;/*将3直接赋给普通变量num*/

p=#/*把num的地址装入p,使p指向num*/

*P-3;/*将3赋给指针变量p所指向的变量*/

[Return]

指针变量的概念与小空:

指针:变量a的地址,称为变量a的指针;即&a称为变量a的指针

指针变量:用于专门存放地址的变量称为指针变量(P)O

指针变量定义的格式:基类型*指针变量;

普通变量定义:inta;

指针变量定义:int*p;

1•对指针变量,定义语句中各符号的说明

类型符号“*,,:说明p是指针变量

基类型符号int:说明p存储整型变量的地址。(基类型,用于指针运算时的步长

单位,稍后可见)

变量名:P(不要用“*P”作变量名,符号“*”只是类型说明)。

2.对指针等量.引用语句中各符号泅说明

常用运算符号:

&:取址运算,如:&a,取变量a地址

*:取值运算(指针运算),取指针变量指向的变量的数值

例:inta=2,*p;/*定义*/

p=&a;

scanf(aWf,p);printf(“%d”,*p))/*引用*/

3.对于指针变量的符号,出现在不同位置,其作用不同

(1)定义中:“”说明所定义的变量是指针变量

(2)引用中:是指社运篁符,取指针变量指向的变量的数值

9.2指针变量的定义与应用

9.2.1指针变量的定义与相关运算P-int*pint

------k12num_int

[案例9.1]指针变量的定义与相关运算示例。40003000

/*案例代码文件名:AL9」.C*/40033003

#include<stdio.h>

图9-2

main()

intnumint=12,*pint;/*定义一个指向int型数据的指针变量p_int

floatnum_f=3.14,*p_f;/*定义一个指向float型数据的指针变量p_f

charnumch='p'*p_ch;/*定义一个指向char型数据的指针变量p_ch

p_int=&num_int;/*取变量num_int的地址,赋值给p_int*/

pf=&numf;/*取变量num_f的地址,赋值给p_f*/

pch=&numch;/*取变量num_ch的地址,赋值给p_ch*/

printf(^num_int=%d,*p_int=%d\n”,num_int,*p_int);

printf(“num_f=%4.2f,*p_f=%4.2f\n",num_f,*p_f);

printf("numch二%c,*p_ch=%c\n",numch,*pch);

AI91C「程良病示1

程序运行结果:

numint=12,*pint=12

num_f=3.14,*p_f=3.14

num_ch=p,*p_ch=p

程序说明:

(1)头三行的变量定义语句——指针变量的定义

与一般变量的定义相比,除变量名前多了一个星号(指针变量的定义标

识符)外,其余一样:

基(数据)类型*指针变量L*指针变量2……];

注意:此时的指针变量P_int、p_f、p_ch,并未指向某个具体的变量(称指针

是悬空的)。使用悬空指针很容易破坏系统,导致系统瘫痪。

(2)中间三行的赋值语句一一取地址运算(&)

取地址运算的格式:&变量

例如,&numint、&numf、&num_ch的结果,分别为变量numint、numf、

num_ch的地址。

注意:指针变量只能存放指针(地址),且只能是相同类型变量的地址。

例如,指针变量P_int、p_f、p_ch,只能分别接收int型、float型、char型变

量的地址,否则出错。

(3)后三行的输出语句—指针运算(*)

使用直接访问和间接访问两种方式,分别输出变量num_int、num_f、num_ch的

值。

注意:这三行出现在指针变量前的星号“*”是指针运算符,访问指针变量所

指向的变量的值,而非指针定义标识符。

理解:如果已定义pointl是指向变量a的指针变量,

(inta=12,*pointl;pointl=&a;)贝[]

1、&*pointl的含义:&a,即变量a的地址;

2、*&a的含义:即变量a;

3、(*pointl)++:即a++

*pointl++:等价*(point1++)

[案例9.2]使用指针变量求解:输入2个整数,按升序(从小到大排序)输出。

/*案例代码文件名:AL9_2.C*/

main()

{intnuml,num2;

int*numl_p=&numl,*num2_p=&num2,"pointer;

printf("Inputthefirstnumber:");scanf(,numl_p);

printf("Inputthesecondnumber:");scanf("%d”,num2_p);

printf(Unuml=%d,num2二%d\n”,numl,num2);

if(*numl_p>*num2_p)/*如果numl〉nuni2,则交换指针*/

{pointer=numl_p,numl_p=num2_p,num2_p=pointer;}

printf(^min=%d,max二%d\n”,*numl_p,*num2_p);

printf(Unuml=%d,num2=%d\nv,numl,num2);

}

AL9_2.C「程序演示]

numlpnumlnumlpnuml

交换指针交换指针

前:后:

程序运行情况:

Inputthefirstnumber:9*-1

Inputthesecondnumber:6一」

numl=9,num2=6

min=6,max=9

numl=9,num2=6

程序说明:

(1)第5行的if语句

如果*numl_p〉*nuin2_p(即numl>nuni2),则交换指针,使numl_p指向变

量num2(较小值),num2_p指向变量numl(较大值)。

(2)printf(“min=%d,max=%d\n",*numl_p,*num2_p);语句:通过指

针变量,间接访问变量的值。

9.2.2指针变量作函数参数

1.指针变量,既可以作为函数的形参,也可以作函数的实参。

2.指针变量作实参时,与普通变量一样,也是“值传递”,即将指针变量的值(一

个地址)传递给被调用函数的形参(必须是一个指针变量)。

注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的

变量的值。

[案例9.3]使用函数调用方式改写[案例9.2],要求实参为指针变量。

/*案例代码文件名:AL9_3.C*/

/xjxvjxvjxvjxvjxvjxXIX/

/XT*zr**7X*TX*T**T**7XZT**TSXTSZTSZT**TSXTS*T**T**T**TX*T**T**7X*T**T*ZTX*TS*T**T**T**T**T**T**T**T**T**T**T**T**T*ZT*/

/"exchange。功能:交换2个形参指正变量所指向的变量的值*/

/*形参:2个,均为指向整型数据的指针变量

/*返回值:无

*/

//xTsZTXZTX✓TsZTX✓rs✓rxZTX✓TSZTX✓rs✓Ts✓TNXTS#*TXZTSZTSZTXxrsxr%✓ixxTx^TsZTX✓rs✓Ts✓TNXrsZTSxrsZTSXTNXrs#*TXZTXXIXZTXxrsxTszrx^rx✓Ts✓Ts^rxZT%✓TNXTX✓ISXTX✓?>//

voidexchange(int*pointerl,int*pointer2)

{inttemp;

temp=*pointeri,*pointerl=*pointer2,*pointer2=temp;

}

/*主区数main。*/

main()

{intnuml,num2;

int*numl_p=&numl,*num2_p=&num2;

printf("Inputthefirstnumber:");scanf("%d”,numlp);

printf("Inputthesecondnumber:");scanf("%d”,num2_p);

printf(^numl=%d,num2=%d\nw,numl,num2);

if(*numl_p>*num2_p)/*即numl〉num2)*/

exchange(numl_p,num2_p);/*指针变量作实参*/

/*输出排序后的numl和num2的值*/

printf("min二%d,max二%d\n”,numl,num2);

}AL93.C[程序演示]

[案例9.3]与[案例9.2]的主要区别是

通过函数exchange。的调用,交换2个形参指针变量所指向的变量的值。

功能:/*在函数exchange。的调用中,实参把地址传给形参,形参指针变量所指向

国(变量)存储单元地址与实参指针变量所指向的(变量)存储单元地址是同一单

TTjo

其效果是:交换2个形参指针变量所指向的变量的值,实参指针变量所指向的变量

的值也随之交换。

原因是:实参、形参指向的是同一地址单元

numlpnumlpnuml

函数的调变量的值

&num1&num1----k8

用时,把.numi交换前:

实参指社pointe-1IInum2pnum2

变量的值&num1—।&num2----卜6

(地址),

传给了形num2pnumlpnuml

参指社变&num2nuni2变量的值&num1—6

,交换后:

者pointei26num2pnum2

是&num2/

的&num2---8

一地址单

调用函数exchange。之前、之时、结束时和结束后的情况,如图所示(见

前一页)。

形参指针变量pointerl(指向变量numl)和pointer2(指向变量num2),

在函数调用开始时才分配存储空间,函数调用结束后立即被释放。

虽然被调用函数不能改变实参指针变量的值,但可以改变它们所指向的变

量的值。

9.3数组的指针和指向数组的指针变量

9.3.1概述

1.概念

数组的指针——数组在内存中的起始地址,数组元素的指针一一数组元素

在内存中的起始地址。

2.指向数组的指针变量的定义

指向数组的指针变量的定义,与指向普通变量的指针变量的定义方法一样。

例如,intarray[10],*pointer=array(^J&array[0]);

或者:

intarray[10],"pointer;

pointer=array;

注意:数组名代表数组在内存中的起始地址(与第1个元素的地址相同),

所以可以用数组名给指针变量赋值。

3.数组元素的引用

数组元素的引用,既可用下标法,也可用指针法。使用下标法,直观;而

使用指针法,能使目标程序占用内存少、运行速度快。

9.3.2通过指针引用数组元素

如果有“inta=a,贝!J:

(1)p+i和a+i都是数组元素a[i]的地址,如图9-6(见下一页)所示。

实际地址为p+i*d,d为每个数组元素所占的字节数。

(2)*(p+i)和*(a+i)就是数组元素a[i]o实际上,在编译时,对数组元

素a[i]就是处理成*(a+i)。

(3)指向数组的指针变量,也可将其看作是数组名,因而可按下标法来使

用。例如,P[i]等价于*(p+i)。

注意:P+1指向数组的下一个元素,而不是简单地使指针变量P的值+1。其

实际变化为P+I*size(size为一个元素占用的字节数)。

例如,假设指针变量P的当前值为1000,则p+1为1000+1*4=1004,而不是

1001o如图9-6(见下一页)所ZJX

a数元素起始

59—〃•.「…...iP

刘宋:向mtaLiU」,*p=a;〃,则:

1000组地址

(1)p+i和a+i都是数组元素a[i]的地it卜力n函p+1丁_____►

所示。实际地升为D+i*d.d为每个数势阮素所a+1a[0]

占的字节数。1000

(2)*(p+i)和*(a+i)就是数组兀素a[i]实际

1T-0一〜W—士「•rj1oTE1AD+1.

八八-i________________ia[l]

上,仕绷评的,刈然组兀系aLU^GTE九埋-4-rn以H\/,.,

*fa+i)-a+i&a[i]*(P+1004

i)

(3)指向数组的指针变量,也可将其看作是数

a[2]

组名,因而可按卜标法来使用。例如,P[口等图9-6

1008

价于*(p+i)。(有条件:P-a;)等价兀素a[i]o

a[3]

D+9.a.

_____________I______>1012

+9&a[9]*(P+

9)a[i]

1016

定义字节数假设:P指向地址为1000;i二

时表示的地址为:霜

基类指针类型说明符工里d/步长3iJiX

1JLU乙U

蠹r1a1001

int*P2/41002/1004a[6]

1024

float41004

a[7]

1A9«

[案例9.5]使用指向数组的指针变量来引用数组元素。

/*案例代码文件名:AL9_5.C*/

/*程序功能:使用指向数组的指针变量来引用数组元素*/

#include<stdio.h>

main()

{intarray[10],*p=array,i;

printf("Input10numbers:");

for(i=0;i<10;i++)

scanf(“%d”,p+i);/*使用指针变量来输入数组元素的值*/

printf(“array[10]:");

for(i=0;i<10;i++)

printf(^%d”,*(p+i));/*使用指向数组的指针变量输出数组

元素的值*/

printf(“\n”);

}AL9_5.C[程序演示]

程序运行情况:

Input10numbers:0123456789-」

array[10]:0123456789

说明:

(1)指针变量的值是可以改变的,所以必须注意其当前值,否则容易出错。

(2)指向数组的指针变量,可以指向数组以后的内存单元,虽然没有实际意

义。

(3)对指向数组的指针变量(px和py)进行算术运算和关系运算的含义

1)可以进行的算术运算,只有以下几种:

px±n,px++/++px,px一/一px,px-py

•px±n:将指针从当前位置向前(+n)或回退(-n)n个数据单位,而不

是n个字节。显然,px++/++px和px--/—px是px土n的特例(n=l)。

•px-py:两指针变量的值之差,其意义是两指针之间的数据(数组元

素的)个数,而不是指针的地址之差。

思考题:

目0<ivl0,则对数组元素的错误引用是:

若有以下定义和语句,

inta[]={1,2,3,4,5,6,7,8,9,10),

int*p=a,i;

A*(a+i)Ba[p-a]Cp+iD*(&a⑴)

2)关系运算

表示两个指针所指地址之间、位置的前后关系:前者为小,后者为大。

例如,如果指针px所指地址在指针py所指地址之前,则px<py的值为1。

9.3.3再论数组名作函I数参数

数组名作形参时,接收实参数组的起始地址;作实参时,将数组的起始地

址传递给形参数组。

引入指向数组的指针变量后,数组及指向数组的指针变量作国数参数时,

可有4种等价形式(本质上是一种,即指针数据作函数参数):

(1)形参、实参都用数组名

(2)形参、实参都用指针变量

(3)形参用指针变量、实参用数组名

(4)形参用数组名、实参用指针变量

2007年4月

1、有以下程序

voidf(int*q)

{inti=0;

for(;i<5;i++)(*q)++;

)

main()

{inta[5]={l,2,3,4,5},i;

f(a);

for(i=0;i<5;i++)printf(“%d,",a[i]);

)

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

A)2,2,3,4,5,B)6,2,3,4,5,

01,2,3,4,5,D)2,3,4,5,6,

2007年4月

2、以下程序的输出结果是

intfun(int*x,intn)

{if(n==0)returnx[0];

elsereturnx[0]+fun(x+1,n-1);

10

main()

{inta[]={l,2,3,4,5,6,7);

printf(u%d\nv,fun(a,3));

2007年9月

1、若在定义语句:inta,b,c,*p=&c;之后,接着执行以下选项中的语句,则能

正确执行的语句是

A)scanf(“%d”,a,b,c);B)scanf("%d%d%d”,a,b,c);

C)scanf(“%d”,p);D)scanf("%d〃,&p);

2007年9月

2、有以下程序

#include<stdio.h>

voidfun(int*a,intn)/*函数功能是将a所指数组元素从大到小排序*/

{intt,i,j;

for(i=0;i<n-l;i++)

for(j=i+l;j<n;j++)

if(a[i]<a[j]){t=a[i];a[i]=a[j]}

main()

{intc[10]={l,2,3,4,5,6,7,8,9,0},i;

fun(c+4,6);

for(i=0;i<10;i++)printf(〃%d,〃,c[i]);printf(〃\n");

}

程序运行的结果是

A)1,2,3,4,5,6,7,8,9,0,B)0,9,8,7,6,5,1,2,3,4,

C)0,9,8,7,6,5,4,3,2,1,D)1,2,3,4,9,8,7,6,5,0,

2007年9月

3、有以下程序

#include<stdio.h>

voidfun(intn,int*p)

{intfl,f2;

if(n==l||n==2)*p=l;

else

{fun(n-l,&f1);fun(n-2,&f2);*p=fl+f2;}

}

main()

{ints;

fun(3,&s);printf(〃%d\n〃,s);

)

程序的运行结果是

A)2B)3C)4D)5

2008年4月

1、以下定义语句中正确的是

A)inta=b=0;B)charA=65+1,b='b';

C)floata=l,*b=&a,*c二&b;D)doublea=0.0;b=l.1;

2、有以下程序

#include<stdio.h>

main()

{inta[]={1,2,3,4},y,*p=&a[3];

,,,,

—p;y二*p;printf(y=%d\n5y);

}

程序运行的结果是

A)y=0B)y=lC)y=2D)y=3

2008年4月

3、有以下程序

#include<stdio.h>

voidfun(int*s,intnl,intn2)

{inti,j,t;

i=nl;j=n2;

while(i<j){t=s[i];s[i]=s[j];s[j]=t;i++;j—;}

}

main()

{inta[10]={l,2,3,4,5,6,7,8,9,0},k;

fun(a,0,3);fun(a,4,9);fun(a,0,9);

for(k=0;k<10;k++)printfa[k]);printf(〃\n〃);

}

程序运行得结果是

A)0987654321B)4321098765

C)5678901234D)0987651234

2008年4月

4、以下程序的输出结果是【35】。

#include<stdio.h>

voidswap(int*a,int*b)

{int*t;

t=a;a=b;b=t;

)

main()

{inti=3,j=5,*p=&i,*q=&j;

swap(p,q);printf(〃%d%d\n〃,*p,*q);

2008年4月

5、以下程序的输出结果是[4】。

#include<stdio.h>

main()

{inta[5]={2,4,6,8,10),*p;

P=a;p++;

printf(〃%d〃,*p);

2008年9月

1、若有定义语句:doublex[5]={L0,2.0,3.0,4.0,5.0},*p=x;则错误引用x数

组兀素的是

A)*pB)x[5]C)*(p+1)D)*x

2、以下程序的输出结果是L91

ttinclude<stdio.h>

main()

{intj,a[]={1,3,5,7,9,11,13,15),*p=a+5;

for(j=3;j;j-)

{switch(j)9911

{case1:

case2:printf(〃%d〃,*p++);break;

case3:printf(〃%d〃,*(一p));

2008年9月

3、以下程序的输出结果是【10】

#include<stdio.h>

^defineN5

intfun(int*s,inta,intn)

{intj;*s=a;j=n;

while(a!=s[j])j—;

returnj;

}

main()

{ints[N+l];intk;

for(k=l;k<=N;k++)s[k]=k+l;

printf("%d\n〃,fun(s,4,N));

2009年3月

1、若有定义语句:doublex,y,*px,*py;执行了px二&x;py=&y;之后,正确的输入语

句是

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

C)scanf(“断,px,py);D)scanf(,x,y);

2009年3月

2、有以下程序

#include<stdio.h>

voidfun(int*a,int*b)

{int*c;

c二a;a=b;b=c;

}

main()

{intx=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,3B)3,5,3,5C)5,3,3,5D)5,3,5,3

2009年3月

3、有以下程序

ttinclude<stdio.h>

voidf(int*p,int*q);

main()

{intm=l,n=2,*r=&m;

f(r,&n);printf("%d,%d〃,m,n);

)

voidf(int*p,int*q)

{p=p+l;*q=*q+I;}

程序运行后的输出结果是

A)1,3B)2,3C)l,4D)l,2

2009年3月

4、以下函数按每行8个输出数组中的数据

#include<stdio.h>

voidfun(int*w,intn)

{inti;

for(i=0;i<n;i++)

printf(〃%d〃,w[i]);

printf("\n〃);

)

下划线出应填入的语句是

A)if(i/8==0)printf(“\n");B)if(i/8==0)continue;

C)if(i%8—0)printf(〃\n〃);D)if(i%8—0)continue;

2009年3月

5、若有以下定义

intx[10],*pt=x;

则对数组元素的正确引用是

A)*&x[10]B)*(x+3)C)*(pt+10)D)pt+3

2009年3月

6、有以下程序

#include<stdio.h>

intb=2;

intfun(int*k)

{b二*k+b;return(b);)

main()

{inta[10]={1,2,3,4,5,6,7,8},i;

for(i=2;i<4;i++){b=fun(&a[i])+b;printf(,z%d",b);}

printf("\n〃);

}

程序运行后的输出结果是

A)1012B)810C)1028D)1016

2009年9月

1、有以下程序

#include<stdio.h>

main()

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

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

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

)

程序运行后的输出结果是

A)1,2,1,2B)1,2,2,1C)2,1,2,1D)2,1,1,2

9.3.42维数组的指针及其指针变量

1.2维数组的指针

假设有如下数组定义语句:

inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

(1)从2维数组角度看,数组名a代表数组的起始地址,是一个以行为单位进行控

制的行指针:

a+i:行指针值,指向2维数组的第i行。

*(a+i):等价于a[i],(列)指针值,指向第i行第0列(控制由行转为列,但仍

为指针)。

*(*(a+i)):数组元素a[i][0]的值。

用a作指针访问数组元素a[i][j]的格式:

*(*(a+i)+j)

注意:行指针是一个2级指针,如图所示。

(2)从1维数组角度看,数组名a和第1维下标的每一个值,共同构成一组新的1维

数组名a[0]、a[l]、a[2],它们均由4个元素组成。

a[0]

a[0]+l

a[0]+3

1

a

r、r

2000a[0]—1357

a+1

2016'

a[l]—9111315

a+2

2032'a[2]17192123

=

a2000*(a[l]+2),*(*(a+l)+2)13

a[0L*(a+0)产a2000**a1

a+L&a[l]2016**(a+l)9

a[l].*(a+l)间l]+02016

a[l]+2.*(a+l)+2.&a[l][2]2024

C语言规定:数组名代表数组的地址,所以a[i]是第i行1维数组的地址,它

指向该行的第。列元素,是一个以数组元素为单位进行控制的列指针:

a[i]+j:(列)指针值,指向数组元素

*(a[i]+j):数组元素的值。

如果有“inta[3][4],*p=a[0];,则p+1指向下一个元素,如图所示。

用P作指针访问数组元素a[i]仃]的格式:*(p+(i*每行列数+j))

2.行指针变量—指向由n个元素组成的一维数组的指针变量

(1)定义格式

数据类型(*指针变量)M;

注意:“*指针变量”外的括号不能缺,否则成了指针数组一一数组的每个元

素都是一个指针一一指针数组(本章第6节介绍)。

(2)赋值

行指针变量=2维数组名|行指针变量;

[案例9.6]使用行指针和列指针两种方式输出2维数组的任一元素。

(1)使用行指针

/*案例代码文件名:AL9_6」.C*/

/*程序功能:使用行指针输出2维数组的任一元素*/

main()

{inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12});

int("pointer)[4],row,col;

pointer=a;

printf(aInputrow=");scanf("%d“,&row);

printf("Inputcol二");scanf(,&col);

printf(^a[%ld][%ld]=%d\nw,row,col,*(*(pointer+row)+col));}

程序运行情况:

Inputrow=1—」

Inputcol-2*-1

array[1][2]=7

思考题:本题也可以直接使用数组名a作指针,应如何修改?

(2)使用列指针

/*案例代码文件名:AL9_6_2.C*/

/*程序功能:使用列指针输出2维数组的任一元素*/

main()

{inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12});

int"pointer,row,col;/*定义一个(歹U)指针变量pointer*/

pointer=a[0];/*给(列)指针变量pointer赋值*/

printf("Inputrow二");scanf("%d”,&row);

printf(Inputcol二”);scanf(“%d“,&col);

printf(aa[%ld][%ld]=%d\n",row,col,*(pointer+(row*4+col)));

}[程序演示]

3.2维数组指针作函数参数

一维数组的地址可以作为函数参数传递,多维数组的地址也可以作为函数参数

传递。在用指针变量作形参以接受实参数组名传递来的地址时,有两种方法:①用

指向变量的指针变量②用指向一维数组的指针变量。

2008年9月

1、有以下程序

ttinclude<stdio.h>

intfun(int(*s)[4],intn,intk)

{intm,i;m=s[0][k];

for(i=l;i<n;i++)

if(s[i][k]>m)m=s[i][k];

returnm;

main()

{inta[4][4]={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34});

,,,,

printf(%d\nJfun(a,4,0));

)

程序的运行结果是

A)4B)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论