7 指针Word文档下载推荐.docx
- 文档编号:20589426
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:17
- 大小:21.85KB
7 指针Word文档下载推荐.docx
《7 指针Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《7 指针Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
\na=%d,b=%d\n"
a,b);
max=%d,min=%d\n"
5,9
a=5,b=9
max=9,min=5
五、指针变量作为函数参数
函数的参数不仅可以是整形,实型、字符型等数据,还可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。
{inta=1,b=2;
swap(&
1:
a=%d,b=%d\n"
swap(int*p,int*q)
{intc;
c=*p;
*p=*q;
*q=c;
2:
*p,*q);
六、数组的指针和指向数组的指针变量
一个变量有地址,一个数组元素也有相应的地址。
当然也可以把数组起始地址或某一元素的地址放到一个指针
变量中。
所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。
引用数组元素可以用下标法(如a[3]),也可以用指针法,即通过指向数组元素的指针找到所需的元素。
使用指针法能使目标程序质量高。
1、指向数组元素的指针变量的定义与赋值
inta[10];
int*p=a;
它的作用是将a的首地址付给指针变量p。
int*p;
p=a;
(p=&
a[0])
2、通过指针引用数组元素
假设p已定义为指针变量,并已给它赋了一个地址,使他指向某一个数组元素。
如果有以下赋值语句:
*p=1;
(表示对p当前所指向的数组元素赋以一个值,值为1)
C规定p+1指向数组的下一个元素(而不是将p值简单加1)。
例如,数组元素是实型,每个元素占4个字节,
则p+1意味着p的原值加4个字节,以使它指向下一元素。
注意点:
****
如果p的初值为&
a[0],则:
(1)p+i和a+i就是a[i]的地址,或者说,它们指向a数组的第i个元素。
(2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i].
(3)指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价。
(4)当指针指向一串连续的存储单元时,可以对指针进行加上或减去一个整数,这种操作称为指针的移动。
例如,p++,p--,都可以使指针移动。
(5)指针不允许进行乘、除运算,移动指针时,不允许加上或减去一个非整数,对指向同一串连续存储单元的
两个指针只能进行相减操作。
例题:
1.从键盘输入10个整数,存放在数组中,并输出数组的全部元素。
用指针变量指向数组元素。
{inti,a[10],*p;
for(i=0;
i<
10;
i++)
%d"
a[i]);
for(p=a;
p<
a+10;
p++)
%4d"
*p);
\n"
);
2.输出a数组的10个元素。
p=a;
p++);
i++,p++)
1234567890
22153234003003625202116318259823728483
3.数组名作函数参数
数组名可以用作函数的实参传给形参。
由于数组名是一个地址值,对应的形参就应该是数组名或一个指针变量,但该指针必须与数组类型一致。
1.有一个一维数组score,内放10个学生成绩,求平均成绩。
floataverage(float*array)
{inti;
floataver,sum=0;
sum=sum+array[i];
aver=sum/10;
return(aver);
{floatscore[10],ave;
inti;
Input10scores:
%f"
score[i]);
ave=average(score);
Averagescoreis%5.2f"
ave);
2.定义长度为10的整形类型一维数组,并将数组中的元素按逆序存放后输出其值。
{inti,a[10];
a[i]);
fun(a,10);
fun(int*p,intn)
{inti,j,t;
for(i=0,j=n-1;
j;
i++,j--)
{t=p[i];
p[i]=p[j];
p[j]=t;
3.已知一维数组中存放互不相同的10个整数,从键盘输入一个数,并从数组中删除与该值相同的元素中的值。
{inti,t,a[10]={2,4,1,6,5,9,7,0,8,3};
i++)printf("
\nInputt:
t);
del(a,t);
9;
del(inta[10],intt)
{inti,j;
i++)if(t==a[i])break;
for(j=i;
j<
j++)a[j]=a[j+1];
4.用选择法对10个整数按由小到大顺序排序。
i++)scanf("
sort(a,10);
sort(intp[],intn)
{inti,j,k,temp;
n-1;
{k=i;
for(j=k+1;
n;
j++)
if(p[j]<
p[k])k=j;
temp=p[i];
p[i]=p[k];
p[k]=temp;
}
5.假定a数组中已存放由小到大顺序排好序的10个数,在a数组中插入一个数,插入后数组中的数任有序。
main()
{inti,x,a[11]={1,3,5,7,9,11,13,15,17,19};
Inputx:
x);
insert(a,x);
11;
insert(int*a,intx)
i=0;
while(i<
10&
&
a[i]<
x)i++;
for(j=9;
j>
=i;
j--)a[j+1]=a[j];
a[i]=x;
6.求一维数组中值最大的那个元素的值,以及其所在的位置。
{inti,k,max;
inta[10]={3,4,9,1,7,6,-10,10,-5,2};
max=find(a,&
k);
max=%d,k=%d\n"
max,k);
find(inta[10],int*k)
{inti,max;
max=a[0];
*k=0;
if(max<
a[i]){max=a[i];
*k=i;
returnmax;
4.指向多维数组的指针和指针变量
设已定义二维数组a:
inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
应清楚:
(1)a是二维数组名,是二维数组的起始地址。
也可以说a指向a数组的第0行,a也是0行的首地址。
(2)a+1是a数组第1行首地址,或者说a+1指向第1行
(3)a[0],a[1],a[2]是二维数组中三个一维数组的名字,因此他们也是地址(分别是0行,1行,2行的首地址)
。
务必不要把他们错认为是整形数组元素。
(4)a[i]+j是i行j列元素的地址。
*(a[i]+j)是i行j列元素的值。
如a[0]+2和*(a[0]+2)分别是0行2列元素的
地址和元素的值。
(5)a[i]与*(a+i)无条件等价。
这两种写法可以互换。
如a[2]和*(a+2)都是2行首地址,即2行0列元素的地址,即&
a[2][0].
(6)a[i][j],*(a[i]+j),*(*(a+i)+j)都是i行j列元素的值。
(7)区别行指针和列指针的概念。
例如a+1和a[1]都代表地址。
但a+1是行指针,它指向一个一维数组。
a[1](即*(a+1))是列指针,
它指向一个元素,它是1行0列元素的地址。
(8)可以定义指向一维数组的指针变量,如
int(*p)[4];
定义p为指向一个含4个元素的一维数组的指针变量。
四、字符串的指针和指向字符串的指针变量
1.字符串的表示形式
(1)用字符数组实现
{charstring[]="
IloveChina!
"
;
%s\n"
string);
(2)用字符指针实现
可以不定义字符数组,而定义一个字符指针,用字符指针指向字符串中的字符。
{char*string="
将字符串a复制到字符串b(用指针变量来处理)
{chara[]="
Iamaboy."
b[20],*p1,*p2;
inti;
for(p1=a,p2=b;
*p1!
='
\0'
p1++,p2++)
*p2=*p1;
*p2='
printf("
Stringais:
a);
Stringbis:
b);
2.字符指针变量和字符数组
虽然用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的:
(1)字符数组由若干个元素组成,每个元素中存放一个字符,而字符指针变量中存放的是地址,决不是将
字符串放到字符指针变量中。
(2)对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值.
charstr[14];
str="
IloveChina"
/*str是数组名,是常量,不能再被赋值*/
而对字符指针变量,可以采用下面方法赋值:
char*a;
a="
(3)对字符指针变量赋初值时:
char*a="
等价于char*a;
a="
而对数组初始化时:
charstr[14]={"
};
不等价于charstr[14];
str[]="
即数组可以在变量定义时整体赋初值,但不能再赋值语句中整体赋值。
(4)在定义一个数组时,在编译时即已分配内存单元,有固定的地址。
而定义一个字符指针变量时,
给指针变量分配内存单元,在其中可以存放一个地址值,也就是说,该指针变量可以指向一个字符型
数据,但如果未对它赋以一个地址值,则它并未具体指向哪一个字符数据。
如:
charstr[10];
scanf("
%s"
str);
是可以的,而常有人用下面的形式:
char*a;
编译时虽然给指针变量a分配一个存储单元,a的地址是已指定了,但a中的值并未确定,在a单元中是一个
不可预料的值,可能破坏内存中的有用数据,因此会导致严重的后果,所以要先使a有确定值,然后才能
把一个字符串输入给以a中值为首地址的连续内存中。
(5)指针变量的值是可以改变的。
(6)用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。
char*format;
format="
a=%d,b=%f\n"
printf(format,a,b);
它相当于:
3.字符串指针作函数参数
将一个字符串从一个函数传递到另一个函数,可以用地址传递的方法,即用字符数组名或用指向字符串的
指针变量作参数。
1、将字符数组中的字符串按逆序存放后输出。
#include<
stdio.h>
string.h>
charch[80];
gets(ch);
puts(ch);
j=strlen(ch)-1;
fun(ch,j);
puts(ch);
fun(char*p,intj)
chart,*q;
q=p+j;
for(;
q;
p++,q--)
{t=*p;
*q=t;
2.从键盘输入一个字符串,计算该字符串的长度。
不要用strlen函数。
{intlen;
chara[80];
gets(a);
puts(a);
len=lenth(a);
%d\n"
len);
lenth(char*p)
{char*q=p;
while(*q!
)q++;
returnq-p;
3.编一程序,将两个字符串连接起来。
不要用strcat函数。
{chars1[80],s2[40];
\nInputstring1:
gets(s1);
\nInputstring2:
gets(s2);
scat(s1,s2);
\nNewstring:
s1);
scat(char*s1,char*s2)
{while(*s1!
)s1++;
while(*s2!
){*s1=*s2;
s1++;
s2++;
*s1='
五、函数的指针和指向函数的指针变量
1、用函数指针变量调用函数
可以用指针变量指向整形变量、字符串、数组,也可以指向一个函数。
一个函数在编译时被分配给一个
入口地址。
这个入口地址就称为函数的指针。
可以用一个指针变量指向函数,然后通过该指针变量调用此函数。
{intmax(int,int);
int(*p)(int,int);
inta,b,c;
p=max;
c=(*p)(a,b);
max=%d\n"
c);
intmax(intx,inty)
{intz;
if(x>
y)z=x;
elsez=y;
return(z);
(1)指向函数的指针变量的一般定义形式为:
数据类型标识符(*指针变量名)(类型参数1,类型参数2)
(2)函数的调用可以通过函数名调用,也可以通过函数指针调用。
(3)(*p)(int,int)表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的,而只是
表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。
(4)在个函数指针变量赋值是,只需给出函数名而不必给出参数。
(5)用函数指针变量调用函数时,只需将(*p)代替函数名即可。
(6)对指向函数的指针变量,像p+n,p++,p--等运算是无意义的。
(7)函数指针变量常用的用途之一是把指针作为参数传递到其他函数。
六、指针数组和指向指针的指针
1.指针数组的概念
一个数组,其元素均为指针类型数据,称为指针数组。
也就是说,指针数组中的每一个元素都是指针变量,
指针数组的定义形式为:
类型标识符*数组名[数组长度说明]
例如:
int*p[4];
2.指向指针的指针
指针变量也有地址,这地址可以存放在另一个指针变量中。
如果变量p中存放了指针变量q的地址,那么p
就指向指针变量q。
指向指针数据的指针变量,简称为指向指针的指针。
char**p;
3.main函数的命令行参数
main(intargc,char**argv)
argc和argv是main函数的形参。
argc是指命令行中参数的个数,argv是指向字符指针数组的指针,它指向的
指针数组的每一元素都指向一个字符串。
习题
一、选择题
1.指针变量a所指的字符串长度为
\nMyNameisZhangLi.\"
A.26B.27C.28D.23
2.在C语言中,变量的指针是指该变量的
A.值B.名C.地址D.一个标志
3.已设p1和p2为指针变量,且已指向一个整形数组中的元素,a是一个整形变量,以下不能正确执行的语句是
A.a=*p1
B.a=*p1+*p2
C.a=p1-p2
D.p1=a-p2
4.下面程序段的运行结果是
char*s="
abcde"
s+=2;
s);
A.cde
B.无确定的输出结果
C.字符‘c’的ASCII码值
D.存放字符‘c’的存储单元的地址
5.若有定义:
int*p[4];
则标识符p
A.是一个指向整形变量的指针
B.是一个指针数组名
C.是一个指针,它指向一个含有四个整形元素的一维数组
D.说明不合法
6.有一个二维数组a[3][4],2行3列元素的正确表示方法为
A.&
a[2][3]
B.a[2]+3
C.*(a+2)+3
D.*(a[2]+3)
7.若有以下说明语句
char*language[]={"
FORTRAN"
"
BASIC"
PASCAL"
JAVA"
C"
则表达式:
*language[1]>
*language[3]
比较的是
A.字符B和字符J
B.字符串BASIC和字符串JAVA
C.字符串FORTRAN和字符串PASCAL
D.字符F和字符P
8.指向一个包含4个整形元素的一维数组的指针变量的定义形式为
A.int(*p)[4]
B.int*p[4]
C.int(p[4])
D.int(p)[]
9.以下正确的叙述是
A.C语言允许main函数带形参,但形参个数和形参名均可由用户指定
B.C语言允许main函数带形参,形参名只能是argc和argv
C.当main函数带有形参时,传给形参的值从命令行中得到
D.若有说明main(intargc,char*argv),则形参argc的值必须大于1
10.有以下程序片段,对一个字符串的不正确引用是
chara[4][12]={"
china"
Japan"
Franch"
England"
},*p[4];
for(i=0;
4;
i++)p[i]=a[i];
A.a[i]B.p[i]C.*pD.p
二、填空题
1.以下程序的运行结果是
fun(int*p1,int*p2)
{if(*p1>
*p2)
*p1);
elseprintf("
*p2);
{inta=3,b=7;
fun(&
2.若有定义,inta[3][5],i,j;
且0<
=i<
3,0<
=j<
5,则a[i][j]的地址可用五种形式表示。
他们是
(1)&
a[i][j]
(2)a[i]+j
(3)*(a+i)+j
(4)&
a[0][0]+
(5)a[0]+
3.以下程序的运行结果是
{char*s[]={"
China"
char**p;
p=s+2;
4.以下程序在屏幕上将输出的信息是
设程序的文件名为“c8.c”
main(intargc,char*argv[])
{whilea(argc>
1)
{++argv;
*argv);
--argc;
5.若有以下定义和语句:
ints[2][3]={0},(*p)[3];
p=s;
则p+1表示数组
6.以下程序段运行结果是
charstr[]="
abc\0def\0ghi"
*p=str;
p+5);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 指针