第8章指针.ppt

上传人:本田雅阁 文档编号:2501508 上传时间:2019-04-04 格式:PPT 页数:93 大小:1.08MB
返回 下载 相关 举报
第8章指针.ppt_第1页
第1页 / 共93页
第8章指针.ppt_第2页
第2页 / 共93页
第8章指针.ppt_第3页
第3页 / 共93页
亲,该文档总共93页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第8章指针.ppt》由会员分享,可在线阅读,更多相关《第8章指针.ppt(93页珍藏版)》请在三一文库上搜索。

1、第8章 指 针,8.1 地址和指针的概念 8.2 变量的指针和指向变量的指针变量 8.3 数组的指针和指向数组的指针变量 8.4 字符串的指针和指向字符串的指针变量 8.5 函数的指针和指向函数的指针变量 8.6 返回指针值的函数 8.7 指针数组和指向指针的指针 习题,8.1 地址和指针的概念,内存:内部存储器,由存储单元组成。存储单元是 线性连续的。存储单元的最小单位是字节。 计算机中对不同存储单元的区分:给每个存储单元 编号,根据编号找到相应的存储单元(即内存地址)。,int i=10; char ch=A; float f1=3.14;,printf(”%f”,f1);,int i,j

2、,k;,printf(”%d”,i);,scanf(“%d“,k=i+j;,int *i_pointer; i_pointer=,为了表示将数值3送到变量中,可以有两种表达方法: (1) 将3送到变量i所标志的单元中。 (2) 将3送到变量i_pointer所“指向”的单元。 由于通过地址能找到所需的变量单元,我们可以说,地址“指向”该变量单元。因此在C语言中,将地址形象化地称为“指针” 。,如果有一个变量专门用来存放另一变量的地址(即 指针),则它称为“指针变量”。,回第八章,8.2 变量的指针和指向变量的指针变量 如前所述,变量的指针就是变量的地址。存放变量地址的变量是指针变量,用来指向另

3、一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中用“*”符号表示“指向”,例如,i_pointer代表指针变量,而*i_pointer是i_pointer所指向的变量。,*i_pointer也代表一个变量,它和变量i是同一回事。下面两个语句作用相同: i=3; *i_pointer=3;,int i,*i_pointer; i_pointer=,8.2.1 定义一个指针变量 C语言规定所有变量在使用前必须定义,指定其类型,并按此分配内存单元。指针变量不同于整型变量和其他类型的变量,它是用来专门存放地址的。必须将它定义为“指针类型”。 int i,j; int *pointer_1

4、,*pointer_2; 定义指针变量的一般形式为: 基类型 *指针变量名,float *pointer_3; char *pointer_4; 指针变量指向另一个变量: pointer_1= 将变量i的地址存放到指针变量pointer_1 中,因此pointer_1 就“指向”了变量i。 同样,pointer_2 就“指向”了变量j。,在定义指针变量时要注意两点: (1) 指针变量前面的“*”,表示该变量的类型为指针型变量。注意:指针变量名是pointer_1、pointer_2,而不是*pointer_1、*pointer_2。 (2) 在定义指针变量时必须指定基类型。,指针变量中只能存放

5、地址(指针),不要将一个整型量(或任何其他非地址类型的数据)赋给一个指针变量。下面的赋值是不合法的: pointer_1=100; 有两个有关的运算符: (1) &: 取地址运算符。 (2) *: 指针运算符(或称“间接访问”运算符)。 例如:&a为变量a的地址,*p为指针变量p所指向的存储单元。,8.2.2 指针变量的引用,例8.1通过指针变量访问整型变量。 #include int main( ) int a,b; int *pointer_1, *pointer_2; a=100;b=10; pointer_1= ,100,10 100,10,下面对“”语句,若有 &*pointer_1

6、 它的含义是什么?,“,(2) *&a的含义是什么?先进行&a运算,得a的地址,再进行*运算。即&a所指向的变量,*&a和*pointer_1 的作用是一样的 ( 假设已执行了“pointer_1=&a”),它们等价于变量a。即*&a与a等价。,(3) (*pointer_1)+相当于a+。 *pointer_1+ 相当于*(pointer_1+)。由于+在pointer_1的右侧,是“后加”,因此先对pointer_1的原值进行*运算,得到a的值,然后使pointer_1的值改变,这样pointer_1不再指向a了。 指针变量应用的例子: 例8.2输入a和b两个整数,按先大后小的顺序输出a和

7、b。,#include int main() int *p1,*p2,*p,a,b; scanf(“%d,%d“, ,5,9 a=5,b=9 max=9,min=5,交换前 交换后,8.2.3 指针变量作为函数参数 函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。 例8.3 对输入的两个整数按大小顺序输出。 用函数处理,用指针类型的数据作函数参数。 程序如下:,#include swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; int main() int a,

8、 b, *pointer_1, *pointer_2; scanf(“%d, %d“, ,5,9 9,5,p1,p1,swap(int *p1,int *p2) int temp; *temp=*p1; *p1=*p2; *p2=*temp; ,swap(int x,int y) int temp; temp=x; x=y; y=temp; ,通过函数调用得到n个要改变的值 228页,练习(1): #include void sub(int x,int y,int *z) *z=y-x; int main() int a,b,c; sub(10,5,-5,-12,-7,练习(2): #incl

9、ude void fun(char *a,char *b) a=b; (*a)+; int main( ) char c1=A,c2=a,*p1,*p2; p1= ,Ab,回第八章,8.3 数组的指针和指向数组的指针变量,指向数组元素的指针 int a10; int *p; /*定义p为指向整型变量的指针变量*/ p=,int *p=,通过指针引用数组元素 假设p已定义为指针变量,并已给它赋了一个地址,使它指向某一个数组元素。如果有以下赋值语句: *p=1; C规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素.,float a10,*p,*q; p=a; q=p+

10、1; q=p+5;,int a10,*p; p=,p+i a+i,*(p+i) *(a+i),ai,如果p的初值为&a0,则: (1) p+i和a+i就是ai的地址,它们指向a数组的第i个元素。a代表数组首地址,a+i也是地址,它的实际地址为a+iD。 (2) *(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即ai。例如,*(p+5)或*(a+5)就是a5。,(3) 指向数组的指针变量也可以带下标,如pi与*(p+i)等价。,引用一个数组元素,可以用: (1) 下标法,如a0、a5、a1+1。 (2) 指针法,如*(a+i)或*(p+i)。其中a是数组名,p是指向数组的指针变量,其

11、初值p=a。,例8.5 输出数组中的全部元素。假设有一个a数组, 整型,有10个元素。输出各元素的值,(1) 下标法。,#include int main() int a10; int i; for(i=0;i10;i+) scanf(“%d“,,(2) 通过数组名计算数组元素地址,找出元素的值。 #include int main( ) int a10; int i; for(i=0;i10;i+) scanf(“%d“, ,(3) 用指针变量指向数组元素。 #include int main( ) int a10; int *p,i; for(i=0;i10;i+) scanf(“%d“,

12、 ,三种方法的比较 (课后看234页),使用指针变量时,注意: (1) 指针变量可以实现使本身的值改变。例如,上述第3种方法是用指针变量p来指向元素,用p+使p的值不断改变。如果不用p而使a变化(例如,用a+)行不行呢?假如将上述3)程序的最后两行改为 for(p=a;a(p+10);a+) printf(“%d“,*a);,(2) 要注意指针变量的当前值。 例8.6 通过指针变量输出a数组的10个元素。 #include int main( ) int *p,i,a10; p=a; for(i=0;i10;i+) scanf(“%d“,p+); printf(“n“); for(i=0;i1

13、0;i+,p+) printf(“%d “,*p); return 0;,1 2 3 4 5 6 7 8 9 0 22153 234 0 0 30036 25202 11631 8259 8237 28483,#include int main() int *p,i,a10; p=a; for(i=0;i10;i+) scanf(“%d“,p+); printf(“n“); p=a; for(i=0;i10;i+,p+) printf(“%d “,*p); return 0; ,(3) 从上例可以看到,虽然定义数组时指定它包含10个元素,可以用p指向当前的数组元素。但是实际上指针变量p可以指向

14、数组以后的内存单元。如果引用数组元素a10,C编译程序并不认为非法,但会使程序得不到预期的结果。,(4) 注意指针变量的运算。 若有 p=a;/*前提*/ p+; b=*p;,for(i=0;i10,i+) printf(“%d “,*p+);,p, *p+ 等价于 *(p+) b=*p+; c=*p; 例: for(i=0;i10;i+,p+) printf(“%d “,*p);, *(+p) 先使p加1,再取*p。 b=*(+p);, (*p)+ b=(*p)+;,p, 如果p当前指向a数组中第i个元素,则: *(p-):相当于ai-,先对p进行“*”运算,再使p自减。 *(+p):先使p

15、自加,再进行“*”运算。 *(-p):先使p自减,再进行“*”运算。,b=5 a0=6,输出a数组100个元素: p=a; p=a; while(pa+100) 或 while(pa+100) printf(”%d”,*p+); printf(“%d“,*p); p+;,用数组名作函数参数 数组名可以用作函数的形参和实参。如: #include int main( ) int f(int arr ,int n) int array10; int f(int arr ,int n) ; f(array,10); ,例8.8从10个数中找出其中最大值和最小值。 本题不要求改变数组元素的值,只要求得

16、到最大值和最小值。但是调用一个函数只能得到一个返回值,为了能得到两个结果值,今用全局变量在函数之间“传递”数据。程序如下:,#include int max,min; /*全局变量*/ void max_min_value(int array ,int n) int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;parray_end;p+) if(*pmax) max=*p; else if(*pmin) min=*p; return; ,int main() int i,number10; void max_m

17、in_value(int array ,int n); printf(“enter 10 integer numbers:n“); for(i=0;i10;i+) scanf(“%d“, ,enter 10 integer numbers: -2 4 6 8 0 -3 45 67 89 100 max=100,min=-3,函数max_min_value的形参array可以改为指针变量类型。即将该函数首部改为 void max_min_value(int *array,int n) 效果相同。 实参也可以不用数组名,而用指针变量传递地址,形参仍用指针变量。 P239 表,归纳起来,如果有一个实

18、参数组,想在函数中改变此数组的元素的值,实参与形参的表示形式有以下4种情况:,(1) 形参和实参都用数组名,如: int main() f(int x ,int n) int a10; f(a,10); ,(2) 实参用数组名,形参用指针变量。如: int main() f(int *x,int n) int a10; f(a,10); ,(3) 实参形参都用指针变量。例如:,int main() f(int *x,int n) int a10, *p; p=a; f(p,10); ,(4) 实参为指针变量,形参为数组名。如:,int main() f(int x ,int n) int a1

19、0,*p; p=a; f(p,10); ,例8.10用选择法对10个整数排序,#include int main( ) int *p,i,a10; p=a; for(i=0;i10;i+) scanf(“%d“,p+); p=a; sort(p,10); for(p=a,i=0;i10;i+) printf(“%d“,*p); p+; return 0; ,sort(int x ,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(xjxk) k=j; if(k!=i) t=xi;xi=xk;xk=t; ,12 15 2

20、4 56,sort(int *x,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(*(x+j)*(x+k) k=j; if(k!=i) t=*(x+i);*(x+i)=*(x+k);*(x+k)=t; ,12 15 2 4 56,以下程序的运行结果是:,#include int main() int a10=1,2,3,4,5,6,7,8,9,10,*p=a; printf(”%dn”,*(p+2); return 0; ,3,指向多维数组的指针和指针变量 1. 多维数组的地址 int a34;,a: 0行首地址 a+

21、1: 1行首地址 a+2: 2行首地址,a0 a1 a2,a1+2: &a12 2008+2*2=2012,*(a+1)+1,a1+1,&a11,2. 指向多维数组的指针变量 (1) 指向数组元素的指针变量。 例8.12 用指针变量输出数组元素的值。 #include int 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(“n“); printf(“%4d“,*p); return 0; ,1 3 5 7 9 11 13 15 17 19 21 23

22、,(2) 指向由m个元素组成的一维数组的指针变量。 定义形式: int (*p)n; p指向包含n个元素的一维数组(一般针对二维数组使用)。,p+1: a1 *(p+1),int a34; int (*p)4,i,j; p=a;,例8.13输出二维数组任一行任一列元素的值。,#include int main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j; p=a; scanf(“ i=%d,j=%d“,,i=1,j=2 a1,2=13,*(p+i) : ai,(*(p+i)+j) : &aij,*(*(p+i)+j) : ai

23、j,3. 多维数组的指针作函数参数(课后看),回第八章,8.4.1 字符串的表示形式 C程序中,可以用两种方法访问一个字符串: (1) 用字符数组存放一个字符串,然后输出该字符串.,8.4 字符串的指针和指向字符串的指针变量,例:#include int main() char string= “I love China!“; printf(“%sn“,string); return 0;,I love China!,“I love China!“,string,(2) 用字符指针指向一个字符串。 定义一个字符指针。用字符指针指向字符串中的字符。,例: #include int main()

24、char *string=“I love China!“; printf(“%sn“,string); return 0; ,I love China!,char *string=“I love China!“;,char *string; string=“I love China!“;,通过字符数组名或字符指针变量可以输出一个字符串。而对一个数值型数组,是不能企图用数组名输出它的全部元素的。如: int i10 ,printf(“%dn“,i);,用%s可以对一个字符串进行整体的输入输出。,对字符串中字符的存取,可以用下标方法,也可以 用指针方法。,例8.18 将字符串a复制为字符串b。,c

25、har a =k,e,y; printf(”%sn”,a);,#include int main() char a =“I am a boy.“, b20; int i; for(i=0;*(a+i)!=0;i+) *(b+i)=*(a+i); *(b+i)=0; printf(“string a is:%sn“,a); printf(“string b is:“); for(i=0;bi!=0;i+) printf(“%c“, bi); printf(“n“); return 0;,string a is:I am a boy. string b is:I am a boy.,例8.19用指

26、针变量来处理例8.18问题。,#include int main() char a=“I am a boy.“,b20,*p1,*p2; int i; p1=a; p2=b; for(;*p1!=0;p1+,p2+) *p2=*p1; *p2=0; printf(“string a is:%sn“,a); printf(“string b is:“); for(i=0;bi!=0;i+) printf(“%c“,bi); printf(“n“); return 0; ,8.4.2 字符串指针作函数参数 将一个字符串从一个函数传递到另一个函数,可以用地址传递的办法,即用字符数组名作参数或用指向字

27、符串的指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。 例8.20用函数调用实现字符串的复制。 (1) 用字符数组作参数。,#include void copy_string(char from , char to ) int i=0; while(fromi!=0) toi=fromi;i+; toi=0; int 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)

28、; printf(“nstring a=%snstring b=%sn“,a,b); return 0; ,程序运行结果如下: string_a=I am a teacher. string_b=you are a student.,string_a=I am a teacher. string_b=I am a teacher.,在main函数中也可以不定义字符数组,而用字符型指针变量。main函数可改写如下: int main() char *a=“I am a teacher.“; char *b=“you are a student.“; printf(“string a=%snstr

29、ing b=%sn“,a,b); copy_string(a,b); printf(“nstring a=%snstring b=%sn“,a,b); return 0; ,(2) 形参用字符指针变量。程序如下:,#include void copy_string(char *from,char *to) for(;*from!=0;from+,to+) *to=*from; *to=0; int main() char *a=“I am a teacher.“; char *b=“you are a student.“; printf(“nstring a=%snstring b=%sn“,

30、a,b); copy_string(a,b); printf(“nstring a=%snstring b=%sn“,a,b); return 0; ,(3) 对copy_string函数还可作简化(课后看).,回第十章,8.5.1 用函数指针变量调用函数 可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。 例8.23 求a和b中的大者。按一般方法的程序:,8.5 函数的指针和指向函数的指针变量,#include int main() int max(int

31、,int); int a,b,c; scanf(“%d,%d“, ,#include int main() int max(int,int); int (*p)(); int a,b,c; p=max; scanf(“%d,%d“, ,每一个函数都占用一段内存单元,它们有一个起始地址。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。 将main函数改写为:,c=(*p)(a,b); c=max(a,b); 说明: (1) 指向函数的指针变量的一般定义形式为 数据类型 (*指针变量名)(); (2) 函数的调用可以通过函数名调用,也可以通过 函数指针调用(即用指向函数的指针

32、变量调用)。 c=(*p)(a,b); 或 c=p(a,b);,(3) (*p)()表示定义一个指向函数的指针变量,它是专门用来存放函数的入口地址的。在一个程序中,一个指针变量可以先后指向不同的函数。 (4) 在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:p=max; 不能写成“p=max(a,b);”形式。 (5) 用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名). (6) 对指向函数的指针变量,像p+n、p+、p-等运算是无意义的。,8.5.2 用指向函数的指针作函数参数 函数指针变量常用的用途之一是把指针作为参数传递到其他函数。以前介绍过,函数的参数可

33、以是变量、指向变量的指针变量、数组名、指向数组的指针变量等。指向函数的指针也可以作为参数,以便实现函数地址的传递,也就是将函数名传给形参。,#include int fa(int x) return x*x; int fb(int x) return x*x*x; int f(int (*f1)(),int (*f2)(),int x) return f2(x)-f1(x); int main() int i; i=f(fa,fb,2); printf(”%dn”,i); return 0; ,例:,4,回第八章,一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。

34、一般定义形式: 类型名 *函数名(参数表); int *a(int x,int y); 例8.25有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。 程序如下:,8.6 返回指针值的函数,#include int main() float score 4=60, 70, 80, 90, 56, 89, 67, 88,34, 78, 90, 66; float *search(float (*pointer)4,int n); float *p; int i,m; printf(“enter the number of student

35、:“); scanf(“%d“,,enter the number of student:1 The scores of No.1 are:,for(i=0;i4;i+) printf(“%5.2ft“,*(p+i); return 0; float *search(float (*pointer)4, int n) float *pt; pt=*(pointer+n); return(pt); ,enter the number of student:1 The scores of No.1 are: 56.00 89.00 67.00 88.00,回第十章,8.7.1 指针数组的概念 一个

36、数组,其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。 一维指针数组的定义形式为: 类型名 *数组名数组长度 int p4,8.7 指针数组和指向指针的指针,int (*p)4,例: #include int main() char a=“FORTRAN“; char b=“PB“; char c=“BASIC“; char *p4; int i; p0=a; p1=b; p2=c; p3=NULL; for(i=0;pi!=NULL;i+) printf(“%d:%sn“,i+1,pi); return 0; ,1:FORTRAN 2:PB 3:B

37、ASIC,例: 将若干字符串按字母顺序(由小到大)输出。 #include int main() void sort(char *name , int n); void print(char *name , int n); char *name=“Follow me“,“BASIC“, “Great Wall“,“FORTRAN“,“Computer Design“ ; int n=5; sort(name,n); print(name,n); return 0; ,void sort(char *name ,int n) char *temp; int i,j,k; for(i=0;in-1

38、;i+) k=i; for(j=i+1;jn;j+) if(strcmp(namek,namej)0) k=j; if(k!=i) temp=namei; namei=namek; namek=temp; ,void print(char *name ,int n) int i; for(i=0;in;i+) printf(“%sn“,namei); ,BASIC Computer Design FORTRAN Follow me Great all,8.7.2 指向指针的指针,定义形式: char *p;,#include int main() int a=10; int *p,*p1; p

39、= ,a,p,p1,10,&a,&p,例8.28 使用指向指针的指针。 #include int main() char *name=“Follow me“,“BASIC“, “Great Wall“,“FORTRAN“,“Computer Design“; char *p; int i; for(i=0;i5;i+) p=name+i; printf(“%sn“,*p); return 0; ,Follow me BASIC FORTRAN Great all Computer Design,8.7.3 指针数组作main函数的形参(上机自学),回第八章,以下程序的运行结果是:,(1) #i

40、nclude int main() int a=1,2,3,4,5,6,7,8,9,0, *p; p=a; printf(”%dn”,*p+9) ; return 0;,10,(2) #include int main() int arr=30,25,20,15,10,5,*p=arr; p+; printf(”%dn”,*(p+3); return 0;,10,以下程序的运行结果是:,(3) #include int main() char s=”9876”, *p; for(p=s;ps+2;p+) printf(”%sn”,p); return 0;,9876 876,(4) #include int main() char *s=”one”,”two”,”three”,*p; p=s1; printf(”%c,%sn”,*(p+1),s0); return 0; ,w,one,

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

当前位置:首页 > 其他


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