C语言谭浩强版指针课件

上传人:re****.1 文档编号:569534668 上传时间:2024-07-30 格式:PPT 页数:59 大小:1.30MB
返回 下载 相关 举报
C语言谭浩强版指针课件_第1页
第1页 / 共59页
C语言谭浩强版指针课件_第2页
第2页 / 共59页
C语言谭浩强版指针课件_第3页
第3页 / 共59页
C语言谭浩强版指针课件_第4页
第4页 / 共59页
C语言谭浩强版指针课件_第5页
第5页 / 共59页
点击查看更多>>
资源描述

《C语言谭浩强版指针课件》由会员分享,可在线阅读,更多相关《C语言谭浩强版指针课件(59页珍藏版)》请在金锄头文库上搜索。

1、第十章 指针指针10.1 地址和指针的概念10.2 指针定义和引用10.3 指针与数组10.4 指针与字符串10.1 地址和指针的概念一、数据的存取一、数据的存取1、内存地址内存的每个字节都有一个编号,这个编号称为“内存地址”。低地址高地址2000200220043000程序中的每个数据都对应着内存中的一个地址,从该地址开始的一个或多个字节用来存放该数据。int i, j, k;ijk2、内存单元的地址和内存单元的内容的区别:若i=3, j=5; 从图中可以看出它们的区别。程序编译后已经没有i、j、k这些变量名了,而是将变量名转换为变量的地址,计算机通过内存地址对变量进行存取。二、直接访问和间

2、接访问二、直接访问和间接访问1、直接访问方式:低地址高地址2000200220043000ijk、i=3;、j=i+2;、printf(%d, i);、scanf(%d, &i);、k=i+j; 如何执行?按变量的地址存取变量的方式2、间接访问方式:语言中可以定义整型变量、实型变量、字符型变量,各自存放相应类型的数据;另外还可以定义和使用一种特殊类型的变量,用来存放变量的地址用来存放变量的地址用来存放变量的地址用来存放变量的地址。低地址高地址2000200220043000ijk假设已经定义变量 ip 用来存放整型变量的地址,它被分配到内存单元3000和3001。ip通过执行语句:ip=&i;

3、 将整型变量i 的地址存放到变量ip中,即ip的值为变量i所对应的内存单元的起始地址2000。2000现在要存取i的值可以这样做:先找到存放i的地址的内存单元地址(3000和3001),从中取出变量i的地址(2000),然后再对2000和2001单元进行存取这就称为间接访问。3、关于“指向”的含义:变量ip的值为2000,即变量i的地址,这样就在ip和i之间建立了一种联系:通过变量ip知道变量i的地址,从而找到变量i的内存单元,因此说变量ip指向变量i,用箭头表示这种“指向”关系。20003000ip2000i4、为了表示将数值10送到变量i中,可以有两种表示方法:、将10送到变量i所标志的单

4、元中;2000i10、将10送到变量ip所指向的单元中;20003000ip2000i10三、指针与指针变量三、指针与指针变量通过地址能找到所需的变量单元,可以说:地址“指向”该变量单元。因此,把一个变量的地址称为该变量的“指针”。低地址高地址2000200220043000ijkip2000如果一个变量专门用来存放另一个变量的地址,则称它为“指针变量”。指针变量的值(即指针变量中存放的值)是指针(地址)。注意区分“指针”和“指针变量”这两个概念。四、说明四、说明、程序中定义的每个变量在编译后都占有各自的内存单元,系统是通过内存地址对变量进行存取的;、数据所占有的内存单元个数是由其数据类型决定

5、的;、首地址:即第一个单元的地址;、表示地址的数与整数的区别;、变量i、j的地址可能相邻,也可能不相邻,是由系统分配的,我们不必关心。10.2 指针变量的定义和引用10.2.1 概述1 1、指针运算符:、指针运算符:*为了表示指针变量和它所指向的变量之间的联系,用“*”表示指向的关系。如:ip代表指针变量,*ip表示ip所指向的变量。即*ip也代表一个变量。 例:、若:ip=&i;i=5;*ip=5;结论:*ip与i等价。、x=i+1;x=*ip+1;2 2、取地址运算符:、取地址运算符:&它与一个变量连用,以得到该变量的内存地址。3 3、说明:、说明:、取地址运算符只能作用于变量:&x, &

6、a5;不能作用于常量、表达式或寄存器变量:&25, &(i+1);、不能把整数赋值给一个指针变量:ip=3000;、不能把一个指针变量的值赋值给一个整型变量:x=ip;10.2.2 指针变量的定义与赋值一、指针变量的定义一、指针变量的定义1、格式:类型名 *指针变量名其中:、“*”表示定义的是指针变量;、“类型名”用来指定该指针变量可以指向的变量的类型;2、例:int i, *ip;int *p1, *p2;float x, *xp;char *cp1, *cp2;3、说明:、“*”只表示定义的变量为指针变量,但指针变量名中并不包含“*”;*是指针变量的标志,不可丢掉;、指针变量定义时,指定了

7、它所指向的变量的数据类型;ip=&i;p1=&i;xp=&i; cp1=&x;xp=&x;指针变量定义时必须指定其所指向的变量的数据类型,而且使用过程中只能指向同一种类型的变量。、指针变量定义后,系统为变量分配一个存储单元,用来存放地址。、指针变量定义后,若不赋值,其值是不确定的。二、指针变量的赋值二、指针变量的赋值1、赋值语句:int i, j, *p1, *p2;p1=&i; p2=&j;char ch, *cp1, *cp2;cp1=&ch; cp2=&ch;2、初始化:int x=4;int x;x=4int i, *p1=&i;int i, *p1;p1=&i;3、说明:、指针变量定

8、义后,若不赋值,其值是不确定的;、可以给指针变量赋空值(NULL),使指针变量不指向任不指向任不指向任不指向任何变量何变量何变量何变量;ip=NULL;ip=NULL;、指针变量的值为空值(NULL)与未对指针变量赋值,意义不同;、只能是同类型变量的地址进行赋值;int i, *ip;char ch, *cp;ip=&i;cp=&ch;ip=&ch;cp=&i;、可以将数组名赋给某些类型的指针变量;int a10, *ip; ip=&a0;ip=a;、不能将一个整型量(或任何其它非地址类型的数据)赋给一个指针变量;int *ip;ip=3000;4、分析有关指针的程序时,画图是很好的方法:若有

9、:int i, *p;p=&i;i=5;int i, *p;不定i不定pp=&i;&ii=5;510.2.3 指针变量的引用int a, *p1, *p2;p1=&a;printf(“%x”, p1); p1?p2=p1;*p1=3;printf(%d, *p1);int a, *p1, *p2;不定a不定p1不定p2p1=&a;&aprintf(%x, p1);p2=p1;&a*p1=3;3printf(%d, *p1);1、两个运算符:&和*&:取地址运算符;*:指针运算符(间接访问符);2、说明:、&既可作用于一般变量,也可作用于指针变量;、*只能作用于指针变量;、表达式中的*p与变量定

10、义中的*p含义不同;int i, *p=&i;*p=5; int a, *p=&a;int a, *p;p=&a;int a, *p;*p=&a;3、指针变量可以进行的操作:int a, *p1, *p2;、赋值: p1=&a;p2=p1;、输出:printf(%x, p1);、取内容:*p1=5;a=5;printf(%d, *p1);、增减:p1+;p2-;p1+=4; (只能和一个整数只能和一个整数)例10.1#include main( ) int a1=11, a2=22; int *p1, *p2; p1=&a1; p2=&a2; printf(%d, %dn, *p1, *p2)

11、; p2=p1; printf(%d, %dn, *p1, *p2);11a122a2不定p1不定p2&a1&a2*p1*p2&a1*p2*p2多个指针可以指向同一个存储单元。但在某一时刻,一个指针变量只能指向一个存储单元,因为指针变量在某一时刻只能存放一个变量的地址值。例10.2#include void main( ) int a1=11, a2=22; int *p1, *p2, *p; p1=&a1; p2=&a2; printf(%d, %dn, *p1, *p2); p=p1; p1=p2; p2=p; printf(%d, %dn, *p1, *p2);11a122a2不定p1不

12、定p2不定p&a1&a2*p1*p2&a1&a2*p1*p1&a1*p2*p2使两个指针交换指向使两个指针交换指向使两个指针交换指向使两个指针交换指向例10.3#include main( ) int a1=11, a2=22, t; int *p1, *p2; p1=&a1; p2=&a2; printf(%d, %dn, a1, a2); t=*p1; *p1=*p2; *p2=t; printf(%d, %dn, a1, a2);11a122a2不定t不定p1不定p2&a1*p1&a2*p2112211交换两个指针变量所指向变量的值交换两个指针变量所指向变量的值交换两个指针变量所指向变量

13、的值交换两个指针变量所指向变量的值反映了指针变量的引用方法:反映了指针变量的引用方法:反映了指针变量的引用方法:反映了指针变量的引用方法:、将变量的地址赋给指针变量(p1=&a1)、将一个指针变量赋给另一个指针变量(p2=p1)、通过指针变量间接访问它所指向的变量(*p1)4、*和&运算符的进一步说明:、若有:p1=&a; 则*p1等价于a;&*p1&(*p1)&a、 *&a*(&a)*pa、(*p)+等价于:a+不同于:*p+*p+*(p+)10.2.4 指针作为函数参数题目:输入两个整数a、b,按大小顺序输出。#include s x, int y) int temp; temp=x; x

14、=y; y=temp; main( ) int a, b; printf(nInput a, b: ); scanf(%d%d, &a, &b); if (ab) swap(a, b); printf(max=%d, min=%dn, a, b);注意:语言中的函数调用采用语言中的函数调用采用语言中的函数调用采用语言中的函数调用采用“ “传值传值传值传值” ”方式,即单向传方式,即单向传方式,即单向传方式,即单向传递方式。递方式。递方式。递方式。即:即:即:即:主调函数可以将实参主调函数可以将实参主调函数可以将实参主调函数可以将实参的值传递给被调函数的值传递给被调函数的值传递给被调函数的值传递

15、给被调函数的形参,但不能通过的形参,但不能通过的形参,但不能通过的形参,但不能通过改变形参的值而改变改变形参的值而改变改变形参的值而改变改变形参的值而改变实参的值。实参的值。实参的值。实参的值。#include s *px, int *py) int temp; temp=*px; *px=*py; *py=temp;void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, &a, &b); p1=&a; p2=&b; if (ab) s, p2); printf(max=%d, min=%dn, a, b);5a8

16、b&ap1&bp2不定px不定py&a&b858a5b&ap1&bp2#include void s *px, int *py) int *temp; *temp=*px; *px=*py; *py=*temp;void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, &a, &b); p1=&a; p2=&b; if (ab) s, p2); printf(max=%d, min=%dn, a, b);*temp是指针变量是指针变量temp所所指向的变量,但指向的变量,但temp中并无中并无确定的地址值,其值不确定

17、;确定的地址值,其值不确定;*temp所指向的单元也不确定。所指向的单元也不确定。因此,对因此,对*temp赋值可能会破赋值可能会破坏系统的正常工作状况。坏系统的正常工作状况。应该将*px的值赋给一个整型变量,用整型变量作为临时存储空间实现*px和*py的交换。#include void s *px, int *py) int *p; p=px; px=py; py=p;void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, &a, &b); p1=&a; p2=&b; if (ab) s, p2); printf

18、(max=%d, min=%dn, a, b);5a8b&ap1&bp2不定px不定py&a&b&b&a5a8b&ap1&bp2如果想通过函数调用得到几个要改变的值,可以:如果想通过函数调用得到几个要改变的值,可以:如果想通过函数调用得到几个要改变的值,可以:如果想通过函数调用得到几个要改变的值,可以:、在主调函数中设n个变量;、将n变量的地址作为实参传给所调用的函数的形参;、通过形参指针变量,改变该n个变量的值;、主调函数就可以使用这些改变了的值;10.3 指针与数组10.3.1 指向数组元素的指针变量1、几个概念、一个变量有地址,称变量的地址为该变量的指针指针指针指针;、每个数组都有一个起

19、始地址,数组的起始地址称为数组的指针数组的指针数组的指针数组的指针;、一个数组包含若干元素,每个数组元素都在内存中占用一定的存储单元,即都有相应的地址,数组元素的地址称为数组元素的指针数组元素的指针数组元素的指针数组元素的指针;、指针变量可以指向变量,当然也可以指向数组和数组元素;、数组元素的指针变量数组元素的指针变量数组元素的指针变量数组元素的指针变量就是专门用来存放数组元素地址的变量。2、定义:类型名 *指针变量名int a10;int *p;int a10, *p;a0a1a2a3a4a5a6a7a8a9a a不定p3、赋值:p=&a0;&a04、说明:、语言中的数组名代表数组首地址,即

20、第0号元素的地址;p=&a0;p=a;、定义时可以进行初始化:int *p=&a0;int *p;p=&a0;int *p;*p=&a0;int *p=a;10.3.2 通过指针访问一维数组1、数组元素的引用:int a10, *p;p=a;*p=5;a0=5;p=&a3;*p=5;a3=5;2、语言规定:无论数组的数据类型如何,若指针变量p已指向数组中的某一元素,则p+1指向同一数组中的下一个元素(而不是将p简单的加1)例如:、int x10, *p=x;对于指向整型数组的指针变量p,p+1意味着使p在原值的基础上加2 2个字节个字节个字节个字节,以使它指向下一元素;、float x10,

21、*p=x;对于指向float型数组的指针变量p,p+1意味着使p在原值的基础上加4 4个字节个字节个字节个字节,以使它指向下一元素;总之:总之:总之:总之:设d是一个数组元素所占的字节数,则p+i表示指针移动了i个元素,而它实际的地址变化为:p+i*d。3、在使用指针变量引用数组时,应注意以下问题:、给指针赋初值的方法:p=a; 或p=&a0;、p+1或a+1实际上表示数组元素a1的地址(&a1);则p+i或a+i表示数组的第i个元素的地址(&ai);、*(p+i)或*(a+i)表示p+i或a+i所指向的数组元素,即ai;、指向数组的指针变量也可以带下标;如:pi与*(p+i)等价;、若p已经

22、指向某个数组元素ai,则p+j表示指向数组元素ai+j;综上,可以用两种方法来引用一个数组元素:、下标法下标法:用ai或pi来引用数组a中的第i号元素;、指针法指针法:用*(p+i)或*(a+i)来引用数组中的第i号元素;可见:任何由数组下标完成的操作都能由指针来实现任何由数组下标完成的操作都能由指针来实现任何由数组下标完成的操作都能由指针来实现任何由数组下标完成的操作都能由指针来实现;ai*(p+i)&aip+i4、在使用指针变量时,要注意以下几个问题:、可以使用p+使指针变量p的值不断改变:for (p=a; p(a+10); p+) printf(%4d, *p);、在程序运行期间,要始

23、终注意指针变量当前所指向的是哪一个元素;、注意指针变量的运算:若p指向数组的开始,即:p=a;、p+; 使p指向下一元素,即a1;、*p+; 等价于*(p+);for (i=0,p=a; i10; i+) printf(%4d, *p+);、注意*(p+)与*(+p)的区别;、(*p)+表示p所指向的元素值加1;、若指针变量指向数组的第i号元素,则:*(p-)相当于ai-*(-p)相当于a-i*(+p)相当于a+i10.3.3 通过指针在函数间传递一维数组1、数组元素作为函数参数:s x, int y);swap(a1, a2);2、数组名作为函数参数: f(int x , int n);f(

24、a, 10);数组名代表数组首地址。用数组名作实参,数组名代表数组首地址。用数组名作实参,调用函数时是把数组首地址传递给形参,而不调用函数时是把数组首地址传递给形参,而不是把数组的值传给形参。是把数组的值传给形参。a0a1a2a3a4a5a6a7a8a9a ax xx0x1x2x3x4x5x6x7x8x9实际上能够接受并存放地址值的只能是指针变量,编译系统都是将形参数组名作为指针变编译系统都是将形参数组名作为指针变量来处理的量来处理的。f(int *x, int n);f(int *x, int n);xi*(x+i)若在函数调用期间改变了数组某一存储单元的内容,则在函数调用完毕后,已改变的值

25、被保留下来。变量名与数组名作函数参数时的比较:实参类型实参类型实参类型实参类型变量名变量名变量名变量名数组名数组名数组名数组名要求形参的类型要求形参的类型要求形参的类型要求形参的类型传递的信息传递的信息传递的信息传递的信息能否改变实参的值能否改变实参的值能否改变实参的值能否改变实参的值变量名变量的值不能数组名或指针变量数组的起始地址能需要说明的是:需要说明的是:需要说明的是:需要说明的是:语言的函数调用都是采用“值传递”方式;当用变量名作函数参数时传递的是变量的值;用数组名作函数参数时,由于数组名代表的是数组首地址,因此传递的是数组首地址,所以要求形参为指针变量。3、指针变量可替代数组名作为函

26、数的参数指针变量可替代数组名作为函数的参数指针变量可替代数组名作为函数的参数指针变量可替代数组名作为函数的参数:、指针变量可以作为函数的形参;、指针变量可以作为函数的实参;例例 使用指向数组的指针变量来引用数组元素。main() int a10, *p=a, i; for(i=0; i10; i+) scanf(“%d”, p+i); /*使用指针变量来输入数 组元素的值*/ for(i=0; i10; i+) printf(“%d ”, *(p+i); /*使用指向数组的指针变 量输出数组*/ printf(“n”); 程序说明程序说明:程序中的2个for语句,等价于下面的程序段:for(i

27、=0; i10; i+,p+) scanf(“%d”,p);p=a; /*使p重新指向数组的第一个元素*/for(i=0; i10; i+,p+) printf(“%d”,*p);思考题思考题:(1)如果去掉“p=a;”行,程序运行结果会如何?请上机验证。(2)在本例中,也可以不使用i来作循环控制变量,程序怎么修改?提示:指针可以参与关系运算?endvoid sort(float b, int n) int i, j; float t; for(i=0; in-1; i+) for(j=i+1; jn; j+) if(bibj)t=bi; bi=bj; bj=t; 例例 将将n个数按从大到小排

28、序个数按从大到小排序 main( ) int i; float a10; for(i=0; i10; i+) scanf(“%f”, &ai); sort(a, 10); for(i=0; i10; i+) printf(“%f, ”, ai); printf(“n”); 主函数不变,主函数不变,sort 函数变为:函数变为: void sort(float *p, int n) int i, j; float t; for(i=0; in-1; i+) for(j=i+1; jn; j+) if( *(p+i) *(p+j) )t= *(p+i); *(p+i)=*(p+j);*(p+j)=

29、t; main( ) int i; float *p, a10; p=a; for(i=0; i10; i+)scanf(“%f”, p+); p=a; sort(p, 10); for(i=0; i10; i+) printf(“%f, ”, *p+); sort 函数不变、主函数变为:函数不变、主函数变为:归纳起来,实参与形参的对应关系有:、形参和实参都用数组名:f(int x , int n);f(a, 10);把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;、

30、实参用数组名,形参用指针变量:f(int *x, int n);f(a, 10);把实参数组首地址传给形参把实参数组首地址传给形参把实参数组首地址传给形参把实参数组首地址传给形参( (指针变量指针变量指针变量指针变量) ),函数中用指,函数中用指,函数中用指,函数中用指针访问实参数组针访问实参数组针访问实参数组针访问实参数组、形参和实参都用指针变量:f(int *x, int n);f(p, 10);函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值( (如:如:p=ap=a) )、实参为指针变量,形参为数组名:f(

31、int x , int n);f(p, 10);实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;小结int a10, *p;int a10, *p;p=a; p=a; 或 p=&a0;p=&a0;p为指向数组元素的指针语言规定:数组名表示数组的首地址,即第语言规定:数组名表示数组的首地址,即第0个元素的个元素的地址;即地址;即数组名是指向数组第数组名是指向数组第0个元素的指针常量个元素的指针常量。a+ia+ip+ip+i表示数组第 i 个元素的地址(&ai),即指向第 i 个元素的指针* *

32、( (a+ia+i) )* *( (p+ip+i) )表示数组的第 i 个元素(ai)a a i i p p i i 表示数组的第 i 个元素(ai)数组第 i 个元素地址的表示方法: &ai, a+i, p+i, &pi数组第 i 个元素的表示方法: ai, *(a+i), *(p+i), pi可以执行p+等操作使p指向不同的数组元素,通过* *p p访问不同的数组元素。但要始终注意要始终注意要始终注意要始终注意p p当前所指向的是哪一个数当前所指向的是哪一个数当前所指向的是哪一个数当前所指向的是哪一个数组元素组元素组元素组元素!通过指针在函数间传递一维数组:通过指针在函数间传递一维数组:编

33、译系统都是将形参数组名作为指针变量来处理的。编译系统都是将形参数组名作为指针变量来处理的。f(int x , int n);f(int *x, int n);可以通过xi、*(x+i)来访问实参数组元素。要求实参为指向数组首元素的指针:要求实参为指向数组首元素的指针: a 或 pf(a, 10);f(p, 10);(p=a;)10.3.4 多维数组与指针多维数组与指针1、二维数组的地址、二维数组的地址设数组定义为:设数组定义为:a34a0 a00, a01, a02, a03 a1 a10, a11, a12, a13 a2 a20, a21, a22, a23 视视 a为一维数为一维数组名,

34、组名,ai 为为 a 数组元素数组元素视视 ai 为一维数为一维数组名,组名,aij 为为 ai 数组元素数组元素 例如例如: int a34=1,3,5,7, 9,11,13,15, 17,19,21,23;: int a34=1,3,5,7, 9,11,13,15, 17,19,21,23;a001a013a025a037a109a1111a1213a1315a2017a2119a2221a2323可以认为a是具有3个元素的一维数组:a0、a1、a2;a0a1a2每个元素又是具有4个整型元素的一维数组。2、数组名a表示地址2000120023200452006720089201011201

35、213201415201617201819202021202223a0a1a2从二维数组的角度来看,a为二维数组名,表示整个二维数组的首地址。若把a看成一维数组,每个数组元素a0、a1、a2占_个字节。8 8a表示a0的地址(&a0: 2000);a+1表示的地址();a+1&a1a1a1&a1:a1: 20082008a+2表示的地址();a+2&a2a2a2&a2:a2: 20162016a+1表示:a+81=2008a+2表示:a+82=2016a+i表示:a+8ia+ia+i表示表示表示表示aiai的地址的地址的地址的地址&aiai,即第即第即第即第i i行的地址行的地址行的地址行的地

36、址,它是指向一指向一指向一指向一维数组的指针维数组的指针维数组的指针维数组的指针。3、ai表示地址a001a013a025a037a109a1111a1213a1315a2017a2119a2221a2323a0a1a2a0、a1、a2是一维数组名。a0是一维数组a0的首地址,即第0行一维数组中第0列元素的地址(&a00);即a0的值为&a00;a1是一维数组a1的首地址,即第1行一维数组中第0列元素的地址(&a10);即a1的值为&a10;a2是一维数组a2的首地址,即第2行一维数组中第0列元素的地址(&a20);即a2的值为&a20;因此,aiai是第是第是第是第i i行首元素的地址行首元

37、素的地址行首元素的地址行首元素的地址( (指针指针指针指针) ),它是指向数组指向数组指向数组指向数组元素的指针元素的指针元素的指针元素的指针。4、ai+j表示地址:aiai是第i行首元素的地址。a0+1表示第0行第1列元素的地址; &a01a0+2表示第0行第2列元素的地址; &a02a2+3表示第2行第3列元素的地址; &a23第第第第i i行第行第行第行第j j列元素的地址列元素的地址列元素的地址列元素的地址( (&aijaij) );5、*(a+i)表示地址:*(a+i)等价于ai第第第第i i行首元素的地址行首元素的地址行首元素的地址行首元素的地址6、*(a+i)+j表示地址:*(a

38、+i)+j等价于ai+j第第第第i i行第行第行第行第j j列元素的地址列元素的地址列元素的地址列元素的地址7、数组元素aij的表示:ai+j*( )*( )*(a+i)+j*( *( ) )*(a+i)( ( ) )j若i=0,a0j可表示为:*(*(a0+j)a0+j)、*(*a+j)*(*a+j)、(*a)j(*a)j若j=0,ai0可表示为:*(*(ai)ai)、*(*(a+i)*(*(a+i)、(*(a+i)0(*(a+i)0aij8、(a+i)与*(a+i)的比较:(a+i)等价于等价于&ai*(a+i)等价于等价于ai、都表示地址:a+i表示第i行的地址(指针),*(a+i)表示

39、第i行首元素的地址、它们指向的数据类型不同:a+i指向一个一维数组(二维数组的一行、行指针);*(a+i)指向数组元素;若进行操作:(a+i)+1:使指针移动一维数组所占字节总数(一行、8字节)*(a+i)+1:使指针移动一个数组元素所占内存字节总数(2字节)9、对ai性质的进一步说明:ai从形式上看是a数组中第i个元素。如果a是一维数组名,则ai代表a数组第i个元素所占的内存单元。ai是有物理地址的,占内存单元。如果a是二维数组,则ai代表一维数组名。ai本身并不占实际的内存单元,它也不存放a数组中各个元素的值;它只是一个地址。a、a+i、ai、*(a+i)、*(a+i)+j、ai+j都是地

40、址,*(ai+j)、*(*(a+i)+j)是二维数组元素aij的值。10、关于&ai的说明:、不要把&ai简单的理解为ai单元的物理地址,因为并不存在ai这个变量。它只是一种地址的计算方法,能得到第i行的首地址;、&ai和ai的值是一样的,但它们的含义不同:&ai或a+i指向行,而ai或*(a+i)指向列。当列下标j为0时,&ai和ai(即ai+j)值相等,即指向同一位置。、*(a+i)只是ai的另一种表示形式,不要简单的认为是“a+i所指单元的内容”。对于二维数组:对于二维数组:a+i=ai=*(a+i)=&ai=&ai0,它们的地址相等。它们的地址相等。2、多维数组的指针及指针变量、多维数

41、组的指针及指针变量(1)指向数组元素的指针变量)指向数组元素的指针变量 设二维数组设二维数组 anm若指针变量若指针变量 p=a则则指向指向 aij 的指针为的指针为 p+i*m+j即:即: *(p+i*m+j)=aij(2)指向一维数组的指针变量)指向一维数组的指针变量 使指针变量指向二维数组的每一行使指针变量指向二维数组的每一行若若 p 指向指向 a0,则则 p+1 指向指向 a1;即:即:p 的增值以一维数组长度为单位的增值以一维数组长度为单位称称 p 为行指针为行指针 main( ) static int a34= ., ., . ; int *p, i, j; p=a;1) for(

42、i=0; i12; i+) printf(“%d”,*p+);2) for(i=0; i12; i+) printf(“%d”,*(*a+i);3) for(p=a0; pa0+12; p+) printf(“%d”,*p);4) for(i=0; i3; i+) for(j=0; j4; j+) printf(“%d”,*(p+i*4+j);例:输出二维数组有关的值例:输出二维数组有关的值。10.4 字符串与指针存放字符串的字符数组是一种特殊的数组,即以存放字符串的字符数组是一种特殊的数组,即以存放字符串的字符数组是一种特殊的数组,即以存放字符串的字符数组是一种特殊的数组,即以00作为结束标

43、志。作为结束标志。作为结束标志。作为结束标志。在访问字符串时候,以在访问字符串时候,以0作为结束条件。作为结束条件。10.4.1 通过指针访问字符串一、有关概念:1、字符串的指针: 对应的字符数组在内存中存放的首地址;2、指向字符串的指针变量:专门用来存放字符数组首地址的变量;3、字符数组指针变量的定义与赋值:char *p, str30;p=str;p=&str0;二、字符串的表示形式:1、用字符数组实现:void main( ) char s =I love China!; printf(%sn, s);2、用字符指针指向一个字符串: char s =I love China!;char

44、*p;p=str;printf(%sn, p);对于指向字符的指针变量,除了可以把字符数组名(指向字符的指针常量)赋给它外,还可以将一个字符串常量赋给它。char *cpchar *cp;cp=Hello, world!;cp=Hello, world!;也可以在定义时赋初值:char *cp= Hello, world!;char *cp= Hello, world!;语言在处理字符串常量时,在内存中开辟连续的存储单元,存放字符串中的各字符和字符串结束标志0。对指针变量赋值的作用是:将字符串在内存中的首地址将字符串在内存中的首地址将字符串在内存中的首地址将字符串在内存中的首地址赋给指针变量赋

45、给指针变量赋给指针变量赋给指针变量。不同于用字符串常量对字符数组赋初值:char ca =Hello, world!;char ca =Hello, world!;其作用是:将字符串中的各字符和结束标志0存放到数组ca的各元素中,数组的首地址用数组名ca表示。例:将字符数组a中的字符串复制到字符数组b中。、下标法:#include main( ) char a =Hello, World!, b20; int i; for (i=0; ai!=0; i+) bi=ai; bi=0; printf(%sn, b);、指针法:#include void main( ) char a =Hello,

46、 World!, b20; char *pa=a, *pb=b; for ( ; *pa!=0; pa+, pb+) *pb=*pa; *pb=0; printf(%sn, b);三、字符数组与字符指针变量的比较:、字符数组由若干个元素组成,每个元素中存放着一个字符;而字符指针变量中存放的是地址,不是将字符串放到字符指针变量中;、赋值方式:char str20;char str20;str20=I love China!;str20=I love China!;char *ps;char *ps;ps=I love China!;ps=I love China!;、对字符指针变量赋初值:cha

47、r *s=I love China!;char *s=I love China!;char *s;char *s;s=I love China!;s=I love China!;char str =I love China!;char str =I love China!;char str14;char str14;strcpy(str, I love China!);strcpy(str, I love China!);、字符指针变量是可以改变的。char s20, *ps;char s20, *ps;10.4.2 字符串指针作函数参数将一个字符串从一个函数传递到另一个函数,可以用地址传递的

48、方法,即用字符数组名字符数组名字符数组名字符数组名、指向字符串的指针变指向字符串的指针变指向字符串的指针变指向字符串的指针变量量量量或其它字符地址表达式字符地址表达式字符地址表达式字符地址表达式作参数。1、用字符数组作实参main( )main( ) char a=abcdefg char a=abcdefg; char b=12345; char b=12345; copy_string(a, b); copy_string(a, b); void copy_string(char to, char from)void copy_string(char to, char from) int

49、i=0; int i=0; while (fromi!=0) while (fromi!=0) toi=fromi; i+; toi=fromi; i+; toi=0;toi=0; 2、用字符指针变量作实参 char *a=abcdefg; char *a=abcdefg; char *b=12345; char *b=12345; copy_string(a, b); copy_string(a, b);void copy_string(char *to, char *from)void copy_string(char *to, char *from) for ( ; *from!=0;

50、from+, to+) for ( ; *from!=0; from+, to+) *to=*from; *to=*from; *to=0; *to=0; 3、可以对copy_string函数作下列简化:、void copy_string(char *to, char *from)void copy_string(char *to, char *from) while ( while ( (*to=*from)(*to=*from)!=0 )!=0 ) to+; from+; to+; from+; while (*to=*from)、void copy_string(char *to, ch

51、ar *from)void copy_string(char *to, char *from) while ( while ( (*to+=*from+)(*to+=*from+)!=0 )!=0 ) ; ;while (*to+=*from+)、void copy_string(char *to, char *from)void copy_string(char *to, char *from) while ( while (*from*from!=0 )!=0 ) *to+=*from+; *to+=*from+; *to=0;*to=0;while (*from)、void copy_s

52、tring(char *to, char *from)void copy_string(char *to, char *from) for ( ; for ( ; (*to+=*from+)(*to+=*from+)!=0; )!=0; ) ; ; 、void copy_string(char *to, char *from)void copy_string(char *to, char *from) for ( ; for ( ; (*to+=*from+) (*to+=*from+) ; ); ) ; ; 4、对copy_string函数的调用形式:char s120=12345, s2 =How are you!;char s120=12345, s2 =How are you!;copy_string(s1, s2);copy_string(s1, s2);s1: How are you!s1: How are you!copy_string(s1, copy_string(s1, s2+2s2+2); );s1: w are you!s1: w are you!copy_string(copy_string(s1+2s1+2, s2);, s2);s1: 12How are you!s1: 12How are you!

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号