版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C程序设计中使用指针可以:
使程序简洁、紧凑、高效有效地表示复杂的数据结构动态分配内存第6章指针2023/6/416.1指针和变量在计算机中,内存中的每一个字节的内存单元都有一个编号,这个编号就是“地址”,对于有多个字节的变量,第一个字节的地址就是该变量的地址。如果有:shortintx=5;设系统为x分配的地址为2000,则:
x20005p
20022000注意:区分变量的地址和变量的值2023/6/42变量的指针:就是变量的地址。指针变量:存放变量地址的变量。定义指针变量的一般形式为:基类型*变量名;其中基类型用来指定该指针变量所指向的变量的类型。例如:
float*p;/*定义p为指向实型变量的指针*/
int
*q;/*定义q为指向整形变量的指针*/char*s;/*定义s为指向字符型变量的指针*/2023/6/43charx=‘A’;char*p;p=&x;注意:指针变量只能存放具有基本类型的变量的地址。4000pAxA4000H4001H2023/6/44与指针相关的运算符:⑴
&:取地址运算符,其作用是求变量的地址。取地址运算符具有右结合性,其优先级和自加运算符相同2。⑵*:指针运算符,或称“间接访问”运算符。指针运算符也具有右结合性,优先级为2。2023/6/45【例1】
main(){inta=3;
int*p;p=&a;
printf(“a=%d,*p=%d”,a,*p);
printf(“*&a=%d”,*&a);
printf(“*&*p=%d”,*&*p);}
2023/6/46【例2】用指针的方法交换两个数
main(){intx=102,y=12,t;
int*p1,*p2; p1=&x; p2=&y;
printf(“x=%d,y=%d”,x,y); t=*p1; *p1=*p2; *p2=t;
printf(“x=%d,y=%d”,x,y);}
2023/6/47例main(){inti=10;
int*p;*p=i;
printf("%d",*p);}例
main(){inti=10,k;
int*p;
p=&k;*p=i;
printf("%d",*p);}指针变量必须先赋值,再使用错误正确2023/6/486.2指针与数组6.2.1指向数组的指针1.一维数组的指针例如:inta[10],*p;p=&a[0];
a是数组名,代表一维数组的首地址。
*(a+i)=a[i]p=a;*(p+i)=p[i]=a[i]2023/6/49a[0]a[9]pa【例3】用指针法输出数组元素。main(){inta[10],i,*p;for(i=0;i<10;i++)
scanf("%d",a+i);for(i=0;i<10;i++)printf("%4d",*(a+i));
printf("\n");for(p=a,i=0;i<10;i++)printf("%4d",*(p+i));
printf("\n");}1.一维数组的指针
12345677910
12345677910123456779102023/6/410a[0]a[9]pa【例3】用指针法输出数组元素。main(){inta[10],i,*p;for(p=a;p<a+10;p++)
scanf("%d",p);for(p=a;p<a+10;p++)
printf("%d",*p);
printf("\n");
}1.一维数组的指针
123456789102023/6/411数组名和指向数组的指针变量的区别:指针变量p是变量可以赋值,数组名a是地址常量不能赋值。用指针变量引用数组元素,
必须关注其当前值。例如:
p=p+3*(p-1)等价于a[2]a[0]a[9]pa123456779102023/6/412【例4】用指针法求字符串的长度main(){chars[30],*p;
intn=0;
gets(s);p=s;while(*p!=‘\0’){p++;n++;}
printf(“%d”,n);}ss[0]s[9]s[1]......china
go
On\0s[10]s[11]p2023/6/41301020111212122231323a⑴二维数组的地址例如:inta[3][4];
①二维数组名a是数组的首地址。②二维数组a包含三个行元素:a[0]、a[1]、a[2]
。三个行元素的地址分别是:a、a+1、a+2。而a[0]、a[1]、a[2]也是地址量,是一维数组名,即*(a+0)、*(a+1)、*(a+2)是一维数组首个元素地址。2.二维数组的指针
a[0]a[1]a[2]aa+1a+22023/6/414⑵二维数组元素的地址
a[0]、a[1]、a[2]是一维数组名,所以a[i]+j是数组元素的地址。数组元素a[i][j]的地址可以表示为下列形式:&a[i][j]、a[i]+j
、*(a+i)+ja[0]数组a[1]数组a[2]数组2.二维数组的指针01020111212122231323a[2]+1a[2]+2a[2]+3a[0]+1a[0]+2a[0]+3⑶数组元素可用下列形式表示:
a[i][j]、*(a[i]+j)、*(*(a+i)+j)2023/6/415(4)指向一维数组的指针变量指向一维数组指针变量的定义形式:
数据类型标识符(*变量名)[元素个数]2.二维数组的指针
“*”表示其后的变量名为指针类型,[元素个数]表示目标变量是一维数组,并说明一维数组元素的个数。由于“*”比“[]”的运算级别低,“*变量名”作为一个说明部分,两边必须加括号。“数据类型标识符”是定义一维数组元素的类型。2023/6/416【例5】用指向一维数组的指针变量输出数组元素。main(){inta[3][4]={{0,1,2,3},{10,11,12,13},{20,21,22,23}};
int(*lp)[4],i,j;for(lp=a,i=0;i<3;i++){for(j=0;j<4;j++)printf("%4d",*(*(lp+i)+j));
printf("\n");}}lplp+1lp+2
0123
10111213
2021222301020111212122231323a2023/6/417【例5】用指向一维数组的指针变量输出数组元素。main(){inta[][4]={0,1,2,3,10,11,12,13,20,21,22,23};
int(*lp)[4],j;for(lp=a;lp<a+3;lp++){for(j=0;j<4;j++)printf("%4d",*(*lp+j));
printf("\n");}}lplplp01020111212122231323a
0123
10111213
20212223lp2023/6/418【例6】通过初始化使指针指向一个字符串。main(){charstr1[]="Goodmorning!";
char*str2="Goodnight!";
printf("%s\n",str1);printf("%s\n",str2);}6.2.2指向字符串的指针变量1.指向字符串的指针变量的定义及初始化
字符串的两种表示方式:
字符数组表示方式,字符串存放在一维数组中,引用时用数组名。
字符指针变量表示方式,字符指针变量存放字符串的首地址,引用时用指针变量名。Goodmorning!Good
night!2023/6/419【例7】通过赋值运算使字符指针变量指向一个字符串。#include<string.h>main(){charc[70],*str;
strcpy(c,"Howareyou?");
str="Fine,thanks.";
printf("%s\n%s\n",c,str);}2.字符串的赋值运算
将一个字符串赋给一个字符数组只能使用strcpy函数将字符串常量的首地址赋给指针变量,可使用赋值运算符“=”
Howareyou?Fine,thanks.2023/6/420【例8】利用指针变量输入输出字符串。#include<stdio.h>main(){charc[70],*str;
str=c;
gets(str);
puts(str);}3.字符串的输入输出
IloveChina!
IloveChina!
2023/6/421指针数组定义的一般形式:
数据类型标识符*数组名[元素个数];
在这个定义中由于“[
]”比“*”的优先级高,所以数组名先与“[元素个数]”结合,形成数组的定义形式,“*”表示数组中每个元素是指针类型,“数据类型标识符”说明指针的目标变量的数据类型。例如:
int*ip[10];char*cp[5];6.2.3指针数组1.指针数组的定义
指针数组就是数组中的每个元素均为指针类型
2023/6/422例如:char*str[5]={"int","long","char","float","double"};6.2.3指针数组2.指针数组初始化
str[4]str[3]str[2]str[1]str[0]\0elbuod\0taolf\0rahc\0gnol\0tni2023/6/423【例9】用0--6分别代表星期日至星期六,当输入其中任意
一个数字时,输出相应英文单词。main(){char*weekname[7]={"Sunday","Monday","Tuesday",
"Wednesday","Thursday","Friday","Saturday"};
intweek;
printf("EnterweekNo.:");
scanf("%d",&week);if(week>=0&&week<7)
printf("week
No.%d——%s\n",week,weekname[week]);}6.2.3指针数组3.利用字符指针数组处理多个字符串
利用字符指针数组处理长度不等的字符串,可节省存储空间。
2023/6/424
指针变量中存放的是普通变量的地址,但作为变量它也有自己的存储地址,要存放指针变量存储地址的变量也要是指针变量.由于存储的是指针变量的地址,因此是指向指针的指针变量,或称为二级指针变量.&pq&xp65x二级指针变量一级指针变量普通变量6.2.4多级指针1.二级指针变量的定义
2023/6/425指针的指针是指向指针数据的指针变量。也称为二级指针.定义的一般形式为:char**q;
由于*运算符的结合性是右结合的,因此**q相当于*(*q),表示指针变量q是指向一个字符指针变量的。6.2.4多级指针1.二级指针变量的定义
2023/6/426【例10】使用指向指针的指针。main(){intx=65;
int*p;int**q;p=&x;q=&p;
printf(“x=%d,*p=%d,**q=%d”,x,*p,**q);}运行结果为:x=65,*p=65,**q=652023/6/427【例11】使用指向指针的指针。main(){ char*p[]={"teacher","book","pascal","hello","and","me"}; char**q;
intj;q=p;
for(j=0;j<6;j++) {printf(“%s\n”,*q);q++;}}运行结果为:teacherbookpascalhelloandme2023/6/4286.3指针与函数
返回值为指针的函数称为指针类型函数。指针类型函数原型的一般形式:
类型名*函数名(参数类型表);说明:类型名为函数返回的地址值的基类型。例如:
int*a(int
x,inty);float*b(floatn);char*str(char
ch);6.3.1返回指针值的函数2023/6/429【例12】输入一个1-7之间的整数,输出对应的星期名.char*day_name(intn){char*name[]={“errorday”,”Monday”,”Tuesday”,“Wednesday”,”Thursday”,”Friday”,”Saturday”,”Sunday”};
if(n<1||n>7)returnname[0];elsereturnname[n];}main(){inti;
scanf(“%d”,&i);
printf(“%d->%s”,i,day_name(i));}运行结果为:2↙2->Tuesday2023/6/430
函数作为程序实体,在程序执行前要将其代码装入内存,占据内存中的一段连续存储区域,因此也有内存地址。函数在内存中一段连续的存储区域的首字节编号叫函数的入口地址,又叫做函数指针.
在C语言中,函数指针用函数名表示,它是一个指针常量.可以定义指向函数的指针变量来接受函数指针,然后通过指向函数的指针变量来访问该函数.
6.3.2指向函数的指针2023/6/4311、用指向函数的指针变量调用函数指向函数的指针变量一般定义形式为:
数据类型(*指针变量名)();
其中:数据类型是指函数值的返回类型。例:int(*p)();注意:int(*p)()和int*p()的区别函数的调用可以通过函数名调用,也可以通过函数指针调用(即用指向函数的指针变量调用)。
6.3.2指向函数的指针2023/6/432用指向函数的指针变量调用函数的步骤:定义指向函数的指针变量.给指针变量赋函数的入口地址(即函数名)调用函数.
形式为:(*指针变量)(实参列表)6.3.2指向函数的指针2023/6/433【例13】指向函数的指针示例。
main(){int
sum(intx,inty);int(*p)();
int
a,b,Result;
p=sum;
scanf("%d%d",&a,&b);
result=(*p)(a,b);
printf("Thesumis%d\n",Result);}
int
sum(int
x,inty){intz;z=x+y;
return(z);}2023/6/4342、指向函数的指针作函数参数:有了函数指针,就可以实现整个函数在函数之间的传递,也就是函数名作为实参传递给其它函数。函数指针常见用途之一是把指针作为参数传递到其他函数。6.3.2指向函数的指针2023/6/435【例14】利用梯形法计算定积分
#include“math.h”floatintdgral(double(*funp(),float
a,floatb){floats,h,y;int
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论