机设学习课件语言第6章指针_第1页
机设学习课件语言第6章指针_第2页
机设学习课件语言第6章指针_第3页
机设学习课件语言第6章指针_第4页
机设学习课件语言第6章指针_第5页
免费预览已结束,剩余43页可下载查看

付费下载

下载本文档

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

文档简介

1、第六章 指 针1指针 (Pointer)1. 指针概念2. 指针变量和指针运算3. 指向数组的指针4. 指向字符串的指针5. 指针数组和指向指针的指针6. 指针应用程序举例21. 指针的概念指针表示变量等的存储地址使用指针可以获得紧凑、高效的代码使用指针也可能使程序晦涩难懂指针的使用灵活方便指针操作容易出错且难以调试指针与数组关系密切3指针的故事“该程序执行了非法操作,即将关闭”这种错误绝大部分都是指针和数组造成的黑客攻击服务器利用的 bug绝大部分都是指针和数组造成的有些用C的人,尽量避免使用指针4关于指针的原则学习原则复杂的应用也不建议使用Keep it simple and stupid

2、 (KISS)使用原则永远要清楚每个指针指向了哪里永远要清楚每个指针指向的地方存放的是什么5指针与地址地址通过首地址和数据类型可以访问内存中某一数据数据类型决定所占用存储单元数指针就是地址和类型有关61、变量与地址 程序中: short i; float k; 内存中每个字节有一个编号-地址.2000200120022005内存02003ik 编译或函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象指针与地址72、数组与地址 地址内存单元整型数组元素a0整型数组元素a1整型数组元素a2123300030013002300330043005数组与地址对照表 数组名 数据类型 长 度 首地

3、址 a 整型 3 3000程序中:short a3=1,2,3;82. 指针变量和指针运算变量的指针和指针变量指针变量的定义地址运算符和指针运算符指针变量的引用指针的运算9变量的指针和指针变量变量的指针变量的地址,即内存中存储某个变量的存储单元的首地址可以通过变量的地址来间接的访问变量指针变量具有指针类型的变量,专门存放地址数据的变量 通过指针变量可以间接访问变量或内存数据10.2000200420062005short型变量i10变量i_pointer200120022003指针:一个变量的地址指针变量:专门存放变量地址的变量2000指针指针变量 变量的内容 变量的地址指针变量变量变量地址(

4、指针)变量值指向地址存入指针变量变量的指针和指针变量11如何定义指针变量?定义指针变量int *p;定义了一个指针变量p,简称指针pp是变量,int* 是类型p里保存一个地址。此时这个地址是哪呢(p指向哪呢)?指针变量初始化p = &a;*p就像普通的变量一样使用,其值是p指向的内存的内容(在上例和a等价,但寻址方式不同)p可以动态(任意)地指向不同内存,从而使*p代表不同的变量12指针变量的定义一般形式基类型 *指针变量名;说明“基类型”表示该指针指向的数据的类型可以定义基类型为空类型void的指针变量举例int *pi;char *pc1, *pc2;void *p;13int i,*p;

5、p=&i; int *p;float *q;p=q;int i;float *p;p=&i;int *p;p=1.1;判断是真?是假?指针变量只存放地址!一个指针变量不能指向与其类型不同的变量!我是真的,你猜对了吗?应在类型相同的指针变量之间赋值14地址运算符 (Address Operator)地址运算符 &获得操作数的地址(指针)单目运算符,自右向左结合,优先级较高操作数应为各种类型的内存变量、数组元素、结构体成员等操作数不能是表达式、常量、寄存器变量举例scanf(%f, &score);int i, *p=&i;15指针运算符 (Indirection Operator)指针运算符 *

6、获得指针指向的内存数据又称“间接访问运算符”单目运算符,自右向左结合,优先级较高操作数为具有指针(地址)意义的值举例int i, *p=&i;(*p)+; /* i+; */16指针变量的引用指针变量也要“先赋值,后使用”没有赋值的指针变量所存储的地址数据是不确定的,对它的引用非常危险对指针的赋值要注意类型匹配,必要时可以使用强制类型转换,但要慎重使用*p可以用于与指针p的基类型相同类型的变量可以使用的任何场合指针变量可以作为函数的参数17指针变量引用举例 int a, b, c, *pa, *pb, *pc;pa = &a;pb = &b;pc = &c;a = 100;printf(“*p

7、a=%dn”, *pa);/ *pa=100 *pb = 200;printf(b=%dn, b);/ b=200 scanf(%d, pc);/ 输入34 printf(c=%dn, c);/ c=34 18指针变量与所指变量的关系1020papbabint a, b;int *pa, *pb;pa = &a;pb = &b;*pa = 10;b = 20;pa = pb;pb = &a;&a,&*pa*pa,*&a19指针的运算运算类型算术运算:加、减、自增、自减关系运算:所有关系运算赋值运算:一般赋值、加赋值、减赋值上述运算在一定约束条件下才有意义(后详)变量说明p,q是同类型的指针变量

8、n是整型变量20指针的算术运算运算方式说 明p+np之后第n个元素的地址p-np之前第n个元素的地址p+p作为当前操作数,然后后移一个元素+pp后移一个元素,然后作为当前操作数p-p作为当前操作数,然后前移一个元素-pp前移一个元素,然后作为当前操作数p-q表示p和q两者之间的元素个数条件:p,q是指向同一数据集合(数组)的指针注意避免数组越界21指针的关系运算条件p,q是指向同一数据集合(数组)的指针运算方式pq、p=q、pqpq) printf(%d, p-q);else printf(%d, q-p);pq3个short253. 指向数组的指针指针与数组的关系指向数组的指针通过指针引用数

9、组元素指向二维数组的指针26指针与数组的关系数组名是“常量指针”数组名表示数组的首地址,因此数组名也是一种指针(地址)数组名表示的地址(指针)不能被修改,所以称之为“常量指针”数组的指针数组的起始地址与数组名表示的指针相同与数组的第一个元素(a0)的地址相同27数组和指针的用法数组名不能被赋值和修改,可以直接使用, 若指针指向数组,则两者的其他用法基本相同定义指针时,只分配一段用来存放地址的空间,而没有分配存放数据的空间定义数组时,为所有元素分配相应的连续的存储空间,但没有存放地址的空间指针应赋值后才能使用28指向数组的指针char a10, *p;p = &a0;char a10, *p=&

10、a0;char a10, *p;p = a;char a10, *p=a;ap&a029通过指针引用数组元素当一个指针变量指向数组或某个数组元素时,可以通过这个指针变量引用所有的数组元素引用数组元素的方法下标运算符,例如ai、pi指针运算符*,例如*(a+i)、*(p+i)注意数组名不能被修改和赋值注意防止下标越界30通过指针引用数组元素图示p0, *p, *ap, ap+1, a+1p1, *(p+1), *(a+1)q+i-2, p+i, a+ipi, *(p+i), *(a+i)qi-2, *(q+i-2), p+9, a+9p9, *(p+9), *(a+9)q, p+2, a+2p2

11、, *(p+2), *(a+2) q0, *q31数组名和指针引用数组元素比较 (1)指针指向数组首地址前提条件:int a10, *p=a;ai、pi、*(a+i)、*(p+i)等用法都是合法的,且它们都表示同一个数组元素a+i(或p+i)不是简单的在a(或p)表示的地址值上简单的加i,而是加上i个基类型所需的地址偏移量,即加上i*sizeof(int)指针值可以改变,如p+为下一元素的地址数组名的值不能修改,如a+是非法操作32数组名和指针引用数组元素比较 (2)指针指向某个数组元素前提条件:p=a+i;*(p+)与ai+等价*(p-)与ai-等价*(+p)与a+i等价*(-p)与a-i等

12、价注意不能使用*(a+)或a=p+i这种形式注意区分运算顺序,*(p+)与(*p)+注意防止下标越界,注意掌握指针位置33有一个整型数组a,有10个元素,要求输出数组中的全部元素。 1.下标法 #include int main() int a10, i; printf(“enter 10 integer numbers:n); for(i=0;i10;i+) scanf(%d,&ai); for(i=0;i10;i+) printf(“%d ”,ai); printf(%n); return 0; 34(2) 通过数组名计算数组元素地址,找出元素的值 #include int main()

13、int a10, i; printf(“enter 10 integer numbers:n); for(i=0;i10;i+) scanf(%d,&ai); for(i=0;i10;i+) printf(“%d ”,*(a+i); / *(a+i) 和 ai 等价 printf(n); return 0; 35(3) 用指针变量指向数组元素 #include int main() int i,*p,a10,; printf(“enter 10 integer numbers:n); for(i=0;i10;i+) scanf(%d,&ai); for(p=a;p=(a+9);p+) / 数组

14、名a赋值给p /a+9表示 数组最后一个元素a9的起始地址 printf(“%d ”,*p); printf(n); return 0; 36#include int main() int i,*p,a10; printf(please enter 10 integer numbers:); for(p=a,i=0;i10;i+) / 用指针变量输入,要将数组起始地址赋值给p scanf(“%d”,p+); /指针向后移动 p=a; /指针重新指向数组起始位置 for(i=0;i10;i+,p+) /用指针变量p直接指向数组元素 printf(%d ,*p); printf(n); retur

15、n 0;373种方法的比较: 第(1)和第(2)种方法执行效率相同 编译系统是将ai转换为*(a+i)处理的,即先计算元素地址。因此用第(1)和第(2)种方法找数组元素费时较多。第(3)种方法比第(1)、第(2)种方法快 用指针变量直接指向元素,不必每次都重新计算地址,像p+这样的自加操作是比较快的这种有规律地改变地址值(p+)能大大提高执行效率用下标法比较直观,能直接知道是第几个元素。 用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。384. 指向字符串的指针字符串是存放在字符数组中的。引用一个字符串,可以用以下两种方法。(1) 用字符数组存放一个字符串,可以通过数组

16、名和格式声明“%s”输出该字符串,也可以通过数组名和下标引用字符串中一个字符。(2) 用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。39直接用字符指针指向字符串字符串常量可对字符指针直接赋值这是把字符串常量的地址赋给字符指针不是把字符串的内容赋给字符指针使用字符指针可以修改字符串的内容注意防止越过原字符串常量的范围注意字符串末尾应保留结束标志040字符串(String)与字符数组、字符指针字符串一串以0结尾的字符在C语言中被看作字符串用双引号括起的一串字符是字符串常量,C语言自动为其添加0终结符C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理字符数

17、组每个元素都是字符类型的数组char string100;字符指针指向字符类型的指针char* p;41字符指针变量与字符数组的区别定义方法不同 char str10; char *ptr;赋值方法和含义不同 char str10; str = ”china”; strcpy(str,”china”); char *ptr; ptr = ”china”;/*错误*/*正确*/*正确*/42字符指针变量与字符数组的区别在定义一个数组时,在编译时即分配单元,有确定地址,而定义一个字符指针变量时,如未对它赋初值,则其所指数据是不定的,因而使用是危险的。例如,输入字符串时 char str10; sc

18、anf(%s, str); char *a; scanf(%s, a); char *a; char str10; a = str; scanf(%s, a); /*错误*/*正确*/*正确*/43字符指针变量与字符数组的区别初始化含义不同 char *pstr = ”china”; 等价于 char *pstr; pstr = ”china”; char str14 = ”china”;不等价于 char str14; str = ”china”;字符指针是变量,而数组名是地址常量44字符数组和字符指针变量比较 (1)定义char astr=Hello, World!;char *pstr=Hello, World!;数组在定义时分配存放若干字符的空间指针定义时只分配存放一个地址的空间Hello, World!0 pstr:Hello, World!0astr:45字符数组和字符指针变量比较 (2)字符数组可以直接使用; 指针要先指向一个字符串后才能使用字符串常量只能对数组赋初值; 指针可以用字符串常量或字符数组任意赋值,但只是把字符串的

温馨提示

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

评论

0/150

提交评论