第九讲 指 针Word下载.docx
- 文档编号:21937939
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:26
- 大小:53.79KB
第九讲 指 针Word下载.docx
《第九讲 指 针Word下载.docx》由会员分享,可在线阅读,更多相关《第九讲 指 针Word下载.docx(26页珍藏版)》请在冰豆网上搜索。
{inta,b;
int*pa,*pb;
a=100;
b=10;
pa=&
a;
pb=&
b;
printf(“%d,%d\n”,a,b);
printf(“%d,%d\n”,*pa,*pb);
}
对*及&
的说明:
(同级运算,由右向左)
例:
将两个整型数a,b按由大到小次序输出。
main()
{int*p1,*p2,*p,a,b;
scanf(“%d,%d”,&
a,&
b);
p1=&
p2=&
if(a<
b)
{p=p1;
p1=p2;
p2=p;
}
printf(“a=%d,b=%d\n”,a,b);
printf(“larger=%d,little=%d\n”,*p1,*p2);
运行情况:
5,9
a=5,b=9
larger=9,little=5
a和b并未交换,但p1和p2的值交换了
9.2.3指针变量作函数参数
将一个变量的地址传至另外一个函数中。
swap(p1,p2)
int*p1,*p2;
{intp;
p=*p1;
*p1=*p2;
*p2=p;
交换指针所指向的变量值
{inta,b;
b)swap(pa,pb);
}
5,9
9,5
函数调用过程如下图所示:
开始调用swap函数,实参pa、pb分别向形式参数p1、p2传递数据
执行函数语句,p1、p2所指向的变量的值相互交换
函数调用结束后,p1、p2所占用的内存单元被释放,
·
单向传递,值传递问题
swap(x,y)
intx,y;
{intt;
t=x;
x=y;
y=t;
b)swap(a,b);
形参值的改变无法传递给实参
改变指针形参的值,也不能使指针实参的值改变
{int*p;
p=p1;
p1=p2;
p2=p;
C语言中,实参和形参间的数据是单向值传递方式。
指针做函数参数也遵循该原则
int*pa,*pb;
scanf(“%d,%d”,&
printf(“%d,%d\n”,*pa,*pb);
如输入数据为:
结果为:
9.3数组的指针和指向数组的
数组的指针:
数组的起始地址。
数组元素的指针:
数组元素的地址。
数组名可视为地址常量。
9.3.1指向数组元素的指针变量的定义与赋值
inta[10];
int*pa;
pa=a;
(或pa=&
a[0])
表明指针pa指向数组a的首地址;
此时,指针对象*pa为a[0];
pa+n表示数组第n个数据的地址
即pa+n=&
a[n]
*(pa+n)是a[n]
9.3.2通过指针引用数组元素
引用数组中的元素可以用以下方法:
下标法如a[3]
指针法即通过指向数组元素的指针找到所需的元素.这种方法占内存少,运行速度快,因此说程序的质量高.
假设p已定义为指针变量,并已赋了一个地址,它指向某一个
数组元素.且有赋值语句p=&
a[0];
则:
•p+1表示数组中的下一个元素,
•a+i和p+i都是a[i]的地址,或者说它们指向a[i].
•*(a+i)或*(p+i)是a+i或p+i所指向的数组元素。
•指向数组的指针变量也可带有下标,如p[i]与*(p+i)等价。
输出数组全部元素
•下标法:
{inta[10],i;
for(i=0;
i<
10;
i++)
scanf(“%d”,&
a[i]);
printf(“\n”);
printf(“%5d”,a[i]);
•通过数组名计算数组元素地址,找出数组元素
for(i=0;
printf(“%5d”,*(a+i));
•用指针变量指向数组元素
for(p=a;
p<
(a+10);
p++)
printf(“%5d”,*p);
用指针处理数据。
#include“stdio.h”
{inta[10],*pa,i;
for(i=0;
a[i]=i+1;
i++,pa++)
printf(“%d”,*pa);
printf(“\n”);
给定10个整数,求最大值。
#defineN10
{inta[N]={5,7,3,6,2,1,8,9,4,0};
inti,*p,max;
p=a;
max=*p++;
for(i=1;
i<
N;
i++,p++)
if(*p>
max)max=*p;
printf(“max=%d\n“,max);
9.3.3数组名作为函数参数
当用数组名作为参数时,如果形参数组中个元素的值发生
变化,实参数组元素的值也随之变化,为什么?
若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况:
•形参与实参都用数组名
•实参用数组名,形参用指针变量
•实参形参均用指针变量
•实参为指针变量,形参为数组名
用选择法对10个整数排序
{int*p,i,a[10];
voidsort();
p=a;
scanf(“%d”,p++);
sort(p,10);
for(p=a,i=0;
10;
printf(“%d”,*p++);
voidsort(x,n)
intx[],n;
{inti,j,t;
n-1;
{for(j=i+1;
j<
n;
j++)
if(x[i]>
x[j])
{t=x[i];
x[i]=x[j];
x[j]=t;
}
9.3.4指向多维数组的指针和指针变量
一、多维数组的地址
假设数组名为a,起始地址设为200
Statica[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
则:
•a代表整个二维数组的首地址,即第0行的首地址
•a+1是数组a第1行首地址(208)
•a[0],a[1],a[2]是二维数组中三个一维数组的名字(地址),是第0行,第1行,第2行的首地址,即:
a[0]=a+0、a[1]=a+1、a[2]=a+2
•a[i]+j是第i行j列的地址
•*(a[i]+j)是该地址存储的值,
即a[i][j]
考虑*(a[2]+3)=?
•a[i]和*(a+i)无条件等价
•a+i、a[i]、*(a+i)、&
a[i][0]均表示第i行首地址;
•&
a[i][j]、a[i]+j、*(a+i)+j都是第i行j列元素的地址;
•a[i][j]、*(a[i]+j)、*(*(a+i)+j)都是第i行j列元素的值;
二、指向数组的指针变量
定义格式:
类型说明符(*变量名)[常量表达式]
功能:
定义一个名为“变量名”的指针变量,这个指针变量所指的对象是一个有“常量表达式”个元素的一维数组
若有int(*pa)[4];
被定义成一个指针变量,它所指对象是一个有4个整型元素的数组
输出二维数组任一行任一列元素的值
{inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
int(*p)[4],i,j;
scanf(“%d%d”,&
i,&
j);
printf(“a[%d][%d]=%d\n”,i,j,*(*(p+i)+j));
有一个班,3个学生,各学4门课,计算总平均分,以及第n个学生的成绩
voidaverage(p,n)
float*p;
intn;
{floatsum=0,aver;
for(;
p+n;
sum=sum+(*p);
aver=sum/n;
printf(“average=%6.2f\n”,aver);
voidsearch(p,n)
float(*p)[4];
{inti;
printf(“thescoreofNo.%dare:
\n”,n);
4;
printf(“%6.2f“,*(*(p+n)+i));
{floatscore[3][4]={{65,67,70,80},{80,90,78,91},
{70,79,75,89}};
average(score,12);
search(score,2);
9.4字符串的指针和指向字符串的指针变量
9.4.1字符串的表示形式
1用字符数组表示,如:
mian()
{staticcharstring[]=“IloveChina!
”;
printf(“%s\n”,string);
2用字符指针实现,如:
{char*string=“IloveChina!
运行结果:
IloveChina!
请编写函数intfun(char*str),它的功能是判别字符串str是否是"
回文"
若是,返回1,否则返回0.
例如,“13531”,“helleh”是回文,但“1353”,“Helleh”不是回文.
#include"
stdio.h"
intflag=0;
intfun(char*str)
{intn=0,k;
char*p1=str;
flag=0;
while(*p1){n++;
p1++;
for(k=0;
k<
n/2;
k++)
if(*(str+k)==*(str+n-k)flag=1;
returnflag;
voidmain()
{chars[128];
printf("
\nPleadeenterstring:
\n"
);
gets(s);
fun(s);
字符指针使用中的几点事项:
1.要注意一些常用的符号。
如串的结束符是‘\0’
它的数值为0;
回车符的数值为13;
换行符
的值为10;
文件结束符的数值为27;
2.字符指针常用于文件操作。
3.前面讲过的指针使用中要注意的问题同样适用于字符指针。
字符指针变量与字符数组的比较:
字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址。
赋值方式:
对数组的赋值方法有:
charstr[]=“Iamaboy!
”
或:
charstr[20];
scanf(“%s”,str);
对字符指针变量的赋值方法有三种:
(1)char*pa=“Iamaboy!
(2)
(2)char*pa;
pa=“Iamaboy!
(3)char*pa,str[20];
pa=str;
scanf(“%s”,pa);
9.5函数的指针和指向函数的指针变量
9.5.1用函数指针变量调用函数
可以用指针变量指向一个函数。
一个函数在编译时被分配一个入口地址,这个入口地址称为函数的指针。
求a和b中的大者。
main()
{intmax();
int(*p)();
inta,b,c;
p=max;
scanf(%d,%d”,&
c=(*p)(a,b);
printf(“a=%d,b=%d,max=%d”,a,b,c);
说明:
1.指向函数的指针变量的一般定义形式是:
数据类型标识符(*指针变量名)();
2.函数的调用可以通过函数名调用,也可以通过函数指针调用;
3.在一个程序中,一个指针变量可以先后指向不同的函数;
例如:
intmax();
intmin();
c=(*p)(a,b);
·
p=min;
4.在给函数指针变量赋值时,只需给出函数名而不必给出参数;
5.用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名),(*p)后的括号中应加相应实参。
9.5.2把指向函数的指针变量作函数参数
指向函数的指针变量可以也作为参数,以便实现函数地址的传递,即将函数名传给形参。
9.6返回指针值的函数
即可带回指针值的函数,其一般定义形式为:
类型标识符*函数名(参数表);
如int*a(x,y);
有若干学生的成绩(每人四门),要求输入序号后,能输出该生全部成绩。
{floatscore[][4]={{60,70,80,90},{57,89,46,78},{43,90,87,67}};
float*search();
float*p;
inti,m;
printf(“enterthenumberofstudent:
”);
m);
printf(“ThescoresofNo.%dare:
\n”,m);
p=search(score,m);
i++)printf(“%5.2f\t”,*(p+i));
float*search(pointer,n)
float(*pointer)[4];
intn;
{float*pt;
pt=*(pointer+n);
return(pt);
enterthenumberofstudent:
1
ThescoresofNo.1are:
57.00,89.00,46.00,78.00
9.7指针数组和指向指针的指针
9.7.1指针数组
指针数组:
由相同类型的指针变量排列而成的有序集合(每个元素都是指针变量)。
说明格式:
类型说明符*指针数组名[元素个数]
如int*p[5]注意与int(*p)[5]不同
一般用于指向若干个字符串,使字符处理更方便。
{char*s[4]={“dog”,“cat”,“pig”,“allanimal”};
inti;
for(i=0;
i<
i++)
printf(“%s\n”,*(s+i));
9.7.2指向指针的指针(二级指针)
指向指针的指针:
指向指针数据的指针变量。
通常用于指向字符型指针变量。
说明格式:
类型说明符**指针变量名
char**p;
其含义是定义指针变量p,用于存储另一个指针变量的地址。
mian()
{char*s[]={“China”,“Japan”,“English”,”Franch”};
char**p;
p=s+2;
/*p=*(s+2)=s[2]存放的是English的首地址*/
printf(“%s\n”,p);
/*打印p指针内的内容,即指针指向的字符串*/
9.7.3main()函数的命令行参数
通常,main函数首行为main(),其实可带参数,如:
main(argc,argv)
intargc;
char*argv[];
{………
main函数的实参是和命令一同给出的,即在一个命令行中包括命令名和需要传给main函数的参数
命令行的一般形式为:
命令名参数1参数2…...参数n
假设目标文件名为“F”,需向函数传递的参数为字符串“X”和“Y”,则命令行可写为:
FXY
命令行及命令行参数提供了C程序与操作系统间的接口
若有一个函数,其所在文件名为“F”:
main(argc,argv)
char*argv[];
{while(argc>
1)
{++argv;
printf(“%s\n”,*argv);
--argc;
若输入的命令行参数为
FABCDEF
则执行结果为
ABC
DEF
9.8有关指针的数据类型和指针运算小节
(一)有关指针的数据类型
……….定义整型变量i;
int*p;
……..p为指向整型数据的指针变量;
inta[n];
……定义整型数组a,它有n个元素;
int*p[n];
…..定义指针数组p,它由n个指向整型数据指针元素组成;
int(*p)[n];
…定义指向含n个元素的一维数组的指针变量p;
intf();
……..f为带回整型函数值的函数;
int*p();
…p为带回一个指针的函数,该指针指向整型数据;
….p为指向函数的指针,该函数返回一个整型值;
int**p;
…….p是一个指针变量,它指向一个指向整型数据的指针变量。
(二)指针运算小结
1.赋值=
语法:
指针变量=指针表达式
若有变量定义:
int*p1,*p2,a,array[10];
p1=&
………….变量的地址。
’
p2=array;
…………数组的首地址。
array[i];
…….数组第i个元素的地址。
…………..一个指针变量值赋给另一个指针变量。
2.取地址运算&
语法:
变量
设有变量说明inta,b,*p,*q;
p=&
把a的地址赋给p,即让p指向a
q=p;
让q也指向a,现在p、q都指向a
让p也指向b,现在q指向a,p指向b
其中&
a表示a的地址值
3.取内容运算*
语法:
*指针表达式
设p是一个指针表达式,则:
(1)若*p出现在赋值号左边,表示给p所指变量赋值
(2)若*p不出现在赋值号左边,表示p所指变量的值
若有变量说明:
inta,*p;
则:
p=&
让p指向变量a
*p=10;
*p出现在赋值号左边,等价于a=10
printf(“%d”,*p);
*p不出现在赋值号左边,打印p所指变量的值
scanf(“%d”,&
a);
给变量a输入值
scanf(“%d”,p);
同上
*p+25等价于a+25
4.指针表达式与整数相加减
形式:
p+n或p-n
其中:
p是任意一个指针表达式,n是任何一种整型表达式
计算规则:
表达式p+n的值=p的值+p所指类型长度*n
表达式p-n的值=p的值-p所指类型长度*n
只有当p和p+n或p-n都指向连续存放的同类型数据区域,例如数组时,指针加减才有实际意义。
C语言规定:
表达式p+n和p-n的类型与p相同。
设有变量定义:
inta[10],*p,*q;
则
p=ap指向a[0]
q=a+6q指向a[6]
p=q-4p指向a[2]
5.自增自减运算
p++;
p--;
++p;
--p;
inta[]={1,2,3,4,5},*p,*q;
p=q=&
a[3];
*p++=100;
a[?
]变成100
*++q=100;
p++与++p的区别:
表达式p++的值等于p的原来值;
表达式++p的值等于p的新值;
6.关系运算
只有同类指针进行比较才有意义
==和!
=运算符,比较的是两个指针表达式是否指向同一个内存单元;
<
、<
=、>
、>
=,比较的是两个指针所指内存区域的先后次序
指针表达式关系运算符指针表达式
int*p=a,*q=a+3;
试判断以下表达式的值
p==&
a[0]p==&
a[1]p==qp+4=q+2p<
a+5
q>
a+2p>
q
可用以下语句给数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第九讲 第九