语言电子教案指针.ppt

上传人:本田雅阁 文档编号:3306993 上传时间:2019-08-10 格式:PPT 页数:83 大小:1.32MB
返回 下载 相关 举报
语言电子教案指针.ppt_第1页
第1页 / 共83页
语言电子教案指针.ppt_第2页
第2页 / 共83页
语言电子教案指针.ppt_第3页
第3页 / 共83页
语言电子教案指针.ppt_第4页
第4页 / 共83页
语言电子教案指针.ppt_第5页
第5页 / 共83页
点击查看更多>>
资源描述

《语言电子教案指针.ppt》由会员分享,可在线阅读,更多相关《语言电子教案指针.ppt(83页珍藏版)》请在三一文库上搜索。

1、第11章 指 针,知识点: 指针的定义 指针变量的使用 各种指针的使用 重点: 指针的概念及C语言指针使用的特点 指针变量的定义、引用 数组的指针、字符串的指针、函数的指针、指向指针的指针的使用 难点: 指针的运算和使用 指针在数组中的使用及使用特点,指针是C语言中的一个重要的概念,也是C语言的一个重要特色。 可以表示复杂的数据结构 能动态分配内存 能方便地使用字符串 有效而方便地使用数组 在调用函数时能得到多于1个的值 能直接处理内存地址等,第11章 指 针,11.1 地址和指针的概念,“直接访问”方式 按变量地址存取变量值的方式,int x,y,z;,x=20,y=40;,z=x+y;,编

2、译系统把变量名转换为变量的地址,对变量值的存取通过地址进行的。,内存,11.1 地址和指针的概念,“间接访问”方式 通过存放变量地址的变量去访问变量,int x,*x_point;,x_point=,*x_point=20;,11.1 地址和指针的概念,k=x; /*直接访问*/,x_pointer= /*间接访问*/,10,10,变量的指针 就是变量的地址 指针变量 存放变量地址的变量 用来指向另一个变量 用“*”符号表示“指向”,11.2 变量的指针和指向变量的指针变量,定义一个指针变量 指针变量不同于整型变量和其他类型的变量,它是用来专门存放地址的。 必须将指针变量定义为“指针类型”。

3、一般形式 基类型 *指针变量名; 基类型:指针变量所指向的变量的类型。 例 float *pointer1; int *pointer2; char *pointer3; 指针变量的定义是通过*进行的 定义后的指针变量只能赋值指针,不能赋值为一般数据类型,11.2 变量的指针和指向变量的指针变量,指针变量的引用 & 与*运算符 - 单目运算,优先级2,自右向左结合 & 取地址运算符 取变量的地址,取出的地址一定是一个常数 &变量名=指针值 * 指针运算符 指针变量所指向的内存单元,可称为指针变量所指的变量 与指针变量定义中的*不同 “*指针变量” 可以作为一个基类型变量来用,11.2 变量的指

4、针和指向变量的指针变量,11.2 变量的指针和指向变量的指针变量,main() int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1= ,100,10 100,10,指针变量的初始化 一般形式 基类型 *指针变量名=初始地址值;,11.2 变量的指针和指向变量的指针变量,例 int i; int *p=,例 int i; int *p=,例 int *p=,用已初始化指针变量作初值,11.2 变量的指针和指向变量的指针变量,指针变量使用前必须先初始化或赋初值,例 main() int i=10, *p; *p=i; printf(“

5、%d”,*p); ,结果:10,危险!,例 main( ) int i=10,k, *p; p= ,零指针与空类型指针 零指针:(空指针) 定义:指针变量值为零 表示: int * p=0;,11.2 变量的指针和指向变量的指针变量,p指向地址为0的单元, 系统保证该单元不作他用(不存放有效数据) 表示指针变量值没有意义,NULL在stdio.h中定义,原型为#define NULL 0 int *p=NULL; 用途: 避免指针变量的非法引用 在程序中常作为状态比较,例 int *p; while(p!=NULL) . ,11.2 变量的指针和指向变量的指针变量,空类型指针 定义:指针变量不

6、指向哪一种类型数据 表示: void *p; 使用时要进行强制类型转换,表示不指定p2是指向哪一种 类型数据的指针变量,例 char *p1; void *p2; p1=(char *)p2; p2=(void *)p1;,11.2 变量的指针和指向变量的指针变量,main() int a; int *pa= ,a=10,*pa=10 &a=ffda(hex),pa=ffda(hex) &pa=ffde(hex),练习,11.2 变量的指针和指向变量的指针变量,int x,y,*x_pointer,*y_pointer;,x_pointer=,y_pointer=,y_pointer=,y=*

7、,&与*运算符右结合 *右侧接指针变量,如:*x_pointer &右侧接一般变量,如:&x,指针变量作为函数参数 作用是将变量的地址传送到另一个函数中,11.2 变量的指针和指向变量的指针变量,swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; main() int a,b,*pointer_1,*pointer_2; scanf(“%d,%d“,5,9,9,5,11.2 变量的指针和指向变量的指针变量,swap(int *p1,int *p2) int *temp,x; temp=,5,9,9,5,11.2 变量的指针和

8、指向变量的指针变量,swap(int *p1,int *p2) int *temp; temp=p1; p1=p2; p2=temp; main() int a,b,*pointer_1,*pointer_2; scanf(“%d,%d“,5,9,5,9,想通过函数调用得到n个要改变的值,可以: 在主调函数中设n个变量,用n个指针变量指向它们 将指针变量作实参,将这n个变量的地址传给所调用的函数的形参 通过形参指针变量,改变该n个变量的值 主调函数中就可以使用这些改变了值的变量,11.2 变量的指针和指向变量的指针变量,11.2 变量的指针和指向变量的指针变量,例:输入a、b、 c3个整数,按

9、大小顺序输出。,main() int a,b,c,*p1,*p2,*p3; scanf(“%d,%d,%d“, ,swap(int *pt1, int *pt2) int temp; temp=*pt1; pt1=*pt2; *pt2=temp; ,exchange(int *q1, int *q2, int *q3) if(*q1*q2) swap(q1,q2); if(*q1*q3) swap(q1,q3); if(*q2*q3) swap(q2,q3); ,数组的指针是指数组的起始地址 数组元素的指针是数组元素的地址 指向数组元素的指针 用法与指向变量的指针变量相同 int,a5,*p,

10、*q; p=,11.3 数组与指针,由于数组名是数组的首地址(常量) p=a; /*相当于p=,a,指针变量与指针的运算 指针变量的赋值运算 p= 出现编译警告,但可以执行,11.3 数组与指针,指针的算术运算 p+/+p 指针后移一个单元(元素) p-/-p 指针前移一个单元(元素) p+n 指向p指针下的n个单元(元素) p-n 指向p指针上的n个单元(元素) p-q 求两指针之间单元(元素)个数 单元(元素)大小与指针的具体数据类型有关,如当指针变量的基类型为整型时,一个单元(元素)的大小为2bytes;当指针变量的基类型为浮点型时,一个单元(元素)大小为4bytes。,11.3 数组与

11、指针,11.3 数组与指针,例:,int a5, *p,*q; q=,p+;,p-;,p+2;,q-1;,q-p;,=4,*(p+1)或*(a+1);,=a1,指针的关系运算 实质是两个地址之间的比较,地址大的指针大,地址小的指针小 pq p=q pq p=q p=q p!=q,11.3 数组与指针,引用数组元素的方法 int a5,*p; p=a;,11.3 数组与指针,下标法 ai和pi,指针法 *(a+i)和* (p+i),例 输出数组中的全部元素,11.3 数组与指针,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (i=0;i10;i+)

12、printf(“%4d”,ai); ,用下标法引用数组元素,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (i=0;i10;i+) printf(“%4d”,*(a+i); ,11.3 数组与指针,用指针法引用数组元素 数组名a在计算过程中代表数组的首地址 对ai进行变址运算,转化为*(a+i),main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (p=a;p(a+10);p+) printf(“%4d”,*p); ,11.3 数组与指针,p的初值为数组a的起始地址 计算过程中使用了指针加法 数组名a在计算过

13、程中代表数组的首地址,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (p=a,i=0;i10;i+) printf(“%4d”, pi); ,11.3 数组与指针,用下标法引用数组元素 p的初值为数组a的起始地址,11.3 数组与指针,main() int i,*p,a10; p=a; for(i=0;i10;i+) scanf(“%d“,p+); printf(“n“); for(i=0;i10;i+,p+) printf(“%d“,*p); ,1 2 3 4 5 6 7 8 9 0,22153 234 0 0 30036 25202 11631

14、 8259 8237 28483,p=a;,1 2 3 4 5 6 7 8 9 0,例 通过指针变量输出a数组的10个元素,main() int a =5,8,7,6,2; int y,*p= ,11.3 数组与指针,6,5 6,例:,用数组名作函数参数 数组名作函数实参,传递给形参的是地址(地址传递) 传递的地址是数组的首地址,形参接收的是数组的首地址 形参定义时为数组,形参数组的维数可省略(一维数组) 实际上,编译系统把形参数组名作为指针变量来处理,11.3 数组与指针,前面已经分析,指向数组的指针变量可以通过指针法,也可以通过下标法引用数组元素,所以,11.3 数组与指针,void f(

15、int b ) printf(“len of b is %dByten“,sizeof(b); printf(“a1=%d“,b1); main() int a3=1,2,3; f(a);,len of b is 2Byte a1=2,例:,void f(int *b) printf(“a1=%d“,*(b+1);,数组名作函数参数,实参与形参的对应关系,11.3 数组与指针,例 将数组a中n个整数按相反顺序存放,11.3 数组与指针,算法: 设两个“位置指示变量”i和j,i的初值为0,j的初值为n-1 将ai与aj交换 使i的值加1,j的值减1 再将ai与aj对换,直到i=(n-1)/2为止

16、,main() int i,a10=3,7,9,11,0,6,7,5,4,2; printf(“The original array:n“); for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); inv(a,10); printf(“The array has been inverted:n“); for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); ,void inv(int x ,int n) int temp,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; temp=xi;

17、xi=xj; xj=temp; ,11.3 数组与指针,i,j,void inv(int *x,int n) int *p,temp,*i,*j,m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i=p;i+,j-) temp=*i; *i=*j; *j=temp; ,11.3 数组与指针,多维数组与指针 多维数组的地址 int a34=1,3,5,7,9,11,13,15,17,19,21,23; 可以把a看作是一维数组,有3个元素:a0,a1,a2 a0,a1,a2可以分别认为是包含4个元素的一维数组 二维数组是数组的数组,11.3 数组与指针,11.3 数组与指针,1

18、1.3 数组与指针,a-二维数组的首地址,即第0行的首地址 a+i-第i行的首地址 ai *(a+i)-第i行第0列的元素地址 ai+j *(a+i)+j -第i行第j列的元素地址 *(ai+j) *(*(a+i)+j) aij,a+i=&ai=ai=*(a+i) =&ai0,值相等,含义不同 a+i &ai,表示第i行首地址,指向行 ai *(a+i) &ai0,表示第i行第0列元素地址,指向列,#define FORMAT “%x,%xn“ #define FORMAT1 “%d,%dn“ main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; pri

19、ntf(FORMAT,a,*a); printf(FORMAT,a0,*(a+0); printf(FORMAT,11.3 数组与指针,例 输出二维数组有关的值。,ffb8,ffb8 ffb8,ffb8 ffb8,ffb8 ffc0,ffc0 ffc0,ffc0 ffc8,ffc8 ffc8,ffc8 9,9,11.3 数组与指针,11.3 数组与指针,指向多维数组元素的指针变量 指向数组元素的指针变量,main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=a0;pa0+12;p+) if(p-a0)%4=0) printf(

20、“n“); printf(“%4d“,*p); ,1 3 5 7 9 11 13 15 17 19 21 23,11.3 数组与指针,在int anm数组中求aij的首地址,&aij=&a00+i*m+j,11.3 数组与指针,指向由m个元素组成的一维数组的指针变量 定义形式 数据类型 (*指针变量名)一维数组的维数 例:int (*p)4,可以认为数组名称为*p,p只能指向包含4个元素的一维数组(p是该数组的首地址) 可让p指向二维数组的某一行 例:int a34, (*p)4=a; 一维数组指针变量维数和二维数组列数必须相同,11.3 数组与指针,用指向多维数组的指针作函数参数 指针变量作

21、形参接受实参数组名传递来的地址时,可以 用指向变量的指针变量 用指向一维数组的指针变量 例 有一个班,3个学生,各学4门课,计算总平均分数,以及第n个学生的成绩。,11.3 数组与指针,11.3 数组与指针,main() void average(float *p,int n); void search(float (*p)4,int n); float score34=65,67,70,60,80,87,90,81,90,99,100,98; average(score,12); search(score,2); getch(); void average(float *p,int n) f

22、loat *p_end; float sum=0,aver; p_end=p+n-1;/*最后一行(最后一个学生)最后一列(最后一门成绩)的首地址*/ for(;p=p_end;p+) sum=sum+(*p); aver=sum/n; printf(“naverage= %5.2f n“,aver); void search(float (*p)4,int n) int i; printf(“the score of No.%d are:n“,n); for(i=0;i4;i+) printf(“%5.2f “, *(*(p+n)+i); ,字符串的表示形式,11.4 字符串与指针,用字符数

23、组实现,main() char string =“I love China!“; printf(“%sn“,string); printf(“%sn“,string+7); ,I love China! China!,数组名是数组的首地址,11.4 字符串与指针,用字符指针实现 字符指针变量初始化:把字符串首地址赋值给字符指针变量,main( ) char *string=“I love China!”; printf(“%sn”,string); string+=7; while(*string) printf(“%c“,*string); string+; ,I love China! C

24、hina!,11.4 字符串与指针,字符串指针作函数参数 例:字符串的复制,11.4 字符串与指针,用字符数组作参数,void copy_string(char from , char to ) int i=0; while(fromi!=0) toi=fromi; i+; toi=0; main() char a =“I am a teacher.“; char b =“you are a student.“; printf(“string a=%snstring b=%sn“,a,b); copy_string(a,b); printf(“nstring a=%snstring b=%sn

25、“,a,b); getch(); ,11.4 字符串与指针,用字符指针变量作参数,void copy_string(char *from,char *to) for(;*from!=0;from+,to+) *to=*from; *to=0; main() char *a=“I am a teacher.“; char *b=“You are a student.“; printf(“string_a=%snstring_b=%sn“,a,b); copy_string(a,b); printf(“nstring_a=%snstring_b=%sn“,a,b); getch(); ,字符指针变

26、量和字符数组的区别 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串的首地址),决不是将字符串放到字符指针变量中。 赋值方式。对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值。 char str14; str=“I love China!“; 而对字符指针变量,可以采用下面方法赋值: char*a; a=“I love China!“; 但注意赋给a的不是字符,而是字符串的首地址。,11.4 字符串与指针,对字符指针变量赋初值: char *a=“I love China!“;等价于 char *a; a=“I love China!“; 对数组的

27、初始化: char str14=“I love China!“;不能等价于 char str14; str =“I love China!“; 即数组可以在变量定义时整体赋初值,但不能在赋值语句中整体赋值。,11.4 字符串与指针,编译系统在编译时为定义的字符数组分配内存单元,它有确定的地址。为定义一个字符指针变量分配内存单元,在其中可以放一个地址值,但地址值不确定。 char a9,*p;,11.4 字符串与指针,地址确定,字符指针变量的值可以改变,字符数组名(地址常量)不可以改变。 p+; a+; ,用函数指针变量调用函数 函数指针变量可以指向一个函数。 函数在编译时被分配给一个入口地址,

28、即函数的指针。 函数指针变量存储函数的指针。 函数名是函数的入口地址,即函数指针变量,11.5 指向函数的指针,函数返回值的数据类型,专门存放函数入口地址,可指向返回值类型相同的不同函数,( )不能省,使用函数指针变量 定义形式 数据类型 (*指针变量名)(); 如 int (*p)();,函数指针变量赋值:如p=max;,函数指针变量指向的函数必须有函数说明,函数调用形式: c=max(a,b); c=(*p)(a,b); 对函数指针变量pn, p+, p-无意义,main() int max(int ,int); int (*p)(); int a,b,c; p=max; scanf(“%

29、d,%d“, ,11.5 指向函数的指针,11.5 指向函数的指针,用指向函数的指针作函数参数 例 用函数指针变量作参数,求最大值、最小值和两数之和。,定义形式 类型名 *函数名(参数列表) int *f(int x,int y) 函数返回值的类型是指向整型数据的指针(地址),11.6 返回指针值的函数,例 求两个int型变量中居于较大值的变量的地址。,11.6 返回指针值的函数,!不能把形参或局部变量的地址作函数返回值,11.7 指针数组和指向指针的指针,指针数组的概念 数组中的元素为指针变量 定义形式 数据类型 *数组名数组长度 int *p4;char *name5;,(元素)指针变量所

30、指数据的数据类型,区分int *p4与int (*p)4,用指针数组执行若干字符串,可以节省内存单元以及处理灵活,用二维数组,浪费存储空间,#include void sort(char *name,int n) char *temp; int i,j,k; for(i=0;i0) k=j; if(k!=i) temp=namei; namei=namek; namek=temp; main() char *name=“Follow me“,“BASIC“, “Great Wall“,“FORTRAN“,“Computer “; int n=5; sort(name,n); print(nam

31、e,n); ,例:将若干字符串按字母顺序(由小到大)输出,11.7 指针数组和指向指针的指针,指向指针的指针 指向指针数据的指针变量(即指针变量存放的是指针变量的地址) 定义形式 数据类型 *指针名,最终目标变量的数据类型,例: int c=5,*p,*q; p=,printf(“%d,%d,%d“,c,*p,*q); 5,5,5,11.7 指针数组和指向指针的指针,main() char *a=“hello“,“world“,“China“,*p; int i; for (p=a,i=0;i3;i+) printf(“n*a%d=%s“,i,*(p+i); ,*a0=hello,*a1=wo

32、rld,*a2=China,11.7 指针数组和指向指针的指针,main() char *a=“hello“,“world“,“China“,*p; int i; p=a; for (i=0;i3;i+,p=a+i) printf(“n*a%d=%s“,i,*p); ,指针数组作main函数的形参 命令行:在操作系统状态下,为执行某个程序而键入的一行字符 命令行一般形式:命令名 参数1 参数2参数n C:TC copy.exe source.c temp.c,11.7 指针数组和指向指针的指针,有3个字符串参数的命令行,带参数的main函数形式:,main(int argc, char *ar

33、gv) ,元素指向命令行参数中各字符串首地址,命令行中参数个数,命令行参数传递,第一个参数: main所在的可执行文件名,11.7 指针数组和指向指针的指针,/*test.c*/ main(int argc, char *argv) while(argc1) argv=argv+1; printf(“%sn“,*argv); -argc; ,编译、链接test.c,生成可执行文件test.exe 在DOS状态下运行(test.exe所在路径下) C:TC test.exe hello world!,hello world!,例,指向结构体变量的指针 定义形式 struct 结构体名 *结构体指

34、针名;,11.8 指向结构体的指针,例 struct student int num; char name20; char sex; int age; float score; char addr30; ; struct student s,*p; p=,指向结构体数组的指针,11.8 指向结构体的指针,printf(“%5d %-20s %2c %4dn“, p-num, p-name, p-sex, p-age);,用指向结构体的指针作为函数参数 结构体指针做函数参数,传地址,11.8 指向结构体的指针,11.8 指向结构体的指针,#define FORMAT “%dn%sn%fn%fn%

35、fn“ struct student int num; char name20; float score3; stu=12345,“Li Li“,67.5,89,78.6; main() void print(struct student *); /*形参类型修改成指向结构体的指针变量*/ print( ,例:结构体数组作函数参数 打印2名学生的3门成绩,struct student int num; char name20; int score3; stu2; void input(struct student stu1) int i,j; for(i=0;i2;i+) printf(“in

36、put NO.:“); scanf(“%d“, ,void print(struct student stu2) int i,j; for(i=0;i2;i+) printf(“n NO. %d“,stu2i.num); printf(“n name %s“,stu2i.name); for(j=0;j3;j+) printf(“n %d score %d“,j+1,stu2i.scorej); ,main() clrscr(); input(stu); print(stu); getch(); ,链表是一种常见的数据结构,是可以动态地分配存储空间的一种结构。 数组是一种静态地分配存储空间的方

37、式,11.9 用指针处理链表,链表的构成: 头指针,存放一个地址,指向链表的第一个元素 链表中每个元素称为一个“结点”,每个结点包括两部分:用户数据和指向下一个结点的地址 最后一个元素称为“表尾”,其地址为NULL(空地址),#include struct node /*定义结点类型*/ char data; /*数据域*/ struct node *next; /*指向下一个结点的指针域*/ a,b,c,d,*head,*p;,11.9 用指针处理链表,head=,do printf(“%c-“,p-data); p=p-next; while (p!=NULL);,静态链表: 需要的节点事

38、先建立,动态链表 所需函数,11.9 用指针处理链表,定义节点类型 #define NULL 0 /*空地址*/ #define LEN sizeof(struct node) /*结点长度*/ struct node int data; struct node *next; int n;/*表示结点个数*/,建立动态链表,11.9 用指针处理链表,struct node *creat(void) struct node *head,*p,*q; n=0; p=(struct node *)malloc(LEN); scanf(“%d”,main() struct node *head; he

39、ad=creat(); ,输出链表,11.9 用指针处理链表,void print(struct node *head) struct node *p; p=head; if (head!=NULL) do printf(“ %d“,p-data); p=p-next; while(p!=NULL); ,main() struct node *head; head=creat(); print(head); ,链表的删除(删除p所指的结点),11.9 用指针处理链表,head=p-next; free(p);,q-next=p-next; free(p);,链表的插入(在q所指结点前插入新结点*s),11.9 用指针处理链表,s=(struct node*)malloc(LEN); scanf(“%d“,11.9 用指针处理链表,s=(struct node*)malloc(LEN); scanf(“%d“,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1