




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、指针,C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值,/17,指针的概念,变量与地址,程序中: int i; float k;,内存中每个字节有一个编号-地址,i,k,编译或函数调用时为其分配内存单元,变量是对程序中数据 存储空间的抽象,指针:一个变量的地址 指针变量:专门存放变量地址的变量,2000,指针,指针变量,变量的内容,变量的地址,指针与指针变量, -直接访问,*i_pointer=20; -间接访问,3,20,k=i; -直接访问 k=*i_pointer; - -间接访问,指针变量,指针变量与其所指向的变量之间
2、的关系,指针变量的定义 数据类型 *指针名;,合法标识符,指针的目标变量的数据类型,表示定义指针变量,例 int *p1,*p2; float *q ; char *name;,指针变量,/17,注意: 1、int *p1, *p2; 与 int *p1, p2的区别; 2、指针变量名是p1、p2 ,不是*p1、*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值,例 int *p= ,指针变量的初始化,指针变量的初始化 数据类型 *指针名=初始地址值;,例 int i; int *p=,变量必须与已说明过 类型应一致,例 int i; int
3、 *p=,可以用已初始化的指针变量作初值,变量必须用已存在的变量来初始化,例 float i; int *p= ,例 main( ) int i=10; int *p; *p=i; printf(“%d”,*p); ,危险!,例 main( ) int i=10,k; int *p; p= ,先赋值,再使用,指针变量的初始化,main() int a; int *pa= ,运行结果: 10 10 f86 f86 f88,指针变量举例,例 输入两个数,并使其从大到小输出,main() int *p1,*p2,*p,a,b; scanf(%d,%d, ,运行结果:a=5,b=9 max=9,min
4、=5,指针变量举例,阅读程序,分析运行结果,#include main() int a,b,*p1,*p2; a=b=3; p1= ,/17,运行结果: 8,5,函数参数的求值顺序为从右向左,先求*p1,再求a+b,故结果不是6,5,指针和数组,指针的应用与数组是密不可分的。 数组a的指针是指数组a的起始地址,即int *p=a;,实际上,下标表达式ai就是按照指针表达式*(a+i)定义的。,指向数组的指针变量的赋值方法,方法1:在定义指针变量时赋值。 int a10,*p=a; 方法2:在定义指针变量后赋值。 int a10,*p; p=a; 结果:p是数组a的指针,指向a 数组的第一个元素
5、a0的首地址 main() int i,a6=0,1,2,3,4,5,*p; p=a; for(i=0;i6;i+) printf(%d ,ai); ,可替换为*(a+i)或*(p+i),通过带下标的指针变量引用数组元素,指向数组的指针变量也可以带下标 定义了:int a10,*p=a ; 后: 可以使用ai 或pi 或*(a+i) 或*(p+i) 这4种方法引用a数组中的第i个元素。 注意:这些方法都不造成指针p的移动。,输出数组元素四种方法,main () int a10=10,9,8,7,6,5,4,3,2,1,*p,i; p=a; for(i=0;i10;i+) printf(%d ,
6、ai); putch(n); for(i=0;i10;i+) printf(%d ,pi); putch(n); for(i=0;i10;i+) printf(%d ,*(a+i); putch(n); for(i=0;i10;i+) printf(%d ,*(p+i); ,程序举例,#include main() char a =abcdef; char *p; p=a; *(p+2)+=3; printf(%c,%cn,*p,*(p+2); ,/17,运行结果: a,f,1. 指针的赋值运算 p= (指针变量p2值p1) 不能把一个整数p,也不能把p的值整型变量,1,指针 变量的运算,/1
7、7,2. 指针的算术运算: pi pid (i为整型数,d为p指向的变量所占字节数) p+, p-, p+i, p-i, p+=i, p-=i等 若p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d p1+p2 无意义,指针 变量的运算,例 p指向float数,则 p+1 p+1 4,例 p指向int型数组,且p= 则p+1 指向a1,例 int a10; int *p=,例 int a10; int *p1=,1,指针 变量的运算,3. 指针变量的关系运算 若p1和p2指向同一数组,则 p1p2 表示p1指的元素在后 p1=p2 表示p1与p2指向同一元素 若p1与p2不
8、指向同一数组,比较无意义 p=NULL或p!=NULL,指针 变量的运算,通过指针的算术运算引用数组元素,指向数组的指针可以指向数组中的其它元素。 main() int a10=2,4,5,8; int *p=a; /p指向a0 printf(%4d,*p+); /输出a0,p指向a1 printf(%4d,*p+); /输出a1,p指向a2 printf(%4d,*p+); /输出a2,p指向a3 printf(%4d,*p+); /输出a3,p指向a4 运行结果是: 2 4 5 8,用*p+遍历整个数组,main() int a=9,8,7,6,5,4,3,2,1,0,*p=a,i; fo
9、r(i=0;isizeof(a)/sizeof(int);i+) printf(%d ,*p+ ); 注意: 这种方法造成了指针p的移动。,运行结果是: 9 8 7 6 5 4 3 2 1 0,同样,可以用p+和地址偏移量遍历整个数组 main () int a10=9,8,7,6,5,4,3,2,1,0,*p; for (p=a;p-a10;p+) printf(%d,*p); ,运行结果: 9,8,7,6,5,4,3,2,1, 其中p中存放的是地址,p-a10表示p单元中的值减去数组a的首地址所得的单元数不超过10。 注意: 这种方法也造成了指针p的移动,用p+与地址偏移量遍历整个数组,利
10、用指针变量对数组元素赋值,通过指针变量p实现数组元素的赋值: int a5,*p=a,i; for(i=0;i5;i+) printf(a%d= ,i); scanf(%d, ,可替换成 p-a5;p+) printf(a%d= ,p-a); scanf(%d,p); ,在程序中使用指针变量时应当注意,常见的指针变量运算 *(+p) 先移指针,取出下一个单元的值。 *(p+) 先取出当前单元的值,再移指针。 (*p)+ 先取出当前单元值,再使当前单元加1。 不移指针。 +(*p) 先使前单元的值加1,再取出。不移指针。 注意:* p+和*(p+)是等价的。 数组和指针的统一性是C语言的长处之一
11、。用指针可以很方便地访问数组和模拟动态分配的数组。但是,说数组和指针等价并不表示它们相同,甚至也不能互换。“等价”的意思是:指针算术和数组下标运算等价,指针和数组是不同的。(Wayne Throop),在程序中使用指针变量时应当注意, 指针的变化 + - 使指针按它所指向的类型所规定的字节数在内存区中移动(跳动而不是滑动)。 指针变量的运算 +和*是同优先级,从右至左的结合方向。 * p+和*(p+)等价 * +p和*(+p)等价 (* p)+表示p所指向的元素值加1。,总结:数组遍历的6种方法,造成指针p的移动的2种方法(p必须初始化) *p+ p+ 配合 *p 不造成指针p的移动的4种方法
12、 *(p+i) pi *(a+i) ai 数组在C语言中是个二等公民:不能作为整体操作数组。但将指针变量指向一个数组后,就可以用对指针变量的操作去整体操作一个数组了。,遍历数组时指针的移动,在用指针变量遍历数组时,要特别注意指针是否移动。 main () int *p,i,x10=10,9,8,7,6,5,4,3,2,1; p=x; for (i=0;i10;i+) printf(%d,*p+); printf(n); for (i=0;i10;i+) printf(%d,*p+); 运行时并没有显示二行相同的 9,8,7,6,5,4,3,2,1,0,输出值发生错误,为什么? 实际上, 把*p
13、+换成*(p+i), 也可以避免出错。为什么?,第一个循环后p已经指向数组x的末尾。在第二个for循环开始后,发生错误,应该将在第二个for循环语句前加一句:p=x;,在C语言中有两种方法用指针变量表示一个字符串:,在右例中:字符指针p只存放地址,而字串内容放在内存中另一地方,字串可被再次赋值:p=“hello world”;这种做法称为: p指向了一个无名的字符数组。,字符串和指针,直接使用字符指针表示字串时,可以输出和被赋值,但不可用gets()函数输入一个新的字串。下面这个程序会出现运行时错(Run error): main() char *p; p=HELLO WORLD;puts(p
14、); p=Hello world;puts(p); gets(p);/无名字符数组不能用于gets()函数 puts(p); ,字符串和指针,通常做法是:定义一个字符型指针并将它指向一个字符型数组,然后用对指针的操作代替对数组和数组元素的操作。,main () char a100,*p=a; int i; printf(输入一个字串:);gets(p); puts(p); /方法1 printf(%sn,p); /方法2 for(p=a;*p!=0;p+) /方法3:引用指针变量所指字符串中字符 printf(%c,*p); getch(); ,用指针变量输出一个字符串的三种方法,main() char a100,b100,*p=a,*q=b,*t; gets(p);gets(q); t=p,p=q,q=t; /第三者插足法 puts(p);puts(q); ,例: 以字符串指针实现字符串的交换,不用指针的字串交换程序: main() char a100,b100,t100; gets(a);gets(b); strcpy(t,a);strcpy(a,b);strcpy(b,t); puts(a);puts(b); ,将字符串中的字母排序存放后输出,main() int i,j,n; char t,a80; printf(输入一个字
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教育技术革新博士的实践与未来趋势
- 教育的科技革新与法权保护同行
- 抖音商户自然流量增长策略制度
- 全球汽车零部件制造行业智能化生产线布局与趋势分析报告
- BuChE-IN-21-生命科学试剂-MCE
- 广东机电职业技术学院《知识产权专业英语》2023-2024学年第一学期期末试卷
- 2024年湖北省枣阳市吴店镇清潭第一中学七年级数学第一学期期末调研模拟试题含解析
- 湖南电子科技职业学院《综合设计实务(3)》2023-2024学年第一学期期末试卷
- 辽宁省盘锦市双台子区第四中学2024年化学九上期末学业水平测试试题含解析
- 可克达拉职业技术学院《外事礼仪》2023-2024学年第一学期期末试卷
- 海姆立克评分标准
- 碳汇经济与政策智慧树知到期末考试答案章节答案2024年浙江农林大学
- T-SHNA 0002-2023 泪道冲洗操作规范
- 老年患者风险评估及安全管理
- 安全事故案例警示教育培训
- 散打说课课件
- 面馆开店投资 项目融资计划书
- 车体-罐车(车辆构造检修课件)
- 草鱼高效养殖模式与技术
- 肾骨片产品课件
- 幼师应聘个人简历表格
评论
0/150
提交评论