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 页 第
3、6 6 页以往对变量的访问以往对变量的访问: : 定义变量定义变量: int: int k; k;编译系统根据类型为编译系统根据类型为k k分配内存。分配内存。 输入变量的值输入变量的值:scanf(“%d”,&k:scanf(“%d”,&k);); &k &k就代表了变就代表了变量量k k在内存中的地址。在内存中的地址。 通过变量名访问变量通过变量名访问变量, ,这种操作称为这种操作称为直接访问直接访问;b=k+5;b=k+5;通过指针间接访问通过指针间接访问: :C C提供了另一种方式,将变量提供了另一种方式,将变量 k k的地址存放在另一个的地址存放在另一个变量处变量处( (假定为假定为
4、pkpk) ),通过,通过访问访问 pkpk,就可以间接地访,就可以间接地访问变量问变量 k k,这种方式称为,这种方式称为间接访问间接访问。变量的存取方法:变量的存取方法:直接存取和间接存取。直接存取和间接存取。 共 84 页 第 7 7 页引入指针程序设计的优点引入指针程序设计的优点1. 有效表示复杂的数据结构。有效表示复杂的数据结构。2. 方便使用字符串、数组。方便使用字符串、数组。3. 可以得到多个返回值。可以得到多个返回值。4. 可以进行动态分配内存。可以进行动态分配内存。5. 程序简洁、紧凑程序简洁、紧凑, 执行效率高。执行效率高。共 84 页 第 8 8 页 9.1.1 9.1.
5、1 指针的基本概念指针的基本概念u指针指针:一个变量的地址称为该变量的指针。:一个变量的地址称为该变量的指针。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;
7、 定义的指针变量为定义的指针变量为p1,p2 p1,p2 (2 2)一个指针变量只能指向同一类型的变量。)一个指针变量只能指向同一类型的变量。 如如 p1 p1 只能用于指向只能用于指向整型变量整型变量 p2 p2 只能用于指向只能用于指向实型变量实型变量(3 3)无论指针变量指向何种类型,指针变量本身都)无论指针变量指向何种类型,指针变量本身都是是整型整型的,指针变量本身也有自己的地址,占的,指针变量本身也有自己的地址,占两个两个字节字节的存储空间。的存储空间。 共 84 页 第 1212 页1.取地址运算取地址运算 & 格式格式: & 变量变量 设有变量说明设有变量说明 int a, b,
8、 *p, *q; p=&a; 把把a的地址赋给的地址赋给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. 取内容运算取内容运算 *格式:格式: * * 指针表达式指针表达式若有变量说明:若有变量说明:intint a, a, * *p ; p ; p=&a; p=&a; 让让p p指向变量指向变量a a * *p=10;
9、p=10; 等价于等价于 a=10a=10 printf(“%d printf(“%d”, ”, * *p); p); 打印打印p p所指变量的值所指变量的值 scanf(“%dscanf(“%d”, &a); ”, &a); 给变量给变量a a输入值输入值 scanf(“%dscanf(“%d”, p); ”, p); 给变量给变量a a输入值输入值 * *p+25 p+25 等价于等价于a+25a+25设设p p是一个指针表达式,则:是一个指针表达式,则:(1 1)若)若* *p p出现在赋值号左边,表示给出现在赋值号左边,表示给p p所指变量赋值所指变量赋值(2 2)若)若* *p p不
10、出现在赋值号左边,表示不出现在赋值号左边,表示p p所指变量的值所指变量的值共 84 页 第 1414 页3. 为指针变量赋初值为指针变量赋初值 指针变量使用前必须有值指针变量使用前必须有值 指针变量的初值必须是地址值指针变量的初值必须是地址值(不能是整数不能是整数) 方法方法 :(1)在说明指针变量时同时初始化在说明指针变量时同时初始化 int a , *p = &a;(2) 使用赋值语句赋值使用赋值语句赋值 int a,*p; p =&a ; 可以为指针赋空值可以为指针赋空值(NULL),此时指针不指向任何,此时指针不指向任何 变量变量, 如如 p=NULL或或 p=0;p=0; ( p为
11、空指针为空指针)共 84 页 第 1515 页若若pa=&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不再
12、指向a共 84 页 第 1616 页 例例 9-1 9-1 输出变量的值。输出变量的值。 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输出所指向的变量运行结果为
13、100,10100,10共 84 页 第 1717 页main( ) 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 q=和和!=!=运算符,比较的是两个指针表达式是否指向运算符,比较的是两个指针表达式是否指向同一个内同一个内存单元存单元; ; 、= 、=,比较的是两个指针所指内存区域的比较的是两个指针所指内存区域的先后次序先后次序例:例:int a10; intint a10; in
14、t * *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 页5. 5. 同类指针相减同类指针相减 同类指针相减时,两个指针应该指向连续存放同类指针相减时,两个指针应该指向连续存放的同类数据区域。的同类数据区域。 语法语法 :p-qp-q 说明:说明: p-qp-q 即即p,qp,q两个指针之间数据元素的个数。两个指针之间数据元素的个数。 例如:若有例如:若有 intint a10 , a10 , * *
15、p, p, * *q;q; p=a; p=a; q=&a5; q=&a5; 则则p-qp-q=5 =5 表示表示p,qp,q之间数据元素的个数是之间数据元素的个数是5 5。 共 84 页 第 2828 页格式格式: (类型名类型名 * ) 指针表达式指针表达式功能:将指针表达式的值转换成指定类型的指针。功能:将指针表达式的值转换成指定类型的指针。 例如例如: int *p; double d, *q=&d; p=(int * )q;6. 强制类型转换运算强制类型转换运算共 84 页 第 2929 页 9.3.3 通过指针引用数组元素通过指针引用数组元素引用数组中的元素可以用以下方法:引用数组中
16、的元素可以用以下方法: 下标法下标法 : 如如 a3,ai 指针法指针法: 即通过指向数组元素的指针找到所需的元素即通过指向数组元素的指针找到所需的元素. 这种方法占内存少这种方法占内存少, 运行速度快运行速度快,程序代码质量高。程序代码质量高。 假设假设p已定义为指针变量已定义为指针变量,并已赋了一个地址并已赋了一个地址,它指向某一它指向某一个数组元素个数组元素. 且有赋值语句且有赋值语句p= &a0; 则:则: p+1 指向数组中的指向数组中的下一个元素下一个元素, a+i,p+i i ai 的地址的地址 *(a+i) , *(p+i) a+i,p+i所指向的数组元素。所指向的数组元素。
17、指向数组的指针变量也可带有下标,如指向数组的指针变量也可带有下标,如pi与与*(p+i)等等价。价。v对下标为对下标为i i的元素访问:的元素访问: ai,ai,* *(a+i),(a+i),* *(p+i),pi(p+i),pi v对对aiai的地址表示:的地址表示: & &ai,a+i,p+i,&piai,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
18、;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 页main( )main( ) int int a10, 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+,p
19、a+) printf(“%d printf(“%d”,”,* *pa);pa); printf(“n printf(“n”);”); 不要忘记赋初值不要忘记赋初值共 84 页 第 3232 页main( )main( ) int int a10=5,7,3,6,2,1,8,9,4,0; a10=5,7,3,6,2,1,8,9,4,0; int i, int i, * *p,maxp,max; ; p=a; p=a; max= max=* *p+;p+; for(i for(i=1; i10; i+, p+ )=1; imax ) max=pmax ) max=* *p ;p ; printf
20、( “max=%dn printf ( “max=%dn”, max); ”, max); 问题问题: :如果修改语句如果修改语句for(ifor(i=1;i10; i+ ) =1;imax) pmax) max= max=* *p+ ;p+ ;能实现程序功能吗能实现程序功能吗? ?问题问题: :如果修改语句如果修改语句for(;pfor(;pa+10; p+ ) max) pmax) max= max=* *p ;p ;能实现程序功能吗能实现程序功能吗? ?共 84 页 第 3333 页9.3.4 字符串指针与字符串字符串指针与字符串1.字符串的表示形式字符串的表示形式u 用用字符数组字符数
21、组表示,如:表示,如:main( ) char string =“I love China!”; printf(“%sn”,string);数组名数组名u 用用字符指针字符指针实现,如:实现,如:mian( ) char * string =“I love China!”; printf(“%sn”,string);把“I love China!”的首地首地址赋址赋给指针变量string共 84 页 第 3434 页2.字符指针变量与字符数组的比较字符指针变量与字符数组的比较u字符数组由若干个元素组成,每个元素中放一个字符,字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的
22、是字符串的首地址。而字符指针变量中存放的是字符串的首地址。 赋值方式:赋值方式: char str =“I am a boy!” 或或: char str20; scanf(“%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 已知下面程序的输出结果
23、已知下面程序的输出结果:ABCDCD,:ABCDCD,请完善请完善程序程序: : (请注意,首次执行时即将(请注意,首次执行时即将ABCDABCD全体输出全体输出,输出输出的是字符串,而非单个字符)的是字符串,而非单个字符) main()main() char char * *chpchp=“ABCD”;=“ABCD”; for( ; _A_; chp for( ; _A_; chp=chp+2)=chp+2) printf(“%s printf(“%s”, _B_);”, _B_); printf(“n printf(“n”);”); A. *chp!=0B. chp共 84 页 第 363
24、6 页作用:作用: 函数的参数不仅可以是整型、实型、字符函数的参数不仅可以是整型、实型、字符型,还可以是指针型,型,还可以是指针型,它的作用是将一个变量它的作用是将一个变量的地址传送到另的地址传送到另外外一个函数中。一个函数中。9. 4 指针与函数指针与函数9.4.1 9.4.1 指针变量作函数参数指针变量作函数参数共 84 页 第 3737 页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); 调用函数时调用函
25、数时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; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa,pb); pintf(“%d,%dn”,a,b); 运行情况:运行情况:5,9 9,5交换指针所指交换指针所指向的向的变量的值变量的值例:将两个数按
26、从大到小顺序输出例:将两个数按从大到小顺序输出(交换两个变量的值)。交换两个变量的值)。结论:被调用函数不能改变实参指针变结论:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指量的值,但可以改变实参指针变量所指向的变量的值。向的变量的值。共 84 页 第 3939 页函数调用过程如下图所示函数调用过程如下图所示:调用swap函数之前: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 bswap(pa, pb) swap(p1,p2) 实参 形参*p1*p
27、2共 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;int *pa, *pb; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa, pb);printf(“%d,%dn”,*pa,*pb);C语言中,实参和形参间的数据是单向值传递方式。语言中,实参和形参间的数据是单向值传递方式。改
28、变指针形参的值,也不改变指针形参的值,也不能改变指针实参的值能改变指针实参的值. .结果为结果为:?:?交换了两个指针中的内容。共 84 页 第 4343 页 9.4.2 数组名作函数参数数组名作函数参数 若有一个实参数组,想在函数中改变此数组的元若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下素的值,实参与形参的对应关系有以下4 4种情况:种情况: 形参与实参都用数组名形参与实参都用数组名 实参用数组名,形参用指针变量实参用数组名,形参用指针变量 实参形参均用指针变量实参形参均用指针变量 实参为指针变量,形参为数组名实参为指针变量,形参为数组名都是地址传递,只是形
29、式不同!都是地址传递,只是形式不同!共 84 页 第 4444 页u指针变量在作实参时,必须有确定的值,即指向一个指针变量在作实参时,必须有确定的值,即指向一个已定义的单元。已定义的单元。 如:如:main()main() int int * *p;p; f(p,10); f(p,10); int f(int x ,int int f(int x ,int n n) 错误!如何修改?如何修改?共 84 页 第 4545 页例例9-6:用选择法对:用选择法对10个整数由小到大排序。个整数由小到大排序。方法方法1:形参和实参都用数组名:形参和实参都用数组名(在函数中介绍的在函数中介绍的)main(
30、 ) int i, a10;void sort( );for(i=0;i10;i+) scanf(%d”,&ai);sort(a,10);for(i=0; i10 ;i+) 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 so
31、rt( );p=a;for(i=0;i10;i+) scanf(%d,p+);sort(p,10);for(p=a, i=0; i10 ;i+) printf(%d, *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;形参是数组名形参是数组名实参是指针实参是指针当用数组名作函数参数时,由于当用数组名作函数参数时,由于数组名代表的是数组首元素地址,数组名代表的是数组首元素地址,因此传递的是地址,所以要求实因此传递的是地址,所以要求实参为指针变量。参为指
32、针变量。共 84 页 第 4747 页方法方法3:实参是数组名,形参是指针变量。:实参是数组名,形参是指针变量。void sort( int *x, int n) int 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); 形参是指针形参是指针实参是数组名实
33、参是数组名共 84 页 第 4848 页方法方法4:实参和形参都是指针变量。:实参和形参都是指针变量。void sort( int*x, int n) int 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 *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);指向函数
34、的指针指向max函数共 84 页 第 5757 页在一个程序中,一个指针变量可以先后指向不同在一个程序中,一个指针变量可以先后指向不同的函数;的函数; 例如:例如: intint ( (* *p)( );p)( ); int int max( ); max( ); int int min( ); 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先与先与*结合,是指针变量,结合,是指针变量,然后再与()结合,表示此然后再与()结合,表示此指针变量指
35、向函数。指针变量指向函数。共 84 页 第 5858 页9.5 指针与二维数组指针与二维数组9.5.1 二维数组的结构二维数组的结构 数组名数组名 代表该数组的首地址,并可看成是地址代表该数组的首地址,并可看成是地址常量,这一规定对二维数组或更高维数组同样适用。常量,这一规定对二维数组或更高维数组同样适用。若有定义:若有定义: float *p, d35; d0,d1,d2 分别是一维数组名,表示一维数组的首分别是一维数组名,表示一维数组的首地址,地址,p=d0是正确的。是正确的。d00d00 d01d01 d02d02 d03d03 d04d04d10d10 d11d11 d12d12 d1
36、3d13 d14d14d20d20 d21d21 d22d22 d23d23 d24d24d0d0d1d1d2d2d可以把可以把d看成是由看成是由3个一维数组个一维数组组成,即组成,即d0,d1,d2共 84 页 第 5959 页 a a: : 二维数组的首地址,第二维数组的首地址,第0 0行地址行地址 a+1a+1是数组是数组a a第第1 1行地址行地址(208)(208) * *(a+1) (a+1) 数组数组a a第第1 1行首地址行首地址(208)(208) a1 a1 第第1 1行的首地址行的首地址 ai+jai+j是第是第i i行行j j列的地址列的地址 * *(ai+j)(ai+
37、j)是该地址存储的值,是该地址存储的值, 即即aijaij * *( (* *(a+1)(a+1)+j)+j)是该地址存储的值,是该地址存储的值,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 二维数组元素及其地址二维数组元素及其地址a+1a+1(二级)(二级)= = a1(a1(一级一级) )共 84 页 第 6060 页注意:注意: a0=a+0a0=a+0、a1=a+1a1=a+1、a2=a+
38、2a2=a+2 (值相等,意义不同)(值相等,意义不同) aiai 和和* *(a+i)(a+i)无条件等价无条件等价 a+ia+i、aiai、* *(a+i)(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 页 第 6161 页int i,j;main( ) int *p, a34,
39、 b34, c34; printf(The value of a:n); for(i=0; i3; i+) for(j=0; j4; j+) scanf(%d,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 页 第 6262 页 matrix(*a, b0
40、, &c00); printf(The value of c:); for(i=0, p=c0; pc0+12; p+,i+) if (i%4=0) printf(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*
41、4+j)就是就是取该元素的值。取该元素的值。*a相当于相当于*(a+0),即即a0表示表示a数组第数组第0行第行第0列元素的地址。列元素的地址。b0表示表示 b数组第数组第0行第行第0列元素的地址。列元素的地址。&c00表示表示 c数组第数组第0行第行第0列元素的地址。列元素的地址。计算计算aij在数组中相对位置的在数组中相对位置的计算公式为:计算公式为:i*m+jm为二维数组的列数为二维数组的列数共 84 页 第 6363 页指针法(方法指针法(方法1) main()int a34,b43,i,j,*p,*q;p=&a00;q=&b00;for(i=0;i3;i+) for(j=0;j4;j
42、+) 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指向指向两数组的开始位置两数组的开始位置利用指针利用指针p为数组为数组a输入数据输入数据利用指针利用指针q输出数组输出数组b这里的指针变量这里的指针变量p和和q都是用都是用int *p,*q定义的定义的是指向整型数据的,是指向整型数据的,p+1是指向是指向p所指向的下所指向的下一个元素。能否使一个元素。能否使p不是指向整型变量
43、,而不是指向整型变量,而是指向一个包含是指向一个包含m个元数的一维数组呢?个元数的一维数组呢?共 84 页 第 6464 页9.5.3 9.5.3 指向数组的指针变量指向数组的指针变量1. 1. 定义格式定义格式 类型说明符类型说明符 (* *变量名)变量名) 正整型常量表达式正整型常量表达式 2. 2. 功能功能 定义一个名为定义一个名为“变量名变量名”的指针变量,这个指针的指针变量,这个指针变量所指的对象是一个变量所指的对象是一个有有“正整型正整型常量表达式常量表达式”个元素的一维数组。个元素的一维数组。例如:例如:intint a34,( a34,(* *p)4=a;p)4=a;定义定义
44、p p是一个指针变量,它指向包含是一个指针变量,它指向包含4 4个整型元素的个整型元素的一维数组。一维数组。 p p的值就是该一维数组的起始地址。的值就是该一维数组的起始地址。a0a1a2p,ap+1p+2共 84 页 第 6565 页main( )main( ) intint 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);); print
45、f(“a%d%d=%dn”,i,j printf(“a%d%d=%dn”,i,j, ,* *( (* *(p+i)+j);(p+i)+j); 输入输入1,21,2运行结果:运行结果:a12=13a12=13 1 3 5 7 9 11 13 1517 19 21 23p,ap+1p+2a0a1a2=第第i行行j列元素的地址列元素的地址为为*(p+i)+j或或pi+j第第i行行j列元素的值为:列元素的值为:*(*(p+i)+j)这里的指针变量这里的指针变量p不是指不是指向整型变量,而是指向一向整型变量,而是指向一个包含个包含4个整型元素的一个整型元素的一维数组。维数组。共 84 页 第 6666
46、页例例9-15 阅读下面程序。阅读下面程序。 main( )int i;int *q,(*p)4,a34=2,4,6,8,10,12,14,16,18,20,22,24; q=a0; for(i=1;i=0;i-) printf(%dt, *(pi+i); printf(n);程序运行结果:程序运行结果: 2 6 10 14 22 12 2 第第i行行i列元素的地址列元素的地址为:为:pi+i第第i行行j列元素的值为:列元素的值为:*(pi+i)q q是定义为指向整型数据的是定义为指向整型数据的P P指指向一个包含向一个包含4 4个整型元素的个整型元素的一维数组。一维数组。共 84 页 第 6
47、767 页定义一个由定义一个由 6 6个个指针变量构成的指针变量构成的指针数组指针数组,数组中,数组中的每个数组元素都是一个指向一个整数的指针变量。的每个数组元素都是一个指向一个整数的指针变量。地址地址pa0pa1pa2pa3pa4pa5指针数组指针数组pa指针数组指针数组: :数组中的数组中的元素元素均为均为指针类型指针类型( (可以当做地址来记可以当做地址来记) ) 。适合用来指向字符串适合用来指向字符串1.1.定义形式:定义形式:数据类型数据类型 * * 数组名数组名 常量表达式常量表达式 例如:例如: intint * *pa6;pa6;2.2.功能:功能:9.6 9.6 指针数组指针
48、数组共 84 页 第 6868 页 必须用地址值为指针数组初始化必须用地址值为指针数组初始化 intint a33 = 1,2,3,4,5,6,7,8,9, a33 = 1,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 9a0a1a2pa0pa1pa2初始化的结果初始化的结果:共 84 页 第 6969 页对指针数组中的任意一个对指针数组中的任意一个pai,移动移动j个元素,有:个元素,有: pai+j = ai+j = &aij;*(pai+j) = *(ai+j) =
49、 aij;指针与数组的等价性:指针与数组的等价性:*(a+i )=*(pa+i )=a i ; 指针数组与二维数组是等价的,通过指针数组指针数组与二维数组是等价的,通过指针数组可以引用二维数组中的元素。可以引用二维数组中的元素。注意:注意: intint * *p5 p5 与与 intint ( (* *p)5 p)5 不同不同共 84 页 第 7070 页 字符串数组:字符串数组:数组中的每个元素都是存放字符的数组。数组中的每个元素都是存放字符的数组。 字符串数组的字符串数组的每一行可存放一个字符串每一行可存放一个字符串。 用赋初值的方式给字符串数组赋值:用赋初值的方式给字符串数组赋值:直接
50、给字符串数组赋初值直接给字符串数组赋初值若有定义:若有定义:char b48= Turbo C, FORTRAN, BASIC, Foxpro;此定义还可以写成:此定义还可以写成:char b8= Turbo C, FORTRAN, BASIC, Foxpro;由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。9.7 9.7 指针与字符串数组指针与字符串数组共 84 页 第 7171 页用给字符型指针数组赋初值的方式构成字符串数组用给字符型指针数组赋初值的方式构成字符串数组若有定义:若有定义:char *f4= Turbo C,
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。