第7章指针ppt课件.ppt

上传人:本田雅阁 文档编号:3131733 上传时间:2019-07-14 格式:PPT 页数:67 大小:315.52KB
返回 下载 相关 举报
第7章指针ppt课件.ppt_第1页
第1页 / 共67页
第7章指针ppt课件.ppt_第2页
第2页 / 共67页
第7章指针ppt课件.ppt_第3页
第3页 / 共67页
第7章指针ppt课件.ppt_第4页
第4页 / 共67页
第7章指针ppt课件.ppt_第5页
第5页 / 共67页
点击查看更多>>
资源描述

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

1、第7章 指 针,C语言程序设计 - 第7章 指针,2,目 录,指针概念 指针变量和指针运算 指向数组的指针 指向字符串的指针 指向函数的指针 返回指针值的函数 指针数组和指向指针的指针,C语言程序设计 - 第7章 指针,3,指针 (Pointer),指针表示变量等的存储地址 使用指针可以获得紧凑、高效的代码 使用指针也可能使程序晦涩难懂 指针的使用灵活方便 指针操作容易出错且难以调试 指针与数组关系密切,C语言程序设计 - 第7章 指针,4,指针与地址,地址 通过首地址和数据类型可以访问内存中某一数据 数据类型决定所占用存储单元数 指针 就是地址 和类型有关,C语言程序设计 - 第7章 指针,

2、5,指针变量和指针运算,变量的指针和指针变量 指针变量的定义 地址运算符和指针运算符 指针变量的引用 指针的运算,C语言程序设计 - 第7章 指针,6,变量的指针和指针变量,变量的指针 内存中存储某个变量的存储单元的首地址 指针(地址)实质上是一个整数(不是C的整型) 可以通过变量的地址来间接的访问变量 指针变量 指针(地址)是一个数据,也可以用另一个变量来存放,即指针变量 通过指针变量可以间接访问变量或内存数据,C语言程序设计 - 第7章 指针,7,指针变量的定义,一般形式 基类型 *指针变量名; 说明 “基类型”表示该指针指向的数据的类型 可以定义基类型为空类型void的指针变量 举例 i

3、nt *pi; char *pc1, c, *pc2; void *p;,C语言程序设计 - 第7章 指针,8,地址运算符 (Address Operator),地址运算符 ,C语言程序设计 - 第7章 指针,9,指针运算符 (Indirection Operator),指针运算符 * 获得指针指向的内存数据 又称“间接访问运算符” 单目运算符,自右向左结合,优先级较高 操作数为具有指针(地址)意义的值 举例 int i, *p= */,C语言程序设计 - 第7章 指针,10,指针变量的引用,指针变量也要“先赋值,后使用” 没有赋值的指针变量所存储的地址数据是不确定的,对它的引用非常危险 对指

4、针的赋值要注意类型匹配,必要时可以使用强制类型转换,但要慎重使用 *p可以用于与指针p的基类型相同类型的变量可以使用的任何场合 指针变量可以作为函数的参数,C语言程序设计 - 第7章 指针,11,指针变量引用举例 (07-01.C),int a, b, c, *pa, *pb, *pc; pa = /* c=34 */,C语言程序设计 - 第7章 指针,12,指针变量与所指变量的关系,10,20,pa,pb,a,b,int a, b; int *pa, *pb;,pa = ,*pa = 10; b = 20;,pa = pb;,pb = ,&a,&*pa,*pa,*&a,C语言程序设计 - 第

5、7章 指针,13,指针变量作为函数参数,参数传递 仍然遵循“单向值传递”的规则 这里的传递规则是指针类型参数的值的传递 作为参数的指针型实参的值不会改变 但是对指针型实参所指向的内存数据所作的操作将不会随函数的返回而恢复 用途 借助指针类型参数可以改变多个数据的值,C语言程序设计 - 第7章 指针,14,指针类型函数参数举例 (07-02.C),void swap(int *x, int *y) int t; t=*x, *x=*y, *y=t; void main() int a=1, b=4; int *pa, *pb; pa= ,&a,a,&b,pb,1,4,4,1,b,pa,&a,&b

6、,y,x,参数传递,C语言程序设计 - 第7章 指针,15,指针的运算,运算类型 算术运算:加、减、自增、自减 关系运算:所有关系运算 赋值运算:一般赋值、加赋值、减赋值 上述运算在一定约束条件下才有意义(后详) 变量说明 p,q是同类型的指针变量 n是整型变量,C语言程序设计 - 第7章 指针,16,指针的算术运算,条件:p,q是指向同一数据集合(数组)的指针 注意避免数组越界,C语言程序设计 - 第7章 指针,17,指针的关系运算,条件 p,q是指向同一数据集合(数组)的指针 运算方式 p=q、pq pq:判断p所指元素是否在q所指元素之前 其他运算的含义与上述类似 若p,q不是指向同一数

7、据集合的指针,则运算无意义,C语言程序设计 - 第7章 指针,18,指针的赋值运算,条件 p,q是指向同一数据类型的指针 n是整型数据 有意义的赋值方式 p=q p=q+n、p=q-n (要求q指向数组) p+=n、p-=n (要求p指向数组) 注意避免数组越界,C语言程序设计 - 第7章 指针,19,指针的运算说明,指针的运算还包括 指针运算 对指向数组的指针的下标运算 对指针变量的取地址运算 对指向结构体的指针的指向成员运算 除上述运算方式(包括约束条件)外的其他运算都没有意义 无意义的指针运算不一定会出现语法错误,但可能造成危险的操作,C语言程序设计 - 第7章 指针,20,指针的运算举

8、例,short a5, *p, *q; p = ,C语言程序设计 - 第7章 指针,21,指向数组的指针,指针与数组的关系 指向数组的指针 通过指针引用数组元素 数组用作函数参数 指向二维数组的指针,C语言程序设计 - 第7章 指针,22,指针与数组的关系,数组名是“常量指针” 数组名表示数组的首地址,因此数组名也是一种指针(地址) 数组名表示的地址(指针)不能被修改,所以称之为“常量指针” 数组的指针 数组的起始地址 与数组名表示的指针相同 与数组的第一个元素(a0)的地址相同,C语言程序设计 - 第7章 指针,23,数组和指针的用法,数组名不能被赋值和修改,若指针指向数组,则两者的其他用法

9、基本相同 定义指针时,只分配一段用来存放地址的空间,而没有分配存放数据的空间 定义数组时,为所有元素分配相应的连续的存储空间,但没有存放地址的空间 指针应赋值后才能使用 数组名不能被赋值,可以直接使用,C语言程序设计 - 第7章 指针,24,指向数组的指针,char a10, *p; p = ,a,p,&a0,C语言程序设计 - 第7章 指针,25,通过指针引用数组元素,当一个指针变量指向数组或某个数组元素时,可以通过这个指针变量引用所有的数组元素 引用数组元素的方法 下标运算符,例如ai、pi 指针运算符*,例如*(a+i)、*(p+i) 注意数组名不能被修改和赋值 注意防止下标越界,C语言

10、程序设计 - 第7章 指针,26,通过指针引用数组元素图示,p0, *p, *a,p, a,p+1, a+1,p1, *(p+1), *(a+1),q+i-2, p+i, a+i,pi, *(p+i), *(a+i) qi-2, *(q+i-2),p+9, a+9,p9, *(p+9), *(a+9),q, p+2, a+2,p2, *(p+2), *(a+2) q0, *q,C语言程序设计 - 第7章 指针,27,数组名和指针引用数组元素比较 (1),指针指向数组首地址 前提条件:int a10, *p=a; ai、pi、*(a+i)、*(p+i)等用法都是合法的,且它们都表示同一个数组元素

11、 a+i(或p+i)不是简单的在a(或p)表示的地址值上简单的加i,而是加上i个基类型所需的地址偏移量,即加上i*sizeof(int) 指针值可以改变,如p+为下一元素的地址 数组名的值不能修改,如a+是非法操作,C语言程序设计 - 第7章 指针,28,数组名和指针引用数组元素比较 (2),指针指向某个数组元素 前提条件:p=a+i; *(p+)与ai+等价 *(p-)与ai-等价 *(+p)与a+i等价 *(-p)与a-i等价 注意不能使用*(a+)或a=p+i这种形式 注意区分运算顺序,*(p+)与(*p)+ 注意防止下标越界,注意掌握指针位置,C语言程序设计 - 第7章 指针,29,通

12、过指针引用数组元素举例,int a10, i, *p; p = a; /* 指针需要先赋值 */ while (pa+10) /* 指针在数组范围内移动 */ scanf(“%d“, p+); /* 指针向下移动 */ p = a; /* 指针指向正确位置 */ for (i=0; i10; i+) printf(“%d“, pi); /* 指针使用 */,C语言程序设计 - 第7章 指针,30,数组用作函数参数,数组元素用作函数实参 与同类型的一般变量用法相同 数组用作函数参数 数组类型可以作为函数参数类型 数组可以用作函数的形参和实参 定义函数时,数组型形参实际上作为指针型形参处理,实参可

13、用相同类型的数组或指针 声明数组类型形参时,不需要指定数组长度 一般应把数组长度作为另一个参数传递,C语言程序设计 - 第7章 指针,31,以数组作为实参的几种方法 (1),形参用数组名 实参用数组名,形参用指针变量 实参用数组名,f(int x, int n) . . main() int a10; . . f(a, 10); ,f(int *x, int n) . . main() int a10; . . f(a, 10); ,C语言程序设计 - 第7章 指针,32,以数组作为实参的几种方法 (2),形参用数组名 实参用指针变量,形参用指针变量 实参用指针变量,f(int x, int

14、n) . . main() int a10, *p=a; . . f(p, 10); ,f(int *x, int n) . . main() int a10, *p=a; . . f(p, 10); ,C语言程序设计 - 第7章 指针,33,数组用作函数参数举例,选择排序法,C语言程序设计 - 第7章 指针,34,例1:选择排序法 (07-03.C),void sort(int x, int n) /* int *x */ int i, j, k, t; for (i=0; ixk) k=j; if (k!=i) t=xi,xi=xk,xk=t; ,C语言程序设计 - 第7章 指针,35,例

15、1:选择排序法 (续),void main() int a10, *p, i; p = a; for (i=0; i10; i+) scanf(“%d“, p+); p = a; sort(p, 10); /* sort(a, 10); */ for (p=a,i=0; i10; i+) printf(“%d“, *p+); ,C语言程序设计 - 第7章 指针,36,指向二维数组的指针 (1),char a34;,*a,*(a+1),*(a+2),a、a+1、a+2都是指针,它们的基类型是长度为4的字符数组,它们与下面定义的指针p同类型 char (*p)4;,C语言程序设计 - 第7章 指针

16、,37,指向二维数组的指针 (2),a0,a1,a2,a13 *(*(a+1)+3),a23 *(*(a+2)+3),a03 *(*a+3),char *,char,char *,基类型为 char4 的指针,C语言程序设计 - 第7章 指针,38,指向二维数组的指针总结,表示二维数组 a:指向二维数组的指针类型 表示第i行 ai、*(a+i):指向一维数组的指针类型 表示第i行j列的元素 aij、 *(*(a+i)+j) *(ai+j)、(*(a+i)j:char类型 注意a和*a都是指针,但是基类型不同 注意*(a+i)和*a+i的区别,C语言程序设计 - 第7章 指针,39,指向二维数组

17、的指针变量,指向数组元素的指针变量 指向二维数组的元素 类型为 char *p; 根据一维数组元素和二维数组元素的对应关系,可以访问所有的二维数组元素 基类型为一维数组的指针变量 指向二维数组的行 类型为 char (*p)4; 把每一行作为一个一维数组来处理,C语言程序设计 - 第7章 指针,40,指向二维数组元素的指针变量,一维数组与二维数组 char aMN; char aM*N; aij ai*N+j 使用指向元素的指针访问二维数组元素 char aMN; char *p=a0; /* p=*a; */ 则pi*N+j、*(p+i*N+j)、aij 表示二维数组第i行j列的元素,C语言

18、程序设计 - 第7章 指针,41,指向二维数组的行的指针变量,二维数组是基类型为一维数组的指针 可以使用与二维数组同类型的指针变量 使用指向行的指针访问二维数组元素 int aMN; int (*p)N=a; /* p=a; */ 则pi、*(p+i)、ai表示数组的第i行 且pij、*(*(p+i)+j)、*(pi+j)、 (*(p+i)j表示二维数组第i行j列的元素,C语言程序设计 - 第7章 指针,42,二维数组的指针作函数参数,二维数组的地址也可以用作函数参数 用指向数组元素的指针作为参数 用指向二维数组的行的指针作为参数 举例,void foo(int *p, int n); voi

19、d bar(int (*p)4, int n); int a34; /* 定义二维数组 */ foo(*a, 12); /* 二维数组的行作为参数 */ bar(a, 3); /* 二维数组名作为参数 */,C语言程序设计 - 第7章 指针,43,指向字符串的指针,指针指向存放字符串的字符数组 与前述“指向数组的指针”类似 直接用字符指针指向字符串 字符串常量按字符数组处理,在存储器中占有一定的空间,并有自己的地址(指针) 可以把字符串常量的地址赋给字符指针变量 通过这个字符指针变量可以修改字符串常量 两个内容完全一样的字符串常量,在存储器中是不同的字符串,具有不同的存储空间,C语言程序设计

20、- 第7章 指针,44,直接用字符指针指向字符串,可以用字符指针直接指向字符串常量 可以用字符串常量对字符指针直接赋值 这是把字符串常量的地址赋给字符指针 而不是把字符串的内容赋给字符指针 使用字符指针可以修改字符串的内容 只有利用指针才能再次访问某字符串常量 注意防止越过原字符串常量的范围 注意字符串末尾应保留结束标志0,C语言程序设计 - 第7章 指针,45,字符串指针举例,char *s=“I love“; char *t; t = “China!“; s0 = U; puts(s); /* U love */ s6 = ; puts(s); /* U loveChina! */ s12

21、 =; puts(t); /* China */,s0,s6,s12,U,C语言程序设计 - 第7章 指针,46,字符串指针作函数参数举例,void strcpy(char *s, char *t) while(*t+=*s+); /* 逐个字符复制 */ void main() char *str1=“C Language“, str220; strcpy(str1, str2); puts(str2); /* C Language */ ,C语言程序设计 - 第7章 指针,47,字符数组和字符指针变量比较 (1),定义 char astr=“Hello, World!“; char *ps

22、tr=“Hello, World!“; 数组在定义时分配存放若干字符的空间 指针定义时只分配存放一个地址的空间,Hello, World!0,astr:,C语言程序设计 - 第7章 指针,48,字符数组和字符指针变量比较 (2),数组可以直接使用 指针要先指向一个字符串后才能使用 字符串常量只能对数组赋初值,把字符串的各个字符放到数组中,并且不能在其他场合对数组整体赋值 指针可以用字符串常量或字符数组任意赋值,但只是把字符串的地址赋给指针 数组名的值不能修改 指针可以任意修改,C语言程序设计 - 第7章 指针,49,指向函数的指针,函数的指令存储在内存中的一段空间中 函数也有相应的内存地址 函

23、数的入口地址就是函数的指针 函数名代表函数的入口地址 函数的指针可以用相应类型的指针变量表示,即指向函数的指针变量 函数也可以用通过指针变量间接调用,C语言程序设计 - 第7章 指针,50,指向函数的指针变量,定义形式 类型 (*变量名)(参数类型列表); 说明 与函数原型类似,函数名用(*变量名)代替 “参数类型列表”可以省略,但一般不要省略 主要用于函数的参数 先赋值,后使用,一般用同类型函数名赋值 不能进行算术运算和关系运算,C语言程序设计 - 第7章 指针,51,指向函数的指针变量使用举例,int max(int x, int y) return xy?x:y; void main()

24、 int (*p)(int, int); /* 定义指针变量 */ int a, b, c; scanf(“%d%d“, */ ,C语言程序设计 - 第7章 指针,52,指向函数的指针用作函数参数举例,一元函数定积分的梯形法数值求解,C语言程序设计 - 第7章 指针,53,例:一元函数定积分 (07-04.C),double integral(double (*f)(double), double a, double b) double s, h; int n=100, i; h = (b-a)/n; s = (*f)(a)+(*f)(b)/2.0; for(i=1; in; i+) s +=

25、 (*f)(a+i*h); return s*h; ,C语言程序设计 - 第7章 指针,54,例:一元函数定积分 (续),#include #include void main() double y1, y2, y3; y1 = integral(sin, 0.0, 1.0); y2 = integral(cos, 0.0, 2.0); y3 = integral(exp, 0.0, 3.5); printf(“%lfn%lfn%lfn“, y1,y2,y3); ,C语言程序设计 - 第7章 指针,55,返回指针值的函数,函数的返回值可以是指针类型 定义形式 类型 *函数名(参数列表); 举例

26、 int *foo(int x, int y); 说明 函数调用可以结合使用*和运算符 注意与指向函数的指针区别 int (*foo)(int x, int y);,C语言程序设计 - 第7章 指针,56,返回指针值的函数举例 (1),int *f(int *px, int *py) /* 返回整型指针 */ return *px*py?px:py; /* 较大数的地址 */ void main() int a=2, b=3, c=9; *f( /* 输出9 */ ,C语言程序设计 - 第7章 指针,57,返回指针值的函数举例 (2),int *f(int *a, int *b) /* 返回整

27、型指针 */ return *a*b?a:b; /* 返回第一个元素 */ /* 较大的数组地址 */ void main() int i, a=1,2,3,4, b=5,6,7,8; for (i=0; i4; i+) printf(“%dn“, f(a,b)i); /* 打印数组b的元素 */,C语言程序设计 - 第7章 指针,58,指针数组和指向指针的指针,指针数组 类型 *数组名长度; 元素是指针类型的数组 举例,char *p4; 注意与基类型为数组的指针区分 char (*p)4; 指向指针的指针 基类型为指针类型的指针 举例,char *p;,C语言程序设计 - 第7章 指针,5

28、9,指针数组举例,/* 把所有名字的所有字母全部改成大写 */ void main() char *name=“Tom“, “John“, “Kate“; int i, j; for (i=0; i=a ,C语言程序设计 - 第7章 指针,60,指向指针的指针举例,/* 利用指向字符指针的指针打印字符串数组 */ void main() char *name=“Tom“, “John“, “Kate“; char *p; int i; p = name; for (i=0; i3; i+) printf(“%sn“, *p+); ,C语言程序设计 - 第7章 指针,61,命令行参数,main函

29、数的几种形式 int main(); int main(int argc, char *argv); int main(int argc, char *argv); 说明 返回值类型一般为int,也可以是其他类型 argc为命令行参数的个数 argv为命令行参数字符串数组 命令行参数包括文件名本身,C语言程序设计 - 第7章 指针,62,命令行参数举例echo命令,echo C Language argc = 3; argv0 = “echo“; argv1 = “C“; argv2 = “Language“;,#include int main(int argc, char *argv) w

30、hile(-argc 0) printf(“%s%c“, *+argv, (argc1)? :n); return 0; ,C语言程序设计 - 第7章 指针,63,复杂的声明形式,复杂类型变量的声明容易混淆 指针数组和指向数组的指针 int *a5; int (*a)5; 指向函数的指针和返回指针值的函数 void (*f)(); void *f(); 过于复杂的声明形式使程序晦涩难懂,而且容易出错 可以用typedef关键字把复杂类型的变量声明用若干个容易理解的小步骤表示,C语言程序设计 - 第7章 指针,64,分析声明形式的方法,从标识符开始,逐层分析其意义 按运算符优先级和结合方向的顺序

31、进行 可能涉及的运算符包括 ()自左向右结合 改变结合顺序;或声明一个函数,向外一层是函数返回值类型声明 自左向右结合 声明一个数组,向外一层是数组元素类型声明 * 自右向左结合 声明一个指针类型,向外一层是指针基类型声明,C语言程序设计 - 第7章 指针,65,声明形式分析举例,char (*(*x3)()5;,x is an array3 of pointer to function returning pointer to array5 of char,C语言程序设计 - 第7章 指针,66,void类型指针,定义形式 void *p; 说明 定义一个指针,但不指定它指向的数据类型 不能通过*p引用它指向的数据 void*指针可以与其他任何类型的指针相互赋值和比较,而不需要显式的强制类型转换 经常作为函数形参和返回值的类型,C语言程序设计 - 第7章 指针,67,结束,The End,

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

当前位置:首页 > 其他


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