第十章 指针_finalppt课件_第1页
第十章 指针_finalppt课件_第2页
第十章 指针_finalppt课件_第3页
第十章 指针_finalppt课件_第4页
第十章 指针_finalppt课件_第5页
已阅读5页,还剩55页未读, 继续免费阅读

下载本文档

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

文档简介

1、第十章第十章 指针指针 C C程序的变量所存放的数据:程序的变量所存放的数据: 数值型数据:整数、实数数值型数据:整数、实数经过前面的学习,我们知道:经过前面的学习,我们知道: 字符型数据:字符、字符串字符型数据:字符、字符串 构外型数据:数组构外型数据:数组前言 在计算机中存储在具有一定长度的内存单在计算机中存储在具有一定长度的内存单元中元中 如:如:int x; x占二字节、二个单元占二字节、二个单元 每一个变量都有一个地址,为无符号整数,它每一个变量都有一个地址,为无符号整数,它不同于普通的整数。不同于普通的整数。 能否对地址运算?能否对地址运算? 能否用一个变量保管地址?能否用一个变量

2、保管地址?问题:问题:10.1 10.1 地址与指针的概念地址与指针的概念一、数据在内存中的存放一、数据在内存中的存放内存:划分为假设干个存储单元,每个单内存:划分为假设干个存储单元,每个单元可存放元可存放8位二进制数即位二进制数即1个字个字节。节。 内存运用延续编号内存运用延续编号(地址地址)为每一为每一个单元编址,使每个内存单元对应个单元编址,使每个内存单元对应独一一个地址编码。独一一个地址编码。 假设假设 int i= 5, j=5, k=10; 设:系统分配设:系统分配i的起始地址为的起始地址为2000的单元的单元那么那么 j的地址有能够为的地址有能够为2002, k的地址有能够为的地

3、址有能够为20042000200120022003200420053001 5+5102000ijk变量的地址:系统分配给变量的内存单元的起始地址变量的地址:系统分配给变量的内存单元的起始地址当程序中要用它们的值时:当程序中要用它们的值时: y=i+j+k;找到找到j的地址的地址2002,将将2002,2003中的数据中的数据5读出;读出;找到找到k的地址的地址2004,将将2004,2005中的数据中的数据10读出。读出。分别分别 找到找到i i的地址的地址20002000, 将将20002000,20012001中的数据中的数据55读出;读出;那么系统经过一张变量名与地址对应关系表编译时确

4、定:那么系统经过一张变量名与地址对应关系表编译时确定:然后把这些数据进展算术运算。然后把这些数据进展算术运算。直接访问:直接运用存放该数据的变量名。直接访问:直接运用存放该数据的变量名。 间接访问:假设将某一变量的地址如间接访问:假设将某一变量的地址如 i i 的的地址地址20002000存放到另一个变量存放到另一个变量x x,那么可经过那么可经过x x来存取来存取i i的值。的值。上述过程称为变量的上述过程称为变量的“直接访问直接访问i相当于运用相当于运用 5运用变量运用变量如:用如:用pi, pj, pk来存放来存放i, j, k的地址的地址200020022004 55103001300

5、330053007200020022004pipjpkijk 假设要得到变量假设要得到变量i的值,可以先访问的值,可以先访问pi,得到,得到i的地的地址,再经过该地址找到它址,再经过该地址找到它i的值。的值。显然,显然,pi与与i是经过是经过i的地址联络起来的。的地址联络起来的。定义:一个变量的地址称为该变量的指针。定义:一个变量的地址称为该变量的指针。 如,如, 地址地址20002000为变量为变量 i i的指针。的指针。如:如: pi, pj, pk就是指针变量。就是指针变量。而存放地址而存放地址(指针指针)的变量叫做指针变量。的变量叫做指针变量。二、指针的定义二、指针的定义.200020

6、0420062005整型变量整型变量i-5变量变量i_pointer200120022003指针:一个变量的地址指针:一个变量的地址指针变量:专门存放变量地址的变量指针变量:专门存放变量地址的变量2000指针指针指针变量指针变量 变量的内容变量的内容变量的变量的地址地址指针变量指针变量目的变量目的变量变量地址变量地址(指针指针)变量值变量值指向指向地址存入地址存入指针变量指针变量指针与指针变量指针与指针变量一、指针变量的定义一、指针变量的定义普通方式:普通方式: 基类型基类型 *指针名;指针名;合法标识符合法标识符指针变量所指向的目的变量的指针变量所指向的目的变量的数据类型数据类型表示定义指针

7、变量表示定义指针变量这里不是这里不是*运算运算符符留意:留意:1、int *p1, *p2; 与与 int *p1, p2;2、指针变量名是、指针变量名是p1,p2 ,不是,不是*p1,*p2;3、指针变量只能指向定义时所规定类型的变量;、指针变量只能指向定义时所规定类型的变量;4、指针变量定义后,变量值不确定,运用前必需先赋值。、指针变量定义后,变量值不确定,运用前必需先赋值。例例 int int * *p1,p1,* *p2;p2; float float * *q ;q ;10.2 指针变量的定义与援用指针变量的定义与援用二、指针变量的援用方式:二、指针变量的援用方式:如如 int *p

8、; char *s; float *t; *p=5; *s=a; *t=3.6;指针变量名指针变量名-表示指向目的变量的指针表示指向目的变量的指针( (地址地址) )。* *指针变量名指针变量名-表示指针变量所指目的变量的值。表示指针变量所指目的变量的值。与指针援用相关运算符与指针援用相关运算符 将一个变量的地址将一个变量的地址( (指针指针) )赋给一个指针变量,赋给一个指针变量,用取地址运算符:用取地址运算符:& & int i, j, p; i=3; p=&i; 假设将整数赋给地址量假设将整数赋给地址量p=1000;编译会;编译会报错误,这是不合法的。报错误,这是不合法的。切记:不能直接

9、将整型常量赋值给指针变量。切记:不能直接将整型常量赋值给指针变量。pi的地址的地址3/表示:表示:*p =3 存取指针变量所指向目的变量的值:存取指针变量所指向目的变量的值: 用指针运算符用指针运算符* *“指向指向, , 即:即:* *p p 为为 i i留意:当留意:当& &或或& &在一同时,具有抵消作用在一同时,具有抵消作用如:如:int i, int i, p; p; i=3; i=3; p=&i; p=&i; 那么:那么:* *p=p=* *&i&i相当于相当于* *p=i p=i 假设对指针变量进展取址运假设对指针变量进展取址运算,算,&p会有什么结果?会有什么结果?请思索:请思

10、索:*: 取指针所指向变量的内容取指针所指向变量的内容单目运算符单目运算符优先级优先级: 2结合性结合性:自右向左自右向左&: 取变量的地址取变量的地址单目运算符单目运算符优先级优先级: 2结合性结合性:自右向左自右向左两者关系:互为逆运算两者关系:互为逆运算.2000200420062005整型变量整型变量i10变量变量i_pointer2001200220032000指针变量指针变量i_pointer-指针变量,它的内容是地址量指针变量,它的内容是地址量*i_pointer-指针的目的变量,它的内容是数据指针的目的变量,它的内容是数据&i_pointer-指针变量占用内存的地址指针变量占用

11、内存的地址200010i_pointer*i_pointer&i_pointerii_pointer &i &(*i_pointer)i *i_pointer *(&i)i_pointer = &i = &(*i_pointer)i = *i_pointer = *(&i)了解了解&与与*运算符运算符指针变量与其所指向的变量之间的关系指针变量与其所指向的变量之间的关系3变量变量i2000i_pointer*i_pointeri*i_pointer&ii_pointeri=3;*i_pointer=33变量变量i2000i_pointer*i_pointeri*i_pointer&ii_poin

12、teri=3;*i_pointer=3阐明:阐明: (*i_pointer)+相当于相当于i+. *i_pointer+:“+和和*的优先级一样,右结合,等的优先级一样,右结合,等价于价于*(i_pointer+) 先对先对i_pointer的原值进展的原值进展*运算,得到运算,得到i的值,然后的值,然后i_pointer的值改动,的值改动, i_pointer不再指向不再指向i了了. p普通方式:基类型普通方式:基类型 *指针名指针名=初始地址值;初始地址值;赋给指针变量,赋给指针变量,不是赋给目的变量不是赋给目的变量例例 int i; int i; int int * *p=&i;p=&i

13、;变量必需已阐明过;变量必需已阐明过;且类型应一致且类型应一致例例 int int * *p=&i; p=&i; int i; int i;例例 int i; int i; int int * *p=&i;p=&i; int int * *q=p;q=p;用已初始化指针变量作初值用已初始化指针变量作初值三、指针变量的初始化三、指针变量的初始化int *p=2000;不能用整型常量初始化指针变量不能用整型常量初始化指针变量#include void main() int i=10; int *p; *p=i; printf(%d,*p);危险!危险!见见VCvoid main() int i=1

14、0,k; int *p; p=&k; /修正后修正后 *p=i; printf(*p=%d, k=%dn,*p, k); .2000200420062005整型变量整型变量i10指针变量指针变量p200120022003随机随机指针变量必需先赋值指针变量必需先赋值, ,再运用再运用p 零指针:零指针:( (空指针空指针NULL)NULL)p定义:指针变量值为零定义:指针变量值为零p表示:表示: int int * * p=0; p=0; p p指向地址为指向地址为0 0的单元,的单元,系统保证该单元不作它用系统保证该单元不作它用表示指针变量值没有意义表示指针变量值没有意义C言语定义言语定义#d

15、efine NULL 0int *p=NULL:p=NULL与未对与未对p赋值不同赋值不同用途用途: 防止指针变量的非法援用,即防止误操作。在指针不运用防止指针变量的非法援用,即防止误操作。在指针不运用或指向对象无效时,建议将之置空,否那么是或指向对象无效时,建议将之置空,否那么是 “野指针。野指针。运用指针时得先判别它是不是运用指针时得先判别它是不是NULL,必需不是,必需不是NULL了才了才可以运用它,这个指针才有意义。可以运用它,这个指针才有意义。 例例 int *p; . while(p!=NULL) . p void void类型类型 * *指针变量指针变量p表示表示: void :

16、 void * *p; p; p运用时要进展强迫类型转换运用时要进展强迫类型转换例例 char *p1; void *p2; p1=(char *)p2; p2=(void *)p1;表示不指定表示不指定p p是指向哪一种是指向哪一种类型数据的指针变量类型数据的指针变量零指针或空类型指针来赋值零指针或空类型指针来赋值归纳得出,指针变量的初始化方法:用已定义的同类型变量的地址用已定义的同类型变量的地址赋空值赋空值NULL,但运用前要使指针变量指向有,但运用前要使指针变量指向有意义的内存单元。意义的内存单元。强调一点:强调一点: 指针变量必需先赋值,再运用指针变量必需先赋值,再运用main() i

17、nt *p1,*p2,*p,a,b; scanf(%d,%d,&a,&b); p1=&a; p2=&b; if(ab) p=p1; p1=p2; p2=p; printf(a=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1,*p2);运转结果:运转结果:a=5,b=9 max=9,min=5.指针变量指针变量p1 指针变量指针变量p20002021200220042006 指针变量指针变量p2 整型变量整型变量b 整型变量整型变量a5200692021200620212006例例 输入两个数,并使其从大到小输出输入两个数,并使其从大到小输出p特点:共享内存,特

18、点:共享内存,“双向传送双向传送void swap(int x,int y) int temp; temp=x; x=y; y=temp;void main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);例例 将数从大到小输出将数从大到小输出.20002021200A2002200420065变量变量a 变量变量b(main)9 变量变量temp 变量变量y 变量变量x(swap)559 59COPY四、指针变量作为函数参数四、指针变量作为函数参数地址传送地址传送void swap(int x,int

19、y) int temp; temp=x; x=y; y=temp;void main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);例例 将数从大到小输出将数从大到小输出值传送值传送.20002021200A2002200420065变量变量a 变量变量b(main)9运转结果:运转结果:5, 9p特点:共享内存,特点:共享内存,“双向传送双向传送四、指针变量作为函数参数四、指针变量作为函数参数地址传送地址传送void swap(int *p1, int *p2) int p; p=*p1; *p1=*

20、p2; *p2=p;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);.20002021200A200220042006200C200E2021.59整型变量整型变量a 整型变量整型变量b(main)指针指针pointer_1指针指针pointer_220002002(swap)指针指针p1指针指针p2整型整型p5920002002COPY5例例 假

21、设利用指针作函数参数,将数从大到小输出假设利用指针作函数参数,将数从大到小输出void swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);.20002021200A200220042006200C200E2021.59整型变量整型变量a 整型变量整

22、型变量b(main)指针指针pointer_1指针指针pointer_22000200259运转结果:运转结果:9,5地址传送地址传送例例 将数从大到小输出将数从大到小输出1 1void swap(int *p1, int *p2) int *p; *p=*p1; *p1=*p2; *p2=*p;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);运

23、转结果:运转结果:9,9编译警告!编译警告!结果不对!结果不对!甚至甚至“运转程序错误!运转程序错误!int x;int *p=&x;.20002021200A200220042006200C200E2021.59整型变量整型变量a 整型变量整型变量b(main)指针指针pointer_1指针指针pointer_2200020029920002002COPY(swap)指针指针p1指针指针p2指针指针p*假设假设2000指针变量在运用前指针变量在运用前必需赋值!必需赋值!例例 将数从大到小输出将数从大到小输出2 2void swap(int x,int y) int t; t=x; x=y;

24、y=t;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(*pointer_1,*pointer_2); printf(n%d,%dn,a,b);运转结果:运转结果:5,9值传送值传送.20002021200A200220042006200C200E2021.59整型整型a 整型整型b(main)pointer_1pointer_2200020029COPY(swap)整型整型x整型整型y整型整型t555 9例例 将数从大到小输出

25、将数从大到小输出3 3运转结果:运转结果:5,9void swap(int *p1, int *p2) int *p; p=p1; p1=p2; p2=p;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(pointer_1,pointer_2); printf(%d,%d,*pointer_1,*pointer_2);.20002021200A200220042006200C200E2021.59整型整型a 整型整型b(main

26、)pointer_1pointer_22000200220002002COPY(swap)指针指针p1指针指针p2指针指针p*2000地址传送地址传送20002002例例 将数从大到小输出将数从大到小输出4 4经过函数调用得到两个要改动的值,可以:1在主调函数中设两个变量,用两个指针变量在主调函数中设两个变量,用两个指针变量指向它们。指向它们。2然后将指针变量作实参,将这两个变量的地然后将指针变量作实参,将这两个变量的地址传给所调用的函数的形参。址传给所调用的函数的形参。3经过形参指针变量,改动这两个目的变量的经过形参指针变量,改动这两个目的变量的值。值。4主调函数中就可以运用这些改动了值的变

27、量。主调函数中就可以运用这些改动了值的变量。一、指向一维数组元素的指针变量一、指向一维数组元素的指针变量例例 int array10; int *p; p=&array0; / p=array;或或 int *p=&array0;或或 int *p=array;array0array1array2array3array9.整型指针整型指针p&array0p数组名数组名array是表示数组首地址的地址常量,是表示数组首地址的地址常量,所以它和指向数组首地址的指针变量所以它和指向数组首地址的指针变量p不同,不同,它不是变量。它不是变量。10.3 指针与数组指针与数组指针变量的赋值运算指针变量的赋值

28、运算p=&a; (将变量将变量a地址地址p)p=array; (将数组将数组array首地址首地址p)p=&arrayi; (将数组元素地址将数组元素地址p)p1=p2; (指针变量指针变量p2值值p1)留意:不能把一个整数留意:不能把一个整数(常量或变量常量或变量)p,也不能把,也不能把p的的值值整型变量整型变量如如 int i, *p, j=2450; p=1000; () p=j; () i=p; ()二、指针的运算二、指针的运算pi p id (i为整型数,为整型数,d为为p指向的变量所占字节数指向的变量所占字节数)。 如:如:p+, p-, p+i, p-i, p+=i, p-=i等

29、等假设假设p1与与p2指向同一数组,指向同一数组, p1-p2=两指针间元素个数两指针间元素个数(p1-p2)/d; p1+p2 无意义无意义 p1与与p2可做比较运算,但不指向同一数组那么无意义可做比较运算,但不指向同一数组那么无意义例例 p指向指向float数,那么数,那么 p+1 p+1 4例例 p指向指向int型数组,且型数组,且p=&a0; 那么那么p+1 指向指向a1例例 int a10; int *p=&a2; p+; *p=1;例例 int a10; int *p1=&a2; int *p2=&a5; 那么:那么:p2-p1=3;1指针的算术运算:指针的算术运算:a0a1a2a

30、3a4a5a6a7a8a9a数组数组pp+1,a+1p+i,a+ip+9,a+9a0a1a2a3a9.aa+9a+1a+2地址元素下标法a0a1a2a9a0a1a2a3a9.pp+9p+1p+2地址元素指针法*p*(p+1)*(p+2)*(p+9) 变址运算符ai *(a+i)数组元素的内容:数组元素的内容:ai pi *(p+i) *(a+i)数组元素的地址:数组元素的地址: a+i p+i*a*(a+1)*(a+2)*(a+9)p0p1p2p9数组元素的表示法数组元素的表示法a0a1a2a3a4void main() int a5,*pa,i; for(i=0;i5;i+) ai=i+1;

31、 pa=a; for(i=0;i5;i+) printf(*(pa+%d):%dn,i,*(pa+i); for(i=0;i5;i+) printf(*(a+%d):%dn,i,*(a+i); for(i=0;i5;i+) printf(pa%d:%dn,i,pai); for(i=0;i5;i+) printf(a%d:%dn,i,ai);12345pa例例 数组元素的援用方法数组元素的援用方法例例 int a=1,2,3,4,5,6,7,8,9,10, *p=a, i; 数组元素地址的正确表示:数组元素地址的正确表示:A&(a+1) Ba+ C&p D&pi 数组名是地址常量数组名是地址常

32、量p+,p- ()a+,a- ()a+1, *(a+2) ()运用指针变量时应留意的问题:1可以改动指针变量的值可以改动指针变量的值2留意指针变量的运算留意指针变量的运算3要留意指针变量的当前值要留意指针变量的当前值4指针变量指针变量p可以指向数组以后的内存单元可以指向数组以后的内存单元例例 void main() int a =5,8,7,6,2,7,3; int y, *p=&a1; y=(*-p)+; printf(“%d ,y); printf(“%d,a0); 输出:输出:5 6pp58762730123456a6例例 留意指针变量的运算留意指针变量的运算#include void

33、main() int i,*p,a7; p=a; for(i=0;i7;i+) scanf(%d,p+); printf(n); for(i=0;i7;i+,p+) printf(%d,*p); printf(n);p=a;pp58762730123456apppppp指针变量可以指到数组后的内存单元指针变量可以指到数组后的内存单元例例 留意指针变量的当前值留意指针变量的当前值数组名作函数参数,是地址传送数组名作函数参数,是地址传送数组作函数参数,实参与形参的对应关系可归纳为数组作函数参数,实参与形参的对应关系可归纳为4种:种:实参实参形参形参数组数组指针变量指针变量数组数组指针变量指针变量数

34、组名数组名数组名数组名指针变量指针变量指针变量指针变量三、数组名作函数参数三、数组名作函数参数分析分析1:实参:实参数组名,形参数组名,形参实参数组名代表该数组首元素的地址。实参数组名代表该数组首元素的地址。形参是用来接纳从实参传送过来的数组首元素的地址。形参是用来接纳从实参传送过来的数组首元素的地址。因此,形参应该是一个指针变量只需指针变量才干存因此,形参应该是一个指针变量只需指针变量才干存放地址或数组。放地址或数组。C编译实践上是将形参数组名作为指针变量来处置的。编译实践上是将形参数组名作为指针变量来处置的。函数函数f的形参表示:的形参表示: f (int arr , int n) 与与

35、f (int *arr, int n)是等价的。是等价的。 在调用该函数时,系统会建立一个指针变量在调用该函数时,系统会建立一个指针变量arr,用来存放从主调函数传送过来的实参数组首元素的地址。用来存放从主调函数传送过来的实参数组首元素的地址。 当当arr接纳了实参数组的首元素地址后,接纳了实参数组的首元素地址后,arr指向实指向实参数组首元素,即指向参数组首元素,即指向array0, *(arr+i) arri 。 ij 3 7 9 11 0 6 7 5 4 20 1 2 3 4 5 6 7 8 9ijijijji11760594723实参与形参均用数组实参与形参均用数组void inv(i

36、nt x, int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n);m=4例例 将数组将数组a中的中的n个整数按相反顺序存放个整数按相反顺序存放1void inv(int *x, int n) int t,*p,*i,*j,m=(n-1)/2; i=x

37、; j=x+n-1; p=x+m; for(;i=p;i+,j-) t=*i; *i=*j; *j=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n); 实参用数组实参用数组, ,形参用指针变量形参用指针变量: :x x就指向就指向a0a0;x+mx+m就是就是amam元素的地址。元素的地址。37911067542a0a1a2a3a4a5a6a7a8a9xp=x+ma数组数组6071

38、1594723ijijijjiji例例 将数组将数组a中的中的n个整数按相反顺序存放个整数按相反顺序存放2void inv(int *x, int n) int t,*i,*j,*p,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,a10,*p=a; for(i=0;i10;i+,p+) scanf(%d,p); p=a; inv(p,10); printf(The array has been reverted:n); for(p=a;pa+10;p+) printf(%d,*p)

39、; 实参与形参均用指针变量实参与形参均用指针变量例例 将数组将数组a中的中的n个整数按相反顺序存放个整数按相反顺序存放3void inv(int x, int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10,*p=a; for(i=0;i10;i+,p+) scanf(%d,p); p=a; inv(p,10); printf(The array has been reverted:n); for(p=arr;parr+10;p+) printf(%d ,*p); 实参用指

40、针变量实参用指针变量, ,形参用数组形参用数组例例 将数组将数组a中的中的n个整数按相反顺序存放个整数按相反顺序存放4int *p 与与 int q10 数组名是指针地址常量;假设数组名是指针地址常量;假设p=q; p+i 是是qi的地址的地址数组元素的表示方法:下标法和指针法,数组元素的表示方法:下标法和指针法, 即假设即假设p=q, 那么那么 pi qi *(p+i) *(q+i) 形参数组本质上是指针变量,即形参数组本质上是指针变量,即int q int *q 在定义指针变量不是形参时,不能把在定义指针变量不是形参时,不能把int *p 写成写成int p;系统只给系统只给p分配能保管一

41、个指针值的内存区分配能保管一个指针值的内存区(普通普通2字节字节;而给而给q分配分配2*10字节的内存区。字节的内存区。四、多维数组与指针四、多维数组与指针 1、指针变量与一维数组的关系归纳一下、指针变量与一维数组的关系归纳一下二维数组二维数组a,它有,它有3行行4列,定义为列,定义为int a34=1,3,5,7,9,11,13,15,17,19,21,23;分析:分析: a是数组名。是数组名。 a数组包括数组包括3行,即行,即3个元素:个元素:a0, a1, a2. a0所代表的一维数组,又包含所代表的一维数组,又包含4个元素:个元素:a00, a01, a02, a03. 二维数组是数组

42、的数组,即数组二维数组是数组的数组,即数组a是由是由3个一维数组所组成。个一维数组所组成。 a是二维数组首元素的地址,如今的首元素不是一个整型变量,是二维数组首元素的地址,如今的首元素不是一个整型变量,而是由而是由4个整型元素所组成的一维数组,个整型元素所组成的一维数组,a代表首行的首地址,代表首行的首地址,a+1代表第代表第1行的首地址。行的首地址。2、二维数组的地址、二维数组的地址对于二维数组:对于二维数组:1a是数组名,是数组名, 包含三个元素包含三个元素 a0,a1,a22每个元素每个元素ai 又是一个一维又是一个一维 数组,包含数组,包含4个个 元素元素aa+1a+2*(*(a+0)

43、+1)*(a0+1)int a34;a0a1a2200020212021200020022021202120212021a00a01a10a11a20a21a02a03a12a13a22a23a0+1a1+1a2+1*(a+0)+1*(a+1)+1*(a+2)+13、行指针与列指针、行指针与列指针1 对二维数组对二维数组 int a34,有有 a-二维数组的首地址,即第二维数组的首地址,即第0行的首地址行的首地址 a+i-第第i行的首地址行的首地址 ai *(a+i)-第第i行第行第0列的元素地址列的元素地址 ai+j *(a+i)+j -第第i行第行第j列的元素地址列的元素地址 *(ai+j

44、) *(*(a+i)+j) aija+i=&ai=ai=*(a+i) =&ai0, 值相等,含义不同值相等,含义不同 a+i &ai,表示第,表示第i行首地址,指向行首地址,指向行行 ai *(a+i) &ai0,表示第,表示第i行行第第0列元素地址,指向列列元素地址,指向列行指针与列指针行指针与列指针2int a34;a0a1a2200020212021200020022021202120212021a00a01a10a11a20a21a02a03a12a13a22a23aa+1a+2int a34;a00a01a10a11a20a21a02a03a12a13a22a23二维数组元素表示方式

45、:二维数组元素表示方式:1a122*(a1+2)3*(*(a+1)+2)4*(&a00+1*4+2)地址表示:地址表示:(1) a+1 (2) &a10(3) a1(4) *(a+1)行指针行指针列指针列指针地址表示:地址表示:(1) &a12(2) a1+2(3) *(a+1)+2(4)&a00+1*4+2行指针与列指针行指针与列指针3在行指针前加一个在行指针前加一个* *,转换为列指针;,转换为列指针;在列指针前加一个在列指针前加一个& &,转换为行指针。,转换为行指针。表示方式表示方式含义含义地址地址a二维数组名,数组首地址二维数组名,数组首地址a0,*(a+0),*a第第0行第行第0列

46、元素地址列元素地址a+1第第1行首地址行首地址a1,*(a+1)第第1行第行第0列元素地址列元素地址a1+2,*(a+1)+2,&a12第第1行第行第2列元素地址列元素地址*(a1+2),*(*(a+1)+2),a12第第1行第行第2列元素值列元素值2000200020212021202113数组数组a的性质的性质n指向二维数组元素的指针变量指向二维数组元素的指针变量例例 指向二维数组元素的指针变量指向二维数组元素的指针变量main() static int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=a0;pa0+12; p+) if(

47、p-a0)%4=0) printf(n); printf(%4d ,*p); p=*a; p=&a00; p=*(a+0); p=a; p=*a; p=&a00; p =*(a+0); p=a; int a34;a00a01a10a11a20a21a02a03a12a13a22a23p4、二维数组的指针变量、二维数组的指针变量 定义方式:定义方式: 数据类型数据类型 (*指针名指针名)一维数组维数一维数组维数; 例例 int (*p)4;( )( )不能少不能少int (int (* *p)4p)4与与int int * *p4p4不同不同p的值是一维数组的的值是一维数组的首地址,首地址,p是

48、行指针是行指针 可让可让p p指向二维数组某一行指向二维数组某一行 如如 int a34, ( int a34, (* *p)4=a;p)4=a;int a34;a00a01a10a11a20a21a02a03a12a13a22a23aa+1a+2pp+1p+2p0+1或或 *p+1p1+2或或 *(p+1)+2*(*p+1)或或*(p0+1) *(*(p+1)+2)或或*(p1+2)一维数组指针变量维数和一维数组指针变量维数和二维数组列数必需一样二维数组列数必需一样指向由指向由m m个元素组成的一维数组的指针变量个元素组成的一维数组的指针变量#include void main() int

49、a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4, i, j; /p是指针变量,指向包含四个整型元素的一维数组是指针变量,指向包含四个整型元素的一维数组 p=a; scanf(i=%d, j=%d,&i, &j); printf(a%d,%d=%dn, i, j, *(*(p+i)+j);例例 输出二维数组任一行任一列元素的值输出二维数组任一行任一列元素的值n实参二维数组名实参二维数组名/ /指针变量;形参的方式如下指针变量;形参的方式如下: :n用指向变量的指针变量用指向变量的指针变量n用指向一维数组的指针变量用指向一维数组的指针变量n用二维数组名用

50、二维数组名实参形参数组名int x4指针变量int (*q)4数组名int x4指针变量int (*q)4数组名a数组名a指针变量p1指针变量p1假设int a34; int (*p1)4=a; int *p2=a0;指针变量p2指针变量int *q5、二维数组的指针作函数参数、二维数组的指针作函数参数用指针变量作形参来接受实用指针变量作形参来接受实参数组名传送来的地址参数组名传送来的地址main() void average(float *p,int n); void search(float (*p)4,int n); float score34=65,67,79,60,80,87,90,

51、81,90,99,100,98; average(*score,12); search(score,2);void average(float *p,int n) float *p_end, sum=0,aver; p_end=p+n-1; for(;p=p_end;p+)sum=sum+(*p); aver=sum/n; printf(average=%5.2fn,aver);void search(float (*p)4, int n) int i; printf( No.%d :n,n); for(i=0;i4;i+) printf(%5.2f ,*(*(p+n)+i);列指针列指针行指

52、针行指针函数阐明函数阐明float p46552796080879081909910098pp例例 3个学生各学个学生各学4门课,计算总平均分,并输出第门课,计算总平均分,并输出第n个学生成果个学生成果 pni 10.4 10.4 指针与字符串指针与字符串字符串表示方式字符串表示方式用字符数组实现用字符数组实现例例 void main( ) char string=“I love China!; printf(“%sn, string); printf(“%sn, string+7); IloveChistring0string1string2string3string4string5string6string7string8string9stringstring10string11string12string13n!a0例例 void main( ) char *string=“I love China!; printf(“%sn,string); string+=7; while(*string) putchar(string0); string+; IloveChistringn!a0字符指针初始化字符指针初始化: :把字符串首地址赋给把字符串首地址赋给stringstring char char * *string;string; string

温馨提示

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

评论

0/150

提交评论