C语言指针第讲课件_第1页
C语言指针第讲课件_第2页
C语言指针第讲课件_第3页
C语言指针第讲课件_第4页
C语言指针第讲课件_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、内容提要指针概述指针的概念为什么引入指针的概念指针变量作为函数参数字符指针作为函数参数指针和数组间的关系一维数组的地址和指针二维数组的地址和指针第1页,共49页。为什么引入指针的概念铁杆C/C+程序员最挚爱的武器:指针C/C+的高效、高能主要来自于指针很多不可能的任务由指针完成 第2页,共49页。为什么引入指针的概念 指针为函数提供修改变量值的手段 为C的动态内存分配系统提供支持 为动态数据结构(如例链表、队列、二叉树等)提供支持 可以改善某些子程序的效率 第3页,共49页。内存的寻址方式如何读写内存中的数据?通过变量的地址访问变量所在的存储单元两种寻址方式直接(寻址)访问通过变量地址直接存取

2、变量内容间接(寻址)访问通过指针变量来间接存取它所指向的变量i_pointer=&i;第4页,共49页。指针(Pointer)的概念指针也是一种数据类型指针变量 声明为指针类型的变量,专门存放地址数据的变量 第5页,共49页。如何定义指针变量?定义指针变量int *p;定义了一个指针变量p,简称指针pp是变量,int*是类型指针变量初始化int *p,a;p = &a;*p 与 a 完全等价第6页,共49页。int i,*p;p=&i; int *p;float *q;p=q;int i;float *p;p=&i;int *p;p=100;判断是真?是假?指针变量只存放地址!一个指针变量不能

3、指向与其类型不同的变量!我是真的,你猜对了吗?应在类型相同的指针变量之间赋值第7页,共49页。&与*操作符&用来取变量的地址*用来取指针指向的内存中的内容int *p, a10;p = &a0;*p=20;int *p, a10;p = &a5;*p=20;int i=3, *p;p = &i;printf(“*p=%d”,*p);int *p, a10;p = a;*p=20; 等价于a0=20;第8页,共49页。指针变量与其它类型变量的对比共性在内存中占据一定大小的存储单元先定义,后使用特殊性 它的内容只能是地址,而不能是数据必须初始化后才能使用,否则指向不确定的存储单元,对该空间进行访问

4、,将可能造成危险可参与的运算:加、减一个整数,自增、自减、关系、赋值只能指向同一基类型的变量第9页,共49页。指针的指向只能指向同一基类型的变量,否则将引起warningfloat x; int *p = &x;TC编译warning: Suspicious pointer conversion in function mainVC编译warning C4133: = : incompatible types - from float * to int *第10页,共49页。指针运算算术运算short *p, a10; p = a; p+; /*p的值增加多少?*/指针的加减运算是以其指向的类

5、型的字节长度为单位的6000600160026003600460056006p-1pp+1第11页,共49页。指针运算int *p, *q, a10;p = a;q = &a5;q - p q = p + 5;指针运算不能乱算一般只进行指针和整数的加减运算,同类型指针之间的减法运算其它运算,比如乘法、除法、浮点运算、指针之间的加法等,并无意义,所以也不支持第12页,共49页。指针运算关系运算指向同一种数据类型的两个指针才能进行关系运算值为1或0p q p q p = q不能与非指针类型变量进行比较,但可与NULL(即0值)进行等或不等的关系运算判断p是否为空指针P = NULLp != NUL

6、L第13页,共49页。指针运算赋值运算指针在使用前一定要赋值为指针变量赋的值必须是一个地址main() int *p; scanf(%d,p); main() int a,*p=&a; scanf(%d,p); 错!但TC下不报错VC下报错第14页,共49页。指针与函数指针既然是数据类型,自然可以做函数参数和返回值的类型指针做函数参数的经典例子:两数的互换第15页,共49页。void Swap(int *x,int *y) int temp; temp = *x; *x = *y; *y = temp;main() int a, b; a = 15; b = 8; Swap( &a, &b )

7、; printf(a=%d,b=%d,a,b);void Swap(int x,int y) int temp; temp = x; x = y; y = temp;main() int a, b; a = 15; b = 8; Swap(a, b); printf(a=%d,b=%d,a,b);程序 1程序 2 例7.17.2:编写函数实现两数的互换主调函数被调函数实 参形 参结果有何不同?Not Work!Why?第16页,共49页。主调函数被调函数main() int a, b; a = 15; b = 8; Swap(a, b); printf(a=%d,b=%d,a,b);void

8、Swap(int x, int y) int temp; temp = x; x = y; y = temp;55ab实 参形 参99xyab程序 1xy55temp9第17页,共49页。主调函数被调函数main() int a, b; a = 15; b = 8; Swap(&a, &b); printf(a=%d,b=%d,a,b);void Swap(int *x, int *y) int temp; temp = *x; *x = *y; *y = temp;&a&a实 参形 参&b&bxyab程序 2xy5temp5ab995第18页,共49页。简单变量作函数参数与指针变量作函数参数

9、的比较15 815 815 81515 8815 81515a) 调用Swap函数(b)执行Swap函数c) 从Swap函数返回temp xy bmain函数Swap函数aaatemptempxxy y bb1588 15&a&b&a&b15(a) 调用Swap函数 (b) 执行Swap函数 a a b b *x *x *y *y y y x x &a &b main函数 Swap函数 temptemp第19页,共49页。swap函数的几种错误形式(1/3)参数单向传递void Swap(int x, int y) int temp; temp = x; /*x,y为内部变量*/ x = y;

10、 y = temp;第20页,共49页。swap函数的几种错误形式(2/3)参数单向传递void Swap(int *p1, int *p2) int *p; p = p1; /*p1,p2为内部变量*/ p1 = p2; p2 = p; 第21页,共49页。swap函数的几种错误形式(3/3)指针p没有确切地址void Swap(int *p1, int *p2) int *p; /*指针p未初始化*/ *p = *p1; *p1 = *p2; *p2 = *p; 第22页,共49页。字符串与字符数组、字符指针C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理字符串一

11、串以0结尾的字符字符数组每个元素都是字符类型的数组char string100;字符指针指向字符类型的指针char *p;数组和指针可以等同看待,上面三者本质上是一回事第23页,共49页。字符指针变量与字符数组的区别定义方法不同 char str10; char *ptr;赋值方法不同 char str10; str = ”china”; /*错误*/ strcpy(str,”china”); /*正确*/ char *ptr; ptr = ”china”;字符指针是变量,而数组名是地址常量第24页,共49页。使用字符指针的注意事项字符指针变量必须有明确的指向,否则使用是危险的例如,输入字符串

12、时 char *a; scanf(%s, a); /*错误*/ 应为: char *a; char str10; a = str; scanf(%s, a); /*正确*/第25页,共49页。例7.5 :字符串拷贝用字符数组编程void MyStrcpy(char dstStr, char srcStr)int i = 0; while (srcStri != 0) dstStri = srcStri; i+; dstStri = 0;下标: 0 1 2 3 4 5 6 7 8 9 10 11 HelloChina0HelloChina0srcStridstStri下标移动方向dstStri=

13、0srcStrdstStr结束拷贝ii+ i 第26页,共49页。void MyStrcpy(char *dstStr, const char *srcStr)while (*srcStr != 0) *dstStr = *srcStr; srcStr+; dstStr+; *dstStr = 0; 当只允许函数访问地址内容,不允许修改时,可以把函数的指针参数定义为constHelloChina0HelloChina0*srcStr*dstStr指针移动方向指针移动方向*to=0dstStrsrcStr+srcStrsrcStrdstStr+dstStr例7.5 :字符串拷贝用字符指针编程第2

14、7页,共49页。例7.5 :字符串拷贝主函数程序#include main()char a80, b80;printf(“Please enter a string:”);gets(a);MyStrcpy(b,a);printf(“The copy is:”); puts(b);第28页,共49页。例7.6 :计算实际字符个数 unsigned int MyStrlen(char str) int i;unsigned int len = 0; for (i=0; stri!=0; i+) len+; return (len); unsigned int MyStrlen(char *pStr

15、) unsigned int len = 0; for (; *pStr!=0; pStr+) len+; return (len); 方法2:用字符指针实现方法1:用字符数组实现第29页,共49页。指针与数组数组名就是一个指针只是不能修改这个指针的指向可以定义函数的参数为数组指针也可当作数组名使用short *p, a10;p = a;数组元素的几种等价引用形式ai*(a+i)pi*(p+i)60006001600260036004600560066007a0a1a2a3aa+1a+260006001600260036004600560066007a0a1a2a3app+p+第30页,共49

16、页。输入输出数组的全部元素main() int a10; int i; for (i=0; i10; i+) scanf(%d, &ai); for (i=0; i10; i+) printf(%d , ai); 方法1:下标法main() int a10; int *p, i; for (p=a; p(a+10); p+) scanf(%d, p); for (p=a; p(a+10); p+) printf(%d , *p); 方法2:指针法第31页,共49页。例7.7 :插入排序 关键是:找到该插入的位置,然后依次移动插入位置及其后的所有元素腾出这一位置放入待插入的元素 1 3 5 7

17、9a0a1a2a3a4a5插入位置pos x=4x插入前: 1 3 4 5 7 9 x插入后:插入元素xa0a1a2a3a4a5第32页,共49页。例7.7 :插入排序主函数#include #define ARR_SIZE 10void Inseart(int a,int n, int x)main() /*教材268页*/int aARR_SIZE+1, x, i, n; Inseart(a, n, x); /*调用函数 实参a为数组名*/第33页,共49页。例7.7 :插入排序数组作形参void Inseart(int a, int n, int x) int i, pos; for (

18、i=0; (i ai); i+) pos = i; for (i = n-1; i = pos; i-) ai+1 = ai; /*向后移动*/apos = x; /*插入元素x到位置pos*/第34页,共49页。main() /*教材270页*/int aARR_SIZE+1, x, i, n; Inseart(a, n, x); /*调用函数 实参a为数组名*/void Inseart(int *a, int n, int x) /*定义函数,形参a为指针变量*/插入排序方式二第35页,共49页。main() /*教材270页*/int aARR_SIZE+1, x, i, n;int *

19、p = NULL; Inseart(p, n, x); /*调用函数 实参p指针变量*/void Inseart(int a, int n, int x) /*定义函数,形参a为数组*/插入排序方式三第36页,共49页。main() /*教材270页*/int aARR_SIZE+1, x, i, n;int *p = NULL; Inseart(p, n, x); /*调用函数 实参p为指针变量*/void Inseart(int *a, int n, int x) /*定义函数,形参a为指针变量*/插入排序方式4第37页,共49页。例7.7 :插入排序指针作形参void Inseart(i

20、nt *a, int n, int x) int i, pos; for (i=0; (i *(a+i); i+) pos = i; for (i = n-1; i = pos; i-) *(a + i + 1) = *(a + i); /*向后移动*/*(a + pos) = x; /*插入元素x到位置pos*/第38页,共49页。指针与二维数组C语言将二维数组看作一维数组,其每个数组元素又是一个一维数组按行顺序存放所有元素a00a01a02a10a11a12aa0+0a+1a1+0a0+1a0+2&a00&a10&a11a1+1&a12&a01&a02 a00 a0a01a02a10 a1

21、 a11a12 a a1+2int a23;第39页,共49页。例7.8 任意输入英文的星期几,在查找星期表后输出其对应的数字。 char weekDay710 = Sunday, Monday, Tuesday,Wednesday, Thursday, Friday, Saturday; 表7-1 星期表的内容0Sunday1Monday2Tuesday3Wednesday4Thursday5Friday6SaturdayweekDay0weekDay1weekDay2weekDay3weekDay4weekDay5weekDay6Sunday0Monday0Tuesday0Wednesda

22、y0Thursday0Friday0Saturday0第40页,共49页。#include main() int i, pos;int findFlag = 0; char x10;char weekDay10 = Sunday,Monday,Tuesday, Wednesday,Thursday,Friday, Saturday; printf(Please enter a string:);scanf(%s, x); for (i=0; i 7 & !findFlag; i+) if (strcmp(x, weekDayi) = 0) pos = i; findFlag = 1; if (

23、findFlag) printf(%s is %dn, x, pos);else printf(Not found!n);例7.8weekDay0weekDay1weekDay2weekDay3weekDay4weekDay5weekDay6Sunday0Monday0Tuesday0Wednesday0Thursday0Friday0Saturday0 xSunday0第41页,共49页。指针与二维数组a 代表二维数组的首地址,第0行的地址a+i 代表第i行的地址*(a+i) 即 ai 代表第i行第0列的地址*(a+i)+j 即 ai+j 代表第i行第j列的地址*(*(a+i)+j ) 即

24、aij 代表第i行第j列的元素行地址转变成列地址第42页,共49页。指针与二维数组二维数组的指针列指针int *p;p = *a;/用列地址初始化逐个元素查找元素所在位置相对于数组起始地址的偏移量i*n+jfor (i=0; im; i+)for (j=0; jn; j+) printf(%d,*(p+i*n+j);a00a01a02a10a11a12pp+第43页,共49页。指针与二维数组二维数组的指针行指针int (*p)3, a43,*p1;p = a;/用行地址初始化p1=a0 ;/用元素地址初始化先逐行查找元素所在行再在行内逐列查找元素所在位置for (i=0; im; i+)for

25、 (j=0; jn; j+) printf(%d,*(*(p+i)+j);a00a01a02a10a11a12pp+第44页,共49页。例7.3:在一个班级中找出最高分及其学号 void FindMax(float score, long num, int n, float pMaxScore, long pMaxNum) int i;pMaxScore = score0; pMaxNum = num0; for (i=1; i pMaxScore) pMaxScore = scorei; pMaxNum = numi; 能返回这两个值吗?第45页,共49页。例7.3:在一个班级中找出最高分及其学号 void FindMax(float s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论