第十章:指针.ppt_第1页
第十章:指针.ppt_第2页
第十章:指针.ppt_第3页
第十章:指针.ppt_第4页
第十章:指针.ppt_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

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

文档简介

1、第10章 指 针 10.1 地址和指针的概念 指针 pointers:与机器内部的硬件结构(内存地址)及其对数据的处理形式等有关。,指针变量:存放变量地址的变量 由此对变量的操作可通过指针来完成,例如:int i, j, k; i=3; j=6; k=i+j;,编译时,系统将内存单元分配给变量后, 程序执行时对变量的操作实际上就是根据变量名查找与之对应的变量的地址,然后按地址对数据进行操作。 1.直接访问 k = i + j 2004 2000 2002 2004 =9 2000=3 2002=6 2.间接访问 *kp = *ip + *jp 3014 3010 3012 3014 2004

2、3010 2000 3012 2002 2004=9 2000=3 2002=6 ip, jp, kp: 指针变量, 其它变量的内存地址。,10.2 变量的指针和指向变量的指针变量 变量的指针:就是变量的地址。 指针变量:用来存放变量地址的变量,如:变量i的指针(地址)是2000,ip是存放i的指针的变量,其自身地址是3010,内容是2000,即i 的地址(指针)。即: ip 是存放变量 i 地址的指针变量(ip=) *ip 是指针变量 ip 所指的对象变量(*ip=i ),10.2.1 定义一个指针变量 指针变量使用前必须定义,以便使其指向特定类型的变量。 指针变量定义形式: 类型标识符 *

3、 标识符 其中:类型标识符:表示所指向变量的数据类型 标识符:表示指针变量名. 例:float *p3;/* p3是指向实型变量的指针变量 * / char *p4; /*p4是指向字符型变量的指针变量* /,int i, j; int *p1, *p2; p1=,10.2.2 指针变量的引用 1、指针变量有两种运算符 *:指针变量所指对象运算符 如:*p1,访问p1所指对象:变量i 说明: 定义时,指针变量名前以*开头说明用途。 引用中,指针变量名前加*表示指针变量所指 对象 看下面的一个例子。,main() int a,b; int *p1,*p2; a=10;b=20; p1= ,mai

4、n() int a,b,c; int *p1,*p2; a=10;b=20; p1= ,运行结果:30 40,运行结果:10,20 10,20,指针变量操作简例 main( ) int a, b, *p1, *p2 ; a=100; b=10; p1= ,运算结果: a=100, b=10 *p1=100, *p2=10 p1= 看下面的例子.,举例: 输入a,b,用指针方法按先大后小的顺序输出。 main( ) int *p1, *p2, *p, a, b; scanf(“%d%d”, ,输入: 5 9 输出: a=5,b=9 *p1=5,*p2=9 t=x; x=y; y=t; print

5、f( ,在被调用函数中变量的值被交换了,返回主函数后,变量的值为什么依旧? 原因:单向的值传递,当函数调用返回后,分配的单元被释放了.,其次 : 指针变量作函数参数,将两个整数按大小顺序输出 swap2(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p; printf( ,main( ) int a, b, *p11, *p12; scanf(%d%d, ,问题:函数调用结束后, 分配给p1,p2单元释放否?,对swap2 函数稍作改动 swap2(int *p1, int *p2) int *p; *p=*p1; *p1=*p2; *p2=*p;

6、printf(p=%x, p1=%x, p2=%xn, p, p1, p2); main ( ) int a, b; int * p11, * p12; scanf(%d%d, ,运行:5, 9 输出:p=ffd2, p11=ffd2, p2=ffd4 a=9, b=9,形参、实参都是指针变量 swap3(int *p1, int *p2) int *p; p=p1; p1=p2; p2=p; printf( ,结论:形参与实参之间的数据传递是单向的值传递,实参的值不会改变。 若在被调函数中通过指针变量改变所指对象的值,结果如何?,举例: 输入 a, b, c三个整数,按从大到小顺序输出 sw

7、ap(int *pt1, int *pt2) int p; p=*pt1; *pt1=*pt2; *pt2=p; exchange(int *q1, int *q2, int *q3) if(*q1 *q2) swap(q1, q2); if(*q1 *q3) swap(q1, q3); if(*q2 *q3) swap(q2, q3); printf(“,printf(“ ,输入:9 0 10 输出: int *p; p=等价. 指针所指元素的地址计算,与数据类型有关(+i:意义因此而异),10.3.2 通过指针引用数组元素 数组名 : 数组的起始地址(常量) 数组元素地址 :数组的起始地址

8、 + 偏移量 若p=等价 例:ai与*(a+i)等价,pi相当于*(p+i),举例 main( ) int a5; int *p= ,输出: float b3=2,4,6; int *p1=a; float *p2=b; printf(“ ,注:若a= for(i=0; i5; i+) printf(“ ,输出: for(i=0;i5;i+) printf(“(a+%d)=%x,*(a+%d)=%d n”,i,(a+i), i,*(a+i); ,输出: (a+0)=ffd0, *(a+0)=55 (a+1)=ffd2, *(a+1)=66 (a+2)=ffd4, *(a+2)=77 (a+3)

9、=ffd6, *(a+3)=88 (a+4)=ffd8, *(a+4)=99,举例:指针法访问数组元素 main( ) int *p, a5=55, 66, 77, 88, 99; for(p=a; p (a+5); p+) printf(“p=%x, *p=%d n”, p,* p); ,输出: p=ffd0, *p=55 p=ffd2, *p=66 p=ffd4, *p=77 p=ffd6, *p=88 p=ffd6, *p=99,举例:下标法、地址法指向数组元素 main( ) int i, * p, a5=55, 66, 77, 88, 99; p=a; for(i=0;i5;i+)

10、printf(“p%d=%d,*(p+%d)=%d n” i,pi,i,*(p+i); ,输出: p0=55, *(p+0)=55 p1=66, *(p+1)=66 p2=77, *(p+2)=77 p3=88, *(p+3)=88 p4=99, *(p+4)=99,使用指针变量时要注意的问题: (1) p+: 合法, 因p是指针变量,+只能用于变量。 a+: 不合法, 因为a是数组名,其值是数组元素的 首地址,是常量。 (2) 指针变量使用时要注意当前值.,举例: 利用指针变量连续两次输出数组元素 main( ) int i, * p, a5=55, 66, 77, 88, 99; p=a;

11、 for(i=0; i5; i+,p+) printf(“p=%x, *p=%d n”, p, *p); for(i=0; i5; i+, p+) printf(“p=%x, *p=%dn”, p, *p); ,输出: p=ffd2, *p=55 p=ffd4, *p=66 p=ffd6, *p=77 p=ffd8, *p=88 p=ffda, *p=99 p=ffdc, *p=-24 p=ffde, *p=285 p=ffe0, *p=1 p=ffe2, *p=-26 p=ffe4, *p=1444,此结果,是何原因?,(3) 数组下标越界时,编译不作检查。 (4) 指针变量使用时的几个问题

12、; +和* 优先级为2, 结合性从右向左 若 p=a+3 则: *p+: 将p所指对象(a3)的值88取出,然后p增1 指向a4 *+p: 先将p增1指向a4,然后将其指向的对象a4的值99取出。 *p- : 将p所指对象(a3)的值88取出,然后p减1 指向a2 *-p : 先将p减1指向a2,然后将其指向的对象a2的值77取出。,若:p=a+i, 则 *p+ 与 ai+ *p- 与 ai- - *+p 与 a+i *-p 与 a- -i 等价,10.3.3 用数组名作函数参数 f( int arr , int n) main( ) int array10; f(array, 10); ,调

13、用函数时,以数组名作实参实际上是把数组的首地址传递给形参,此时,形参数组和实参数组占用的是同一段内存,函数调用过程中,改变形参数组元素实际上也是改变实参数组元素,调用结束后,虽然形参数组名已不存在了,但对实参数组元素的操作起产生作用。,例10.7 数组内容逆序存放 举例: 将数组a中n个整数按相反顺序存放 算法:a0an-1 a1an-2 . a(n-1)/2an-(n-1)/2 x0 x1 x2x3 x4 x5x6 x7 x8x9 3 7 9 1 0 6 7 5 4 2 m = (n-1)/2; for(i=0; i=m; i+) xi xjj = n-1-i,#include void i

14、nv(int x, int n) int t, i, j, m; m = (n-1)/2; for(i=0; i=m; i+) j = n-1-i; t = xi; xi = xj; xj = t; void main() int i, a10=3,7,9,1,0,6,7,5,4,2; printf(the original array:n); for(i=0;i10;i+) printf(%d, ai);printf(n); inv(a,10); printf(the array has been inverted:n); for(i=0;i10;i+) printf(%d, ai);pri

15、ntf(n); ,将上例中的形参x改为指针变量,以接收实参数组a传递来的地址,再设指针i, j, p 指向有关元素,以实现数组元素的转换 void inv(int *x, int n) int *p, t, *i, *j, m=(n-1)/2; i=x; j=x+n-1; p=x+m; for( ; i=p; i+, j-) t=*i; *i=*j; *j=t; ,实参可继续使用数组名,也可以使用指针 main( ) int i, arr10, *p=arr; printf(“input original array : n”); for(i=0; i10; i+, p+) scanf(“%d

16、”,p); printf(“n”); p=arr ; inv(p, 10); printf(“the array has been inverted: n”); for(p=arr; parr+10; p+) printf(“%d “, *p); printf(“ n”); ,显示:the original array: 输入: 3 7 9 11 0 6 7 5 4 2 the array has been inverted: 2 4 5 7 6 0 11 9 7 3,举例: 从10个数中找出最大值和最小值, 分别存入全局 量max, min中,在查找过程中 指针p:依次指向数组各元素, ar

17、ray_end: 指向最未元素后, array:指向array0所对应值。 int max, min; void max_min(int array, int n) int *p; max=min=*array; for(p=array+1; p max) max=*p; else if(*pmin) min=*p; ,main( ) int i, number10; printf(“enter 10 data n”); for(i=0;i10;i+) scanf(“%d”, ,运行: enter 10 data -2 4 6 8 0 -3 45 67 89 10 输出: max=100, m

18、in=-3,举例: 对数组元素的操作,形、实参数均使用指针变量 int max, min; void max_min (int *array, int n) int *p; max=min=*array; for(p=array+1; p max) max=*p; else if(*pmin) min=*p; ,在被调用函数中改变数组的值,实参、形参取值有四种情况: (1)实、形参都是数组名 main( ) int a10 f(a, 10); ,f(int x , int n) ,(2)实参为数组名,形参为指针变量 main( ) int a10 f(a, 10); ,f(int *x, in

19、t n) ,(3)形、实参都是指针变量 main( ) int a10 ,*p; p=a; f(p, 10); ,f(int *x, int n) ,(4)实参为指针变量,形参为数组 main( ) int a10 ,*p; p=a; f(p , 10); ,f(int x , int n) ,例10.10 排序函数. 选择排序 selection sort void selection(int a, int n) int i,k,index,temp; for(k=0; kn-1;k+) index = k; for(i=k+1; in; i+) if(ai aindex) index =

20、i; temp = aindex;aindex = ak;ak = temp; ,冒泡排序bubble sort函数 void bubble(int a, int n) int j,k,temp; for(k=1; k aj+1) temp = aj;aj = aj+1;aj+1 = temp; ,main() int *p,i,a10; p=a; for(i=0;i10;i+) scanf(“%d”, ,10.3.4 多维数组与指针 1、多维数组元素的地址 如定义:int a34=1,3,5,7,9,11,13,15,17,19,21,23; 说明:a, a0, a1 ,a2:本身不占内存,

21、不存放数据,仅表示地址 a:代表整个数组首地址,设为2000 a0 1 3 5 7 a1 9 11 13 15 a217 19 21 23 实际地址 (2000)a0第0行首址:即数组a的首址2000 (2008)a1a+1第1行首址:a+142=2008 (2016)a2a+2第2行首址:a+242=2016 说明:a, a0, a1 ,a2:本身不占内存,不存放数据,仅表示地址,a0、a1、a2是一维数组名,而数组名代表数组首地址 因此:a0表示0行0列元素的地址: printf(a=%x, a0=%x, a1=%x,a2=%xn,a,a0,a1,a2); printf(a+0=%x, a

22、+1=%x,a+2=%xn,a+0,a+1,a+2); for(i=0; i3; i+) for(j=0; j4; j+) printf(%x,%x,%xn,*(a+i)+j, ai+j, ,2、指向多维数组的指针变量 (1) 指向数组元素的指针变量 举例:用指针变量顺序输出数组元素的值 #include void main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p= ,运行结果: 1 3 5 7 1 3 5 7 addr=ffc2, value=1 addr=ffc4, value=3 addr=ffc6, value=

23、5 addr=ffc8, value=7 addr=ffca, value=9 addr=ffcc, value=11 addr=ffce, value=13 addr=ffd0, value=15 addr=ffd2, value=17 addr=ffd4, value=19 addr=ffd6, value=21 addr=ffd8, value=23,由此可见:顺序输出数组元素方法简单 而指定输出数组元素则要进行地址的计算 如二维数组为 n m (n为行, m 为列) 首元素地址为 a0 aij在数组中相对位置的计算公式: i * m + j ( m为每行元素个数) 位移量的计算: a1

24、1=1*4+1=5 a23=2*4+3=11 若初值: p=a0 则: *(p+1*4+1)=*(p+5) a11 *(p+2*4+3)=*(p+11) a23,a11,(2) 指向包含m个元素的一维数组的指针变量 若p是数组(一或二维)元素的指针变量,则p+,指向下一元素. 若p是包含m个元素的一维数组指针, 如定义: (* p)4; 则p只能指向包含m个元素的一维数组,p+指向下一个一维数组. p的值是该一维数组的首地址. p不能指向一维数组中的任一元素,某行第j个元素只能通过(*p)j访问。,举例: 输出二维数组任一行任一列元素的值。 #include void main( ) int

25、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=1 输出:a11=11 a13=15 a22=21,a,a+0,p+0,a+1,p+1,a+2,p+2,10.4 字符串与指针 10.4.1 字符串的表示形式 (1)用字符数组存放一个字符串,然后输出该字符串。 看教材P251页例10.15。 (2)用字符指针指向一个字符串。 看教材P251 P253页例10.16、10.17、10.18。 从书上的例子可知,其使用与数组使用一样,这里就不多叙述了。,举例:用字符数组和字

26、符型指针变量输出字符串 #include void main() char s1 = I love China!; char *s2 = I love Hangzhou!; printf(s1=%sn, s1); printf(s2=%sn, s2); s2 = s2+7; printf(s2=%sn, s2); ,举例: 用下标法存取字符串中的字符 #include void 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); ,举例: 用指针法存取字符串中的字符 #include void main( ) char a=I am a boy.

温馨提示

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

评论

0/150

提交评论