C语言程序ch9 指针_第1页
C语言程序ch9 指针_第2页
C语言程序ch9 指针_第3页
C语言程序ch9 指针_第4页
C语言程序ch9 指针_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

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

文档简介

1、共 84 页 第 1 1 页共 84 页 第 2 2 页1. 理解指针与地址的概念;理解指针与地址的概念;2. 掌握指针的定义和运算;掌握指针的定义和运算;3. 掌握指向基本类型、数组、字符串的指掌握指向基本类型、数组、字符串的指针的使用针的使用;4.充分理解指针和数组的等价性充分理解指针和数组的等价性; ;5.掌握指针函数和函数指针的使用;掌握指针函数和函数指针的使用;6.了解指向指针的指针的概念及其使用。了解指向指针的指针的概念及其使用。共 84 页 第 3 3 页内存:内存:就是内部存储器,是由存储单元组成就是内部存储器,是由存储单元组成 的。它的特点是存储单元是线性连续的。它的特点是存

2、储单元是线性连续 的。存储单元的最小单位是的。存储单元的最小单位是字节字节。 1. 内存的概念内存的概念共 84 页 第 4 4 页地址:地址:为了访问内存中的某个存储单元,我们为了访问内存中的某个存储单元,我们 要为它编号,这种编号称为要为它编号,这种编号称为内存地址内存地址。 通过地址我们就能够访问该地址所标通过地址我们就能够访问该地址所标 识的存储单元。识的存储单元。2. 地址的概念地址的概念共 84 页 第 5 5 页变量的地址:变量的地址:变量的地址是变量在内存中占用连续变量的地址是变量在内存中占用连续字节的首地址。字节的首地址。20072007存储单元共 84 页 第 6 6 页以

3、往对变量的访问以往对变量的访问: : 定义变量定义变量: int k;: int k;编译系统根据类型为编译系统根据类型为k k分配内存。分配内存。 输入变量的值输入变量的值:scanf(“%d”,&k); &k:scanf(“%d”,&k); &k就代表了变就代表了变量量k k在内存中的地址。在内存中的地址。 通过变量名访问变量通过变量名访问变量, ,这种操作称为这种操作称为直接访问直接访问; ;通过指针间接访问通过指针间接访问: :C C提供了另一种方式,将变量提供了另一种方式,将变量 k k的地址存放在另一个的地址存放在另一个变量处变量处( (假定为假定为pkpk) ),通过通过访问访问

4、 pkpk,就可以间接地访,就可以间接地访问变量问变量 k k,这种方式称为,这种方式称为间接访问间接访问。变量的存取方法:变量的存取方法:直接存取和间接存取。直接存取和间接存取。 共 84 页 第 7 7 页引入指针程序设计的优点引入指针程序设计的优点 有效表示复杂的数据结构。有效表示复杂的数据结构。 方便使用字符串、数组。方便使用字符串、数组。 可以得到多个返回值。可以得到多个返回值。 可以进行动态分配内存。可以进行动态分配内存。 程序简洁、紧凑程序简洁、紧凑, 执行效率高。执行效率高。共 84 页 第 8 8 页 9.1.1 9.1.1 指针的基本概念指针的基本概念u指针:一个变量的地址

5、称为该变量的指针。指针:一个变量的地址称为该变量的指针。u指针变量:若一个变量专用于指针变量:若一个变量专用于存放另一个变量存放另一个变量的地址(指针),的地址(指针),则称此变量为指针变量。则称此变量为指针变量。 若指针变量若指针变量p的值等于变量的值等于变量x的地址的地址, 则说指针变则说指针变量量p指向变量指向变量x。1000351000pxx的值p的值X的内存地址9.1 9.1 指针的基本概念及指针变量的定义指针的基本概念及指针变量的定义共 84 页 第 9 9 页指针的对象:指针的对象:当把变量的地址存入指针变量后,当把变量的地址存入指针变量后,就可以说就可以说这个指针指向了该变量这

6、个指针指向了该变量。 共 84 页 第 1010 页指针变量定义的一般形式:指针变量定义的一般形式: 类型标识符类型标识符 * *标识符标识符例例:float *p1;int *p2;作用:作用:定义变量为指针类型,使之专门用于存放定义变量为指针类型,使之专门用于存放地址地址。指针所指的指针所指的变量的类型变量的类型指针变量名指针变量名共 84 页 第 1111 页(1 1)* *用于定义指针变量,但指针变量名不带用于定义指针变量,但指针变量名不带* *。 如如 int int * *p1;p1; float float * *p2;p2; 定义的指针变量为定义的指针变量为p1,p2 p1,p

7、2 (2 2)一个指针变量只能指向同一类型的变量。)一个指针变量只能指向同一类型的变量。 如如 p1 p1 只能用于指向只能用于指向整型变量整型变量 p2 p2 只能用于指向只能用于指向实型变量实型变量(3 3)无论指针变量指向何种类型,指针变量本身都)无论指针变量指向何种类型,指针变量本身都是是整型整型的,指针变量本身也有自己的地址,占的,指针变量本身也有自己的地址,占两个两个字节字节的存储空间。的存储空间。 共 84 页 第 1212 页1.取地址运算取地址运算 & 格式格式: & 变量变量 设有变量说明设有变量说明 int a, b, *p, *q; p=&a; 把把a的地址赋给的地址赋

8、给p,使,使p指向指向a q=p; 让让q也指向也指向a,使,使p、q都指向都指向a p=&b; 让让p指向指向b,使,使q指向指向a,p指向指向b 9.2 9.2 指针变量的引用和运算指针变量的引用和运算C C语言提供两种与指针有关的运算符:语言提供两种与指针有关的运算符:& & * *共 84 页 第 1313 页 2. 取内容运算取内容运算 *格式:格式: * * 指针表达式指针表达式设设p p是一个指针表达式,则:是一个指针表达式,则:(1 1)若)若* *p p出现在赋值号左边,表示给出现在赋值号左边,表示给p p所指变量赋值所指变量赋值(2 2)若)若* *p p不出现在赋值号左边

9、,表示不出现在赋值号左边,表示p p所指变量的值所指变量的值 若有变量说明:若有变量说明:int a, int a, * *p ; p ; p=&a; p=&a; 让让p p指向变量指向变量a a * *p=10; p=10; 等价于等价于 a=10a=10 printf(“%d”, printf(“%d”, * *p); p); 打印打印p p所指变量的值所指变量的值 scanf(“%d”, &a); scanf(“%d”, &a); 给变量给变量a a输入值输入值 scanf(“%d”, p); scanf(“%d”, p); 给变量给变量a a输入值输入值 * *p+25 p+25 等价

10、于等价于a+25a+25共 84 页 第 1414 页3. 为指针变量赋初值为指针变量赋初值 指针变量使用前必须有值指针变量使用前必须有值 指针变量的初值必须是地址值指针变量的初值必须是地址值(不能是整数不能是整数) 方法方法 :在说明指针变量时同时初始化在说明指针变量时同时初始化 int a , *p = &a;(2) 使用赋值语句赋值使用赋值语句赋值 int a,*p; p =&a ; 可以为指针赋空值可以为指针赋空值(NULL),此时指针不指向任何,此时指针不指向任何 变量变量, 如如 p=NULL或或 p=0;p=0; ( p为空指针为空指针)共 84 页 第 1515 页若若pa=&

11、a pa=&a (将(将 a a 的地址送指针变量的地址送指针变量papa), , 则则 & &* *papa &( &(* *pa)pa) &(a) &(a) &a &a * *&a &a * *(&a)(&a) * *pa pa a a ( (* *pa)+ pa)+ a+ a+ * *pa+ pa+ * *(pa+) (pa+) (先取先取* *papa值,然后使值,然后使papa加加1 1) * *+pa +pa * *( (+pa+pa) ) (先使(先使papa加加1 1 ,再取,再取* *papa值)值)注意:此时pa不再指向a共 84 页 第 1616 页 例例 9-1 9-1

12、 输出变量的值。输出变量的值。 main( )main( ) int a,b; int a,b; int int * *pa, pa, * *pb; pb; a=100; b=10; a=100; b=10; pa=&a; pa=&a; pb=&b; pb=&b; printf(“%d,%dn”,a,b); printf(“%d,%dn”,a,b); printf(“%d,%dn”, printf(“%d,%dn”,* *pa,pa,* *pb);pb); 定义指针变量pa,pb将a的地址送pa将b的地址送pb输出所指向的变量运行结果为100,10100,10共 84 页 第 1717 页ma

13、in( ) int *p1 ,*p2 ,*p ,a ,b; scanf(“%d,%d”,&a,&b); p1=&a;p2=&b; if(a、=、 q pq p指针所指元素位于指针所指元素位于q q所指元素所指元素之后之后时为时为1 1,反之为,反之为0 0。 p p=q pq p指针所指元素位于指针所指元素位于q q所指元素所指元素之后之后(或两指针指向(或两指针指向同同一元素一元素)时为)时为1 1,反之为,反之为0 0。=和和!=!=运算符,比较的是两个指针表达式是否指向运算符,比较的是两个指针表达式是否指向同一个内同一个内存单元存单元; ; 、= 、=,比较的是两个指针所指内存区域的比较

14、的是两个指针所指内存区域的先后次序先后次序语法格式语法格式: 指针表达式指针表达式 关系运算符关系运算符 指针表达式指针表达式例:例:int a10; int int a10; int * *p=a, p=a, * *q=a+3;q=a+3;判断以下表达式的值判断以下表达式的值p=&a0 p=&a1 p=q p+4=q+2 pa+2 p=&a0 p=&a1 p=q p+4=q+2 pa+2 pq pq 共 84 页 第 2727 页 同类指针相减时,两个指针应该指向连续存放同类指针相减时,两个指针应该指向连续存放的同类数据区域。的同类数据区域。 语法语法 :p-qp-q 说明:说明: p-q

15、p-q 的值,等于的值,等于(p(p的值的值-q-q的值的值) )/ /所指类型长度所指类型长度, 即即p,qp,q两个指针之间数据元素的个数。两个指针之间数据元素的个数。 例如:若有例如:若有 int a10 , int a10 , * *p, p, * *q;q; p=a; p=a; q=&a5; q=&a5; 则则p-q=5 p-q=5 表示表示p,qp,q之间数据元素的个数是之间数据元素的个数是5 5。 共 84 页 第 2828 页格式格式: (类型名类型名 * ) 指针表达式指针表达式功能:将指针表达式的值转换成指定类型的指针。功能:将指针表达式的值转换成指定类型的指针。 例如例如

16、: int *p; double d, *q=&d; p=(int * )q;6. 强制类型转换运算强制类型转换运算共 84 页 第 2929 页 9.3.3 通过指针引用数组元素通过指针引用数组元素引用数组中的元素可以用以下方法:引用数组中的元素可以用以下方法: 下标法下标法 : 如如 a3,ai 指针法指针法: 即通过指向数组元素的指针找到所需的元素即通过指向数组元素的指针找到所需的元素. 这种方法占内存少这种方法占内存少, 运行速度快运行速度快,程序代码质量高。程序代码质量高。 假设假设p已定义为指针变量已定义为指针变量,并已赋了一个地址并已赋了一个地址,它指向某一它指向某一个数组元素个

17、数组元素. 且有赋值语句且有赋值语句p= &a0; 则:则: p+1 表示数组中的表示数组中的下一个元素下一个元素, a+i和和p+i都是都是ai 的地址,或者说它们指向的地址,或者说它们指向ai. *(a+i) 或或 *(p+i)是是a+i或或p+i所指向的数组元素。所指向的数组元素。 指向数组的指针变量也可带有下标,如指向数组的指针变量也可带有下标,如pi与与*(p+i)等等价。价。v对下标为对下标为i i的元素访问:的元素访问: ai,ai,* *(a+i),(a+i),* *(p+i),pi(p+i),piv对对aiai的地址表示:的地址表示: & &ai,a+i,p+i,&piai,

18、a+i,p+i,&pi 共 84 页 第 3030 页例例: 用三种方法输出数组全部元素。用三种方法输出数组全部元素。u下标法下标法:main( ) int a10, i; for(i=0;i10;i+) scanf(“%d”,&ai); printf(“n”); for(i=0;i10;i+) printf(“%5d”,ai); u地址法地址法(通过数组名计算数组元素地(通过数组名计算数组元素地址)址)for(i=0;i10;i+)printf(“%5d”,*(a+i);u指针法指针法for(p=a;p(a+10);p+)printf(“%5d”,*p );共 84 页 第 3131 页ma

19、in( )main( ) int a10, int a10,* *pa, i;pa, i; for (i=0;i10;i+) for (i=0;i10;i+) ai=i+1; ai=i+1; pa=a; pa=a; for(i=0;i10;i+,pa+) for(i=0;i10;i+,pa+) printf(“%d”, printf(“%d”,* *pa);pa); printf(“n”); printf(“n”); 不要忘记赋初值不要忘记赋初值如何修改程序可如何修改程序可以完成功能以完成功能? ?共 84 页 第 3232 页main( )main( ) int a10=5,7,3,6,2,

20、1,8,9,4,0; int a10=5,7,3,6,2,1,8,9,4,0; int i, int i, * *p,max;p,max; p=a; p=a; max= max=* *p+;p+; for(i=1; i10; i+, p+ ) for(i=1; imax ) max=pmax ) max=* *p ;p ; printf ( “max=%dn”, max); printf ( “max=%dn”, max); 问题问题: :如果修改语句如果修改语句for(i=1;i10; i+ ) for(i=1;imax) pmax) max= max=* *p+ ;p+ ;能实现程序功能吗

21、能实现程序功能吗? ?问题问题: :如果修改语句如果修改语句for(;pa+10; p+ ) for(;pmax) pmax) max= max=* *p ;p ;能实现程序功能吗能实现程序功能吗? ?共 84 页 第 3333 页9.3.4 字符串指针与字符串字符串指针与字符串u 用用字符数组字符数组表示,如:表示,如:main( ) char string =“I love China!”; printf(“%sn”,string);数组名数组名u 用用字符指针字符指针实现,如:实现,如:mian( ) char * string =“I love China!”; printf(“%sn

22、”,string);把“I love China!”的首地首地址赋址赋给指针变量string特点特点: :字符串的长度不受字符串的长度不受限制限制; ;字符指针指向别处字符指针指向别处, ,字符串将失踪字符串将失踪. .共 84 页 第 3434 页2.字符指针变量与字符数组的比较字符指针变量与字符数组的比较u字符数组由若干个元素组成,每个元素中放一个字符,字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址。而字符指针变量中存放的是字符串的首地址。 赋值方式:赋值方式: char str =“I am a boy!” 或:或: char str20; sca

23、nf(“%s”,str);u字符指针变量指向字符串首地址。字符指针变量指向字符串首地址。赋值方法三种:赋值方法三种: (1) char *pa=“I am a boy!” (2) char *pa; pa=“I am a boy!” (3) char *pa, str20; pa=str; scanf(“%s”,pa);共 84 页 第 3535 页 例例9-5 9-5 已知下面程序的输出结果已知下面程序的输出结果:ABCDCD,:ABCDCD,请完善请完善程序程序: : main() main() char char * *chp=“ABCD”;chp=“ABCD”; for( ; _A_;

24、 chp=chp+2) for( ; _A_; chp=chp+2) printf(“%s”, _B_); printf(“%s”, _B_); printf(“n”); printf(“n”); A. *chp!=0B. chp共 84 页 第 3636 页作用:作用: 函数的参数不仅可以是整型、实型、字符函数的参数不仅可以是整型、实型、字符型,还可以是指针型,型,还可以是指针型,它的作用是将一个变量它的作用是将一个变量的地址传送到另的地址传送到另外外一个函数中。一个函数中。9. 4 指针与函数指针与函数9.4.1 9.4.1 指针变量作函数参数指针变量作函数参数共 84 页 第 3737

25、页swap(x,y)int x,y; int t; t=x; x=y; y=t;main( ) int a,b; scanf(“%d,%d”,&a,&b); if(ab) swap(a,b); printf(“%d,%dn”,a,b); 调用函数时调用函数时a的值传送给的值传送给x,b值值传送给传送给y,可是执行完函数后可是执行完函数后,x和和y的值是互换了的值是互换了,但但a,b的值并未的值并未互换。互换。共 84 页 第 3838 页swap(int *p1,int *p2) int p; p=*p1; *p1=*p2; *p2=p;main( )int a,b; int *pa, *pb

26、; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa,pb); pintf(“%d,%dn”,a,b); 运行情况:运行情况:5,9 9,5交换指针所指交换指针所指向的向的变量的值变量的值例:将两个数按从大到小顺序输出例:将两个数按从大到小顺序输出(交换两个变量的值)。交换两个变量的值)。结论:被调用函数不能改变实参指针变结论:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指量的值,但可以改变实参指针变量所指向的变量的值。向的变量的值。共 84 页 第 3939 页函数调用过程如下图所示函数调用过程如下图所示:调用swap函数之

27、前:pa &a 5 a &b pb 9 b共 84 页 第 4040 页 &ap1 &bp2 5 &apa a 9 &bpb b &a 9 &apap1 a 5 &b &bpbp2 b执行函数语句,执行函数语句,p1、p2所指所指向的变量的值相互交换向的变量的值相互交换*p1*p2共 84 页 第 4141 页pa &a 9 a &b 5 pb b函数调用结束后,函数调用结束后,p1、p2所占所占用的内存单元被释放,用的内存单元被释放,共 84 页 第 4242 页swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p; main( )int a,b;i

28、nt *pa, *pb; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa, pb);printf(“%d,%dn”,*pa,*pb);C语言中,实参和形参间的数据是单向值传递方式。语言中,实参和形参间的数据是单向值传递方式。指针做函数参数也遵循该原则指针做函数参数也遵循该原则.结果为结果为:?:?交换了两个指针中的内容。共 84 页 第 4343 页 9.4.2 数组名作函数参数数组名作函数参数 当用数组名作为参数时,如果形参数组中元素当用数组名作为参数时,如果形参数组中元素的值发生变化,实参数组元素的值也随之变化,的值发生变化,实参数组元

29、素的值也随之变化,为为什么?什么? 若有一个实参数组,想在函数中改变此数组的若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下元素的值,实参与形参的对应关系有以下4 4种情况:种情况: 形参与实参都用数组名形参与实参都用数组名 实参用数组名,形参用指针变量实参用数组名,形参用指针变量 实参形参均用指针变量实参形参均用指针变量 实参为指针变量,形参为数组名实参为指针变量,形参为数组名都是地址传递,只是形式不同!都是地址传递,只是形式不同!共 84 页 第 4444 页u指针变量在作实参时,必须有确定的值,即指向一个指针变量在作实参时,必须有确定的值,即指向一个已定义的单

30、元。已定义的单元。 如:如:main()main() int int * *p;p; f(p,10); f(p,10); int f(int x ,int n int f(int x ,int n) 错误!如何修改?如何修改?共 84 页 第 4545 页例例9-6:用选择法对:用选择法对10个整数由小到大排序。个整数由小到大排序。方法方法1:形参和实参都用数组名:形参和实参都用数组名(在函数中介绍的在函数中介绍的)main( ) int i, a10;void sort( );for(i=0;i10;i+) scanf(%d”,&ai);sort(a,10);for(i=0; i10 ;i+

31、) printf(%d, ai); void sort( int x , int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;jxj) t=xi; xi=xj; xj=t; 形参是数组名形参是数组名实参也是数组名实参也是数组名共 84 页 第 4646 页方法方法2:形参是数组名,实参是指针变量。:形参是数组名,实参是指针变量。main( ) int *p, i, a10;void sort( );p=a;for(i=0;i10;i+) scanf(%d,p+);sort(p,10);for(p=a, i=0; i10 ;i+) printf(%d, *

32、p+); void sort( int x, int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;jxj) t=xi; xi=xj; xj=t; p=a;形参是数组名形参是数组名实参是指针实参是指针当用数组名作函数参数时,由于当用数组名作函数参数时,由于数组名代表的是数组首元素地址,数组名代表的是数组首元素地址,因此传递的是地址,所以要求实因此传递的是地址,所以要求实参为指针变量。参为指针变量。共 84 页 第 4747 页方法方法3:实参是数组名,形参是指针变量。:实参是数组名,形参是指针变量。void sort( int *x, int n) int

33、 i,j, t; for(i=0;in-1;i+) for(j=i+1;j*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t; 实参是指针实参是指针main( ) int i, a10;void sort( );for(i=0;i10;i+) scanf(%d”,&ai);sort(a,10);for(i=0; i10 ;i+) printf(%d , ai); 形参是指针形参是指针实参是数组名实参是数组名共 84 页 第 4848 页方法方法4:实参和形参都是指针变量。:实参和形参都是指针变量。void sort( int*x, int n) int i,j,

34、t; for(i=0;in-1;i+) for(j=i+1;j*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t; 实参是指针实参是指针main( ) int *p, i, a10;void sort( );p=a;for(i=0;i10;i+) scanf(%d,p+);p=a;sort(p,10);for(p=a, i=0; iy) z=x; else z=y; return (z);指向函数的指针指向max函数共 84 页 第 5959 页在一个程序中,一个指针变量可以先后指向不同在一个程序中,一个指针变量可以先后指向不同的函数;的函数; 例如:例如: in

35、t (int (* *p)( );p)( ); int max( ); int max( ); int min( ); int min( ); p=max; c=( p=max; c=(* *p)(a , b); p)(a , b); p=min; c=( p=min; c=(* *p)(a , b);p)(a , b);P先于先于*结合,是指针变量,结合,是指针变量,然后再与()结合,表示此然后再与()结合,表示此指针变量指向函数。指针变量指向函数。共 84 页 第 6060 页实参函数名实参函数名f1 f2 sub( x1, x2)int(*x1)( ),(*x2)( );int a,b,

36、i,j;a=(*x1)(i);b=(*x2)(i,j);定义x1,x2为函数指针变量调用f1函数调用f2函数指向函数的指针变量作函数参数指向函数的指针变量作函数参数: :共 84 页 第 6161 页9.5 指针与二维数组指针与二维数组9.5.1 二维数组的结构二维数组的结构 数组的名代表该数组的首地址,并可看成是地址数组的名代表该数组的首地址,并可看成是地址常量,这一规定对二维数组或更高维数组同样适用。常量,这一规定对二维数组或更高维数组同样适用。若有定义:若有定义: float *p, d35; d0,d1,d2 分别是一维数组名,表示一维数组的首分别是一维数组名,表示一维数组的首地址,地

37、址,p=d0是正确的。是正确的。d可以把可以把d看成是由看成是由3个一维数组个一维数组组成,即组成,即d0,d1,d2共 84 页 第 6262 页 a a代表整个二维数组的首地址,即代表整个二维数组的首地址,即第第0 0行的首地址行的首地址 a+1a+1是数组是数组a a第第1 1行首地址行首地址(208)(208) a0,a1,a2a0,a1,a2是二维数组中三个是二维数组中三个一维数组的名字(地址),是第一维数组的名字(地址),是第0 0行,第行,第1 1行,第行,第2 2行的首地址,即:行的首地址,即:a0=a+0a0=a+0、a1=a+1a1=a+1、a2=a+2a2=a+2 ai+

38、jai+j是第是第i i行行j j列的地址列的地址 * *(ai+j)(ai+j)是该地址存储的值,是该地址存储的值, 即即aijaij考虑考虑 * *(a2+3)=?(a2+3)=?a0a1a2a数组数组a (200)a+1a+2(216)假设数组名为假设数组名为a,起始地址设为,起始地址设为200,按行优先存放按行优先存放, int a34=1,3,5,7,9,11,13,15,17,19,21,23;则:则:9.5.2 二维数组元素及其地址二维数组元素及其地址共 84 页 第 6363 页 aiai和和* *(a+i)(a+i)无条件等价无条件等价 a+ia+i、aiai、* *(a+i

39、)(a+i)、&ai0&ai0均表示第均表示第i i行首行首地址;地址; &aij&aij、 ai+jai+j、* *(a+i)+j(a+i)+j都是第都是第i i行行j j列元列元素的素的地址地址; aijaij、 * *( (ai+jai+j) )、* *( (* *(a+i)+j(a+i)+j) )都是第都是第i i行行j j列元素的列元素的值值;共 84 页 第 6464 页int i,j;main( ) int *p, a34, b34, c34; printf(The value of a:n); for(i=0; i3; i+) for(j=0; j4; j+) scanf(%d

40、,ai+j); printf(The value of b:n); for(i=0; i3; i+) for(j=0; j4; j+) scanf(%d, *(b+i)+j);例例9-11: 将将a矩阵与矩阵与b矩阵相加矩阵相加,计算结果存入计算结果存入c矩阵。矩阵。表示表示a数组第数组第i行第行第j列元素的列元素的地址地址表示表示b数组第数组第i行第行第j列元素的列元素的地址地址共 84 页 第 6565 页 matrix(*a, b0, &c00); printf(The value of c:); for(i=0, p=c0; pc0+12; p+,i+) if (i%4=0) prin

41、tf(n); printf(%-4d,*p); matrix(int *x, int *y, int *z) for(i=0; i3; i+) for(j=0; j4; j+) *(z+i*4+j)=*(x+i*4+j)+ *(y+i*4+j); 数组元素在内存中按数组元素在内存中按“行优先行优先”的顺序存放,因此可用的顺序存放,因此可用x+i*4+j表示二维数组各元素的地址,表示二维数组各元素的地址,相当于相当于&xij ,*(x+i*4+j)就是就是取该元素的值。取该元素的值。*a相当于相当于*(a+0),即即a0表示表示a数组第数组第0行第行第0列元素的地址。列元素的地址。b0表示表示

42、b数组第数组第0行第行第0列元素的地址。列元素的地址。&c00表示表示 c数组第数组第0行第行第0列元素的地址。列元素的地址。计算计算aij在数组中相对位置的在数组中相对位置的计算公式为:计算公式为:i*m+jm为二维数组的列数为二维数组的列数共 84 页 第 6666 页 例例9-12 将矩阵将矩阵A转置后存放到矩阵转置后存放到矩阵B中,中, 即:即:bji=aij (下标法下标法)main()int a34,b43,i,j;for(i=0;i3;i+) for(j=0;j4;j+) scanf(%d,&aij);for(i=0;i3;i+) for(j=0;j4;j+) bji=aij;f

43、or(i=0;i4;i+) for(j=0;j3;j+) printf(%5d,bij); printf(n); 共 84 页 第 6767 页指针法(方法指针法(方法1) main()int a34,b43,i,j,*p,*q;p=&a00;q=&b00;for(i=0;i3;i+) for(j=0;j4;j+) scanf(%d,p+i*4+j);for(i=0;i3;i+) for(j=0;j4;j+) bji=aij;for(i=0;i4;i+) for(j=0;j3;j+) printf(%5d,*(q+i*3+j); printf(n); 将指针变量将指针变量p,q指向指向两数组的

44、开始位置两数组的开始位置利用指针利用指针p为数组为数组a输入数据输入数据利用指针利用指针q输出数组输出数组b这里的指针变量这里的指针变量p和和q都是用都是用int *p,*q定义的定义的是指向整型数据的,是指向整型数据的,p+1是指向是指向p所指向的下所指向的下一个元素。能否使一个元素。能否使p不是指向整型变量,而不是指向整型变量,而是指向一个包含是指向一个包含m个元数的一维数组呢?个元数的一维数组呢?共 84 页 第 6868 页1. 1. 定义格式定义格式 类型说明符类型说明符 (* *变量名)变量名) 正整型常量表达式正整型常量表达式 2. 2. 功能功能 定义一个名为定义一个名为“变量

45、名变量名”的指针变量,这个指针的指针变量,这个指针变量所指的对象是一个变量所指的对象是一个有有“正整型正整型常量表达式常量表达式”个元素的一维数组。个元素的一维数组。例如:例如:int a34,(int a34,(* *p)4=a;p)4=a;定义定义p p是一个指针变量,它指向包含是一个指针变量,它指向包含4 4个整型元素的个整型元素的一维数组。一维数组。 p p的值就是该一维数组的起始地址。的值就是该一维数组的起始地址。a0a1a2p,ap+1p+2共 84 页 第 6969 页main( )main( ) int int a34=1,3,5,7,9,11,13,15,17,19,21,2

46、3;a34=1,3,5,7,9,11,13,15,17,19,21,23; int int * *p p,i,j ;,i,j ; p=a; p=a; scanf(“%d,%d”,&i,&j); scanf(“%d,%d”,&i,&j); printf(“a%d%d=%dn”, i , j, printf(“a%d%d=%dn”, i , j,* *(p+i(p+i* *4+j)4+j);); 输入输入1,21,2运行结果:运行结果:a12=13a12=13这里的指针变量这里的指针变量p是定义为指向整型数据的是定义为指向整型数据的aij在数组中在数组中的位置用相对于的位置用相对于数组起始位置的数

47、组起始位置的相对移位量计算相对移位量计算共 84 页 第 7070 页main( )main( ) int int a34=1,3,5,7,9,11,13,15,17,19,21,23;a34=1,3,5,7,9,11,13,15,17,19,21,23; int ( int (* *p)4,i,j ;p)4,i,j ; p=a; p=a; scanf(“%d%d”,&i,&j); scanf(“%d%d”,&i,&j); printf(“a%d%d=%dn”,i,j, printf(“a%d%d=%dn”,i,j,* *( (* *(p+i)+j);(p+i)+j); 输入输入1,21,2运

48、行结果:运行结果:a12=13a12=13 1 3 5 7 9 11 13 1517 19 21 23p,ap+1p+2a0a1a2=第第i行行j列元素的地址列元素的地址为:为:*(p+i)+j第第i行行j列元素的值为:列元素的值为:*(*(p+i)+j)这里的指针变量这里的指针变量p不是指不是指向整型变量,而是指向一向整型变量,而是指向一个包含个包含4个整型元素的一维个整型元素的一维数组。数组。共 84 页 第 7171 页例例9-15 阅读下面程序。阅读下面程序。 main( )int i;int *q,(*p)4,a34=2,4,6,8,10,12,14,16,18,20,22,24;

49、q=a0; for(i=1;i=0;i-) printf(%dt, *(pi+i); printf(n);程序运行结果:程序运行结果: 2 6 10 14 22 12 2 第第i行行j列元素的地址列元素的地址为:为:pi+j第第i行行j列元素的值为:列元素的值为:*(pi+j)q q是定义为指向整型数据的是定义为指向整型数据的P P指向一个包含指向一个包含4 4个整型元素的个整型元素的一维数组。一维数组。共 84 页 第 7272 页定义一个由定义一个由 6 6个个指针变量构成的指针变量构成的指针数组指针数组,数组中,数组中的每个数组元素都是一个指向一个整数的指针变量。的每个数组元素都是一个指

50、向一个整数的指针变量。整数整数整数整数整数整数整数整数整数整数整数整数pa0pa1pa2pa3pa4pa5指针数组指针数组pa指针数组指针数组: :数组中的数组中的元素元素均为均为指针类型指针类型。适合用来指向字符串。适合用来指向字符串1.1.定义形式:定义形式:数据类型数据类型 * * 数组名数组名 常量表达式常量表达式 例如:例如: int int * *pa6;pa6;2.2.功能:功能:9.6 9.6 指针数组指针数组共 84 页 第 7373 页 必须用地址值为指针数组初始化必须用地址值为指针数组初始化 int a33 = 1,2,3,4,5,6,7,8,9,int a33 = 1,

51、2,3,4,5,6,7,8,9,* *pa3;pa3; pa0=a0;pa1=a1;pa2=a2; pa0=a0;pa1=a1;pa2=a2; 1 2 34 5 67 8 9a0a1a2*pa0*pa1*pa2指针数组指针数组*pa3 相当于有三个指针,相当于有三个指针,*pa0,*pa1,*pa2 初始化的结果初始化的结果:共 84 页 第 7474 页对指针数组中的任意一个对指针数组中的任意一个pai,移动移动j个元素,有:个元素,有: pai+j = ai+j = &aij;*(pai+j) = *(ai+j) = aij;指针与数组的等价性:指针与数组的等价性:*(a+i )=*(pa

52、+i )=a i ; 指针数组与二维数组是等价的,通过指针数组指针数组与二维数组是等价的,通过指针数组可以引用二维数组中的元素。可以引用二维数组中的元素。注意:注意: int int * *p5 p5 与与 int (int (* *p)5 p)5 不同不同共 84 页 第 7575 页 字符串数组:字符串数组:数组中的每个元素都是存放字符的数组。数组中的每个元素都是存放字符的数组。 字符串数组的每一行可存放一个字符串。字符串数组的每一行可存放一个字符串。 用赋初值的方式给字符串数组赋值:用赋初值的方式给字符串数组赋值:直接给字符串数组赋初值直接给字符串数组赋初值若有定义:若有定义:char

53、b48= Turbo C, FORTRAN, BASIC, Foxpro;此定义还可以写成:此定义还可以写成:char b8= Turbo C, FORTRAN, BASIC, Foxpro;由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。9.7 9.7 指针与字符串数组指针与字符串数组共 84 页 第 7676 页用给字符型指针数组赋初值的方式构成字符串数组用给字符型指针数组赋初值的方式构成字符串数组若有定义:若有定义:char *f4= Turbo C, FORTRAN, BASIC, Foxpro;此定义还可以写成:此定

54、义还可以写成:char *f= Turbo C, FORTRAN, BASIC, Foxpro;则数组则数组f中的每个元素都存放着对应的一个字符串的中的每个元素都存放着对应的一个字符串的首地址首地址,各字符串依次存入各相应的首地址开始的连续存储单元中。各字符串依次存入各相应的首地址开始的连续存储单元中。 F O R T R A N 0 B A S I C 0F o x p r o 0f0f1f2f3 T u r b o C 0节省内存空间!共 84 页 第 7777 页例9-16#include “stdio.h”main( )char *s4=“dog”,“cat” , “pig”, “all animals”; int i; for (i=0; i 1)while (argc1

温馨提示

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

评论

0/150

提交评论