计算机应用技术c程序设计语言课件8pointers_第1页
计算机应用技术c程序设计语言课件8pointers_第2页
计算机应用技术c程序设计语言课件8pointers_第3页
计算机应用技术c程序设计语言课件8pointers_第4页
计算机应用技术c程序设计语言课件8pointers_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

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

文档简介

第8章指针指针pointers与机器内部的硬件结构(内存地址)及其对数据的处理形式等有关变量包括:对应的地址(称指针,是内存单元号)对应的值(具体的数值)指针变量:存放变量地址的变量由此对变量的操作可通过指针来完成例如:inti,j,k;i=3;j=6;k=i+j;编译时,系统将内存单元分配给变量后,程序执行时对变量的操作实际上就是根据变量名查找与之对应的变量的地址,然后按地址对数据进行操作。1.直接访问

k=i+j2004200020022005=92001=32003=62.间接访问*kp=*ip+*jp3014301030123015200430112000301320022005=92001=32003=6ip,jp,kp:指针变量,其它变量的内存地址。ijkipjpkp200220002004301030123014369┇200020022004┇用户数据区8.1指针变量的指针:就是变量的地址。

指针变量:用来存放变量地址的变量,如:变量i的指针(地址)是2000,ip是存放i的指针的变量,其自身地址是3010,内容是2000,即i的地址(指针)。即:

ip是存放变量i的地址的指针变量(ip=&i;) *ip是指针变量ip所指的对象 (变量i)

ip20003i2000

i=3则等价*ip=38.1.1指针变量的定义指针变量使用前必须定义,以便使其指向特定类型的变量指针变量定义形式: 类型标识符*标识符其中:类型标识符:表示所指向变量的数据类型

标识符:表示指针变量名.例: float*p3; /*p3是指向实型变量的指针变量*/ char*p4; /*p4是指向字符型变量的指针变量*/inti,j;int*p1,*p2;p1=&i;p2=&j;i=3;*p1=5;j=6;*p2=8;3568┇20002002ijp1p2200020028.1.2指针变量的引用1、指针变量有两种运算符

&: 取地址运算符 可将变量的地址赋给指针变量,如:p1=&i;*: 指针变量所指对象运算符 如:*p1,访问p1所指对象:变量i说明:

定义时,指针变量名前以*开头说明用途。 引用中,指针变量名前加*表示指针变量所指对象例8-1(P158)取地址和间接访问例8-2(P159)使用指针改变变量的值指针变量操作简例main(){inta,b,*p1,*p2;a=100;b=10;p1=&a;p2=&b;printf(“a=%d,b=%d\n”,a,b);printf(“*p1=%d,*p2=%d\n”,*p1,*p2);printf(“&a=%x,&b=%x\n”,&a,&b);printf(“p1=%x,p2=%x\n”,p1,p2);printf(“&p1=%x,&p2=%x\n”,&p1,&p2);}运算结果:a=100,b=10*p1=100,*p2=10&a=ffd4,&b=ffd6p1=ffd4,p2=ffd6&p1=ffd8,&p2=ffda10010ffd4ffd6abp1p2ffd4ffd6ffd8ffda

2、&

和*运算符的优先级与结合性

*和&的优先级:同为2级结合性:从右向左。例如: inta,b,*p1,*p2;p1=&a; p2=&b; a=100; b=10;

则①&*p1 &a (p1)&*p2 &b (p2)②p2=&*p1 p2=&a③*&a a &a&bp1p210100ba&a&ap2p110100ba3.指针的算术运算指针赋值:可将地址常量或指针变量的值赋给另一个变量;

inta,b,*p1,*p2; p1=&a;p2=&b;a=100;b=10;p2=p1;指针与整数作加减运算:

p2+1

表示p2所指单元的下一个单元*和++或--

:优先级为2

结合性:从右到左

(*p1)++ a++*p1++ *(p1++)后者表示: 先访问p1所指对象(即变量a),然后使p1自增

p1原指向a,现在指向下一个变量4.指针变量赋初值

inta,*p=&a;例8-3(P160)指针赋值例8-4(P161)指针初始化举例:输入a,b,用指针方法按先大后小的顺序输出。main(){ int*p1,*p2,*p,a,b; scanf(“%d%d”,&a,&b); p1=&a;p2=&b; printf(“a=%d,b=%d\n”,a,b); printf(“*p1=%d,*p2=%d\n”,*p1,*p2); printf(“&a=%x,&b=%x\n”,&a,&b); printf(“p1=%x,p2=%x,p=%x\n”,p1,p2,p); printf(“&p1=%x,&p2=%x,&p=%x\n”,&p1,&p2,&p); if(a<b){p=p1;p1=p2;p2=p;} printf(“a=%d,b=%d\n”,a,b); printf(“*p1=%d,*p2=%d\n”,*p1,*p2); printf(“&a=%x,&b=%x\n”,&a,&b); printf(“p1=%x,p2=%x,p=%x\n”,p1,p2,p); printf(“max=%d,min=%d\n”,*p1,*p2);}

输入:59

输出:a=5,b=9*p1=5,*p2=9&a=ffd6,&b=ffd8p1=ffd6,p2=ffd8,p2=20&p1=ffd0,&p2=ffd2,&p=ffd4a=5,b=9*p1=9,*p2=5&a=ffd6,&b=ffd8p1=ffd8,p2=ffd6,p=ffd6&p1=ffd0,&p2=ffd2,&p=ffd4max=9,min=5只交换了指针的值,没有交换变量的值换后换前ffd8ffd655ffd0ffd2ffd4ffd8ffd6ffd6ffd820ffd699p1p2pab8.1.3指针变量作为函数参数指针变量作为函数参数时,传递的是变量的地址。例8-5(P165)数据交换。首先:形实参采用普通变量swap1(intx,inty){ intt;t=x;x=y;y=t; printf("&t=%x,&x=%x,&y=%x\n",&t,&x,&y); printf("t=%d,x=%d,y=%d\n",t,x,y);}main(){ inta,b;scanf(“%d%d”,&a,&b); if(a<b)swap1(a,b); printf("&a=%x,&b=%x\n",&a,&b); printf("a=%d,b=%d\n",a,b);}

在被调用函数中变量的值被交换了,返回主函数后,变量的值为什么依旧?原因:单向的值传递,当函数调用返回后,分配的单元被释放了.5599559ffceffc8ffd0ffd2ffd4txyab例8-5(续):指针变量作函数参数,将两个整数按大小顺序输出swap2(int*p1,int*p2){ intp; p=*p1; *p1=*p2; *p2=p; printf("&p=%x,&p1=%x,&p2=%x\n",&p,&p1,&p2); printf("p1=%x,p2=%x\n”,p1,p2); printf("p=%d,*p1=%d,*p2=%d\n",p,*p1,*p2);}ffcaffd2ffd0ffd4ffd6ffd8ffdapp1p2abp11p125┇ffd4ffd65995ffd4ffd6main(){ inta,b,*p11,*p12; scanf("%d%d",&a,&b); p11=&a;p12=&b; printf("&a=%x,&b=%x,&p11=%x,&p12=%x\n",&a,&b,&p11&p12); printf("p11=%x,p12=%x\n",p11,p12); printf("a=%d,b=%d\n",a,b); if(a<b)swap2(p11,p12); printf("max=%d,min=%d\n",a,b);}问题:函数调用结束后,分配给p1,p2单元释放否?例8-5(续):对swap2函数稍作改动swap2(int*p1,int*p2){ int*p;*p=*p1;*p1=*p2;*p2=*p; printf("p=%x,p1=%x,p2=%x\n",p,p1,p2);}main(){ inta,b;int*p11,*p12; scanf("%d%d",&a,&b); p11=&a;p12=&b; if(a<b)swap2(p11,p12); printf("a=%d,b=%d\n",a,b);}如何解决此问题?ffd2ffd4ffd2ffd45999ffd2ffd4p1pp2abp11p12运行:5,9输出:p=ffd2,p11=ffd2,p2=ffd4a=9,b=9例8-5(续):形参、实参都是指针变量swap3(int*p1,int*p2){ int*p;p=p1;p1=p2;p2=p; printf("&p=%x,&p1=%x,&p2=%x\n",&p,&p1,&p2); printf("p=%x,p1=%x,p2=%x\n",p,p1,p2); printf("*p=%d,*p1=%d,*p2=%d\n",*p,*p1,*p2);}main(){ inta,b,*p11,*p12; scanf("%d%d",&a,&b); p11=&a;p12=&b; if(a<b)swap3(p11,p12); printf("&a=%x,&b=%x,&p11=%x,&p12=%x\n",&a,&a,&p11,&p12); printf("a=%d,b=%d,p11=%x,p12=%x\n",a,b,,p11,p12); printf("*p11=%d,*p12=%d\n",*p11,*p12);}

ffd2ffd2ffd4ffd4ffd259ffd2ffd4ffc8ffceffd0ffd2ffd4ffd6ffd8pp1p2abp11p12结论:形参与实参之间的数据传递是单向的值传递,实参的值不会改变。若在被调函数中通过指针变量改变所指对象的值,结果如何?

举例:输入a,b,c三个整数,按从大到小顺序输出swap(int*pt1,int*pt2){intp;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(“&q1=%x,&q2=%x,&q3=%x,q1=%x,q2=%x,q3=%x\n”,&q1,&q2,&q3,q1,q2,q3);printf(“*q1=%d,*q2=%d,*q3=%d\n”,*q1,*q2,*q3);}main(){inta,b,c,*p1,*p2,*p3;scanf(“%d%d%d”,&a,&b,&c);p1=&a;p2=&b;p3=&c;printf(“&a=%x,&b=%x,&c=%x,a=%d,b=%d,c=%d\n”,&a,&b,&c,a,b,c);ffbcffc2ffc4ffcaffccffceffd0ffd2ffd4ffd6ffd8ffdappt1pt2q2q1q3abcp1p2p3ffd091010ffd2ffd490ffd0ffd2ffd4ffd4ffd0009109

0ffd2ffd4printf(“&p1=%x,&p2=%x,&p3=%x,p1=%x,p2=%x,p3=%x\n”,&p1,&p2,&p3,p1,p2,p3);printf(“*p1=%d,*p2=%d,*p3=%d,n”,*p1,*p2,*p3);exchange(p1,p2,p3);printf(“a=%d,b=%d,c=%d\n”,a,b,c);}输入:9010输出:&a=ffd0,&b=ffd2,&c=ffd4,a=9,b=0,c=10&p1=ffd6,&p2=ffd8,&p3=ffda,p1=ffd0,p2=ffd2,p3=ffd4*p1=9,*p2=0,*p3=10&q1=ffca,&q2=ffcc,&q3=ffce,q1=ffd0,q2=ffd2,q3=ffd4*q1=10,*q2=9,*q3=0a=10,b=9,c=0ffbcffc2ffc4ffcaffccffceffd0ffd2ffd4ffd6ffd8ffdappt1pt2q2q1q3abcp1p2p3ffd091010ffd2ffd490ffd0ffd2ffd4ffd4ffd0009109

0ffd2ffd4例8-6(P164)指针作为函数参数的示例例8-7(P165)输入年和天数,输出对应的月和日。例如输入2000和61,输出3和1,即2000年第61天是3月1日。要求自定义函数month_day(year,yearday,pmonth,pday),其中pmonth和pday用于存放计算结果。8.2指针和数组8.2.1指针、数组和地址间的关系 数组名数组的起始地址(常量)数组元素地址数组的起始地址+偏移量通过指针/指针变量访问/引用数组(元素):(1)下标法:a[3](2)指针法:用指针变量指向所找的数组元素。例:inta[5];int*p;p=a;p=&a[0];例:a[i]与*(a+i)等价 p[i]相当于*(p+i)指针所指元素的地址计算,与数据类型有关(+i:意义因此而异)等价

举例main(){inta[5];int*p=&a[0];*p=2;printf(“&p=%x,p=%x\n”,&p,p);printf(“&a=%x,&a[0]=%x,a[0]=%d\n”,&a,&a[0],a[0]);printf(“*p=%d\n”,*p);}2ffceffceffd0ffd2ffd4ffd6ffd8a[0]a[1]a[2]a[3]a[4]p输出:&p=ffd8,p=ffce&a=ffce,&a[0]=ffce,a[0]=2*p=2举例:指针变量值加1其意义不同main(){inti,a[3]={1,3,5};floatb[3]={2,4,6};int*p1=a;float*p2=b;printf(“&a[0]=%x,&b[0]=%x,&p1=%x,&p2=%x\n”,&a[0],&b[0],&p1,&p2);printf(“p1=%x,*p1=%d\n”,p1,*p1);p1++;printf(“p1=%x,*p1=%d\n”,p1,*p1);p1++;printf(“p1=%x,*p1=%d\n”,p1,*p1);printf(“p2=%x,*p2=%4.2f\n”,p2,*p2);p2++;printf(“p2=%x,*p2=%4.2f\n”,p2,*p2);p2++;printf(“p2=%x,*p2=%4.2f\n”,p2,*p2);p1=a;printf(“*(a+2)=%d\n”,*(a+2));p2=b;printf(“*(p2+1)=%4.2f\n”,*(p2+1));}135246ffc4ffcaffc4ffc6ffc8ffcaffceffd2ffd6ffd8p1p2a[0]a[1]a[2]b[0]b[1]b[2]p1p2注:若a=&a[0]=ffc4

则a+0=ffc4,a+1=ffc6即:a+0&a[0]a+1&a[1]

若b=&b[0]=ffca

则b+1=ffce,a+2=ffd2输出:&a[0]=ffc4,&b[0]=ffca,&p1=ffd6,&p2=ffd8p1=ffc4,*p1=1p1=ffc6,*p1=3p1=ffc8,*p1=5p2=ffca,*p2=2.00p2=ffce,*p2=4.00p2=ffd2,*p2=6.00*(a+2)=5*(p2+1)=4.00135246ffc4ffcaffc4ffc6ffc8ffcaffceffd2ffd6ffd8a[0]a[1]a[2]b[0]b[1]b[2]p1p2几点说明:设a:数组,p:指针变量,数据类型不同则地址计算也不同(1)p=a;

p+ia+i&a[i]实际地址为:a+i*数组元素所占字节数如:数组a第2个元素的地址:a+2*2=ffc4+4=ffc8

数组b第2个元素的地址:b+2*4=ffca+8=ffd2int2char1float4double8d=135246ffc4ffc4ffc6ffc8ffcaffceffd2ffd6a[0]a[1]a[2]b[0]b[1]b[2]p(2)*(p+i)=*(a+i)=a[i]

编译时,按数组首地址加上相对位移量得到要找数组元素的地址,然后取出该单元中的内容,即:*(a+i)

例:a的首地址:ffc4,则对a[2]的存取方法为:*(&a[2])=*(a+2*2)=*(ffc4+4)=*(ffc8)=a[2]=5(3)指向数组的指针变量可带下标如:p[i],a[i],*(a+i),*(p+i)

都是指向a数组的第i个元素。其中:a:数组名

p:指向a的指针变量初值p=a135246ffc4ffc4ffc6ffc8ffcaffceffd2ffd6a[0]a[1]a[2]b[0]b[1]b[2]p举例:下标法访问数组元素main(){inti,a[5]={55,66,77,88,99};for(i=0;i<5;i++)printf(“&a[%d]=%x,a[%d]=%d\n”,i,&a[i],i,a[i]);}

输出:

&a[0]=ffd2,a[0]=55&a[1]=ffd4,a[1]=66&a[2]=ffd6,a[2]=77&a[3]=ffd8,a[3]=88&a[4]=ffda,a[4]=995566778899ffd2ffd4ffd6ffd8ffdaffd6a[0]a[1]a[2]a[3]a[4]a[5]举例:地址法访问数组元素main(){inti,a[5]={55,66,77,88,99};for(i=0;i<5;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)=ffd6,*(a+3)=88(a+4)=ffd8,*(a+4)=995566778899ffd0ffd2ffd4ffd6ffd8ffdaa[0]a[1]a[2]a[3]a[4]a[5]举例:指针法访问数组元素main(){int*p,a[5]={55,66,77,88,99};for(p=a;p<(a+5);p++)printf(“p=%x,*p=%d\n”,p,*p);}输出:p=ffd0,*p=55p=ffd2,*p=66p=ffd4,*p=77p=ffd6,*p=88p=ffd6,*p=995566778899ffd0ffd2ffd4ffd6ffd8ffdaa[0]a[1]a[2]a[3]a[4]pffd0举例:下标法、地址法指向数组元素main(){inti,*p,a[5]={55,66,77,88,99};p=a;for(i=0;i<5;i++)printf(“p[%d]=%d,*(p+%d)=%d\n”i,p[i],i,*(p+i));}输出:

p[0]=55,*(p+0)=55p[1]=66,*(p+1)=66p[2]=77,*(p+2)=77p[3]=88,*(p+3)=88p[4]=99,*(p+4)=99使用指针变量时要注意的问题:

(1)p++:合法,因p是指针变量,++只能用于变量。

a++:不合法,因为a是数组名,其值是数组元素的首地址,是常量。(2)指针变量使用时要注意当前值.例8-8(P168)输入10个整数,计算并输出它们的和。

举例:利用指针变量连续两次输出数组元素main(){inti,*p,a[5]={55,66,77,88,99};p=a;for(i=0;i<5;i++,p++)printf(“p=%x,*p=%d\n”,p,*p);for(i=0;i<5;i++,p++)printf(“p=%x,*p=%d\n”,p,*p);}输出:p=ffd2,*p=55p=ffd4,*p=66p=ffd6,*p=77p=ffd8,*p=88p=ffda,*p=99p=ffdc,*p=-24p=ffde,*p=285p=ffe0,*p=1p=ffe2,*p=-26p=ffe4,*p=14445566778899-242851-261444a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]p此结果,是何原因?(3)数组下标越界时,编译不作检查。(4)指针变量使用时的几个问题;++和*优先级为2,结合性从右向左若p=a+3则:*p++:将p所指对象(a[3])的值88取出,然后p增1指向a[4]*++p:先将p增1指向a[4],然后将其指向的对象a[4]的值99取出。*p--:将p所指对象(a[3])的值88取出,然后p减1指向a[2]*--p:先将p减1指向a[2],然后将其指向的对象a[2]的值77取出。5566778899ffd0ffd2ffd4ffd6ffd8ffdaa[0]a[1]a[2]a[3]a[4]pffd6p若:p=a+i,则*p++与a[i++]*p--与a[i--]*++p与a[++i]*--p与a[--i]等价8.2.2数组名作函数参数f(intarr[],intn){ ┆}main(){ intarray[10]; ┆ f(array,10);┆}例8-9(P168)输入10个整数,函数fsum(a,n)求前n项和arr[0]array[0]┋arr[1]array[1]arr[9]array[9]调用函数时,以数组名作实参实际上是把数组的首地址传递给形参,此时,形参数组和实参数组占用的是同一段内存,函数调用过程中,改变形参数组元素实际上也是改变实参数组元素,调用结束后,虽然形参数组名已不存在了,但对实参数组元素的操作起产生作用。例8-10(P170)数组内容逆序存放举例:将数组a中n个整数按相反顺序存放算法: a[0] a[n-1] a[1] a[n-2] ... a[(n-1)/2] a[n-(n-1)/2]x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]3 7 9 1 0 6 7 5 4 2 m=(n-1)/2; for(i=0;i<=m;i++) x[i] ~x[j] j=n-1-i#include<stdio.h>voidinv(intx[],intn){ intt,i,j,m; m=(n-1)/2; for(i=0;i<=m;i++){ j=n-1-i; t=x[i]; x[i]=x[j]; x[j]=t; }}voidmain(){ inti,a[10]={3,7,9,1,0,6,7,5,4,2}; printf("theoriginalarray:\n"); for(i=0;i<10;i++)printf("%d,",a[i]); printf("\n"); inv(a,10); printf("thearrayhasbeeninverted:\n"); for(i=0;i<10;i++)printf("%d,",a[i]); printf("\n");}举例:将上例中的形参x改为指针变量,以接收实参数组a传递来的地址,再设指针i,j,p指向有关元素,以实现数组元素的转换

voidinv(int*x,intn){ 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; }}3274951170660711594723a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]i,xp=x+mj实参可继续使用数组名,也可以使用指针

main(){inti,arr[10],*p=arr;printf(“inputoriginalarray:\n”);for(i=0;i<10;i++,p++)scanf(“%d”,p);printf(“\n”);p=arr;inv(p,10);printf(“thearrayhasbeeninverted:\n”);for(p=arr;p<arr+10;p++)printf(“%d“,*p);printf(“\n”);}3274951170660711594723arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]arr[6]arr[7]arr[8]arr[9]i,x,pipj显示::theoriginalarray:输入:37911067542thearrayhasbeeninverted:24576011973举例:从10个数中找出最大值和最小值,并分别存入全局量max,min中,在查找过程中指针p:依次指向数组各元素,array_end:指向最未元素后,array:指向array[0]所对应值。intmax,min;voidmax_min(intarray[],intn){int*p;max=min=*array;for(p=array+1;p<array+n;p++)if(*p>max) max=*p;else if(*p<min)min=*p;}100-24680-3456789number[0]array[0]number[1]array[1]number[2]array[2]number[3]array[3]number[4]array[4]number[5]array[5]number[6]array[6]number[7]array[7]number[8]array[8]number[9]array[9]parray+n-2-24-368456789100maxmin

main(){inti,number[10];printf(“enter10data\n”);for(i=0;i<10;i++)scanf(“%d”,&number[i]);max_min(number,10);printf(“\nmax=%d,min=%d\n”,max,min);}运行:enter10data-24680-345678910输出:max=100,min=-3-2-24-368456789100maxmin100-24680-3456789number[0]array[0]number[1]array[1]number[2]array[2]number[3]array[3]number[4]array[4]number[5]array[5]number[6]array[6]number[7]array[7]number[8]array[8]number[9]array[9]parray+n举例:对数组元素的操作,形、实参数均使用指针变量intmax,min;voidmax_min(int*array,intn){int*p;max=min=*array;for(p=array+1;p<array+n;p++)if(*p>max) max=*p;else if(*p<min)min=*p;}

100-24680-3456789number[0]number[1]number[2]number[3]number[4]number[5]number[6]number[7]number[8]number[9]array、parray_end-2-24-368456789100maxmin在被调用函数中改变数组的值,实参、形参取值有四种情况:(1)实、形参都是数组名

main(){ inta[10]┆f(a,10);┆}┇┇a[0]x[0]a[1]x[1]a[9]x[0]f(intx[],intn){┆}(2)实参为数组名,形参为指针变量

main(){inta[10]┆f(a,10);┆}┇x┇a[0]a[1]a[9]f(int*x,intn){┆}(3)形、实参都是指针变量

main(){inta[10],*p;┆p=a;f(p,10);┆}┇x、p┇a[0]a[1]a[9]f(int*x,intn){┆}(4)实参为指针变量,形参为数组

main(){inta[10],*p;┆p=a;f(p,10);┆}┇┇a[0]x[0]a[1]x[1]a[9]x[0]pf(intx[],intn){┆}例8-11(P171)冒泡排序函数. bubblesort 是必须掌握的三种排序方法之一, 其它二种分别是 选择排序selectionsort P142例7-5

插入排序insertionsort 后面补充#include<stdio.h>voidselection(inta[],intn){ inti,k,index,temp; for(k=0;k<n-1;k++){ index=k; for(i=k+1;i<n;i++)if(a[i]<a[index])index=i; temp=a[index]; a[index]=a[k]; a[k]=temp; }}voidbubble(inta[],intn){ intj,k,temp; for(k=1;k<n;k++) for(j=0;j<n-k;j++) if(a[j]>a[j+1]){ temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; }}voidinsertion(inta[],intn){ inti,j,temp; for(i=1;i<n;i++){ temp=a[i]; for(j=i-1;j>=0&&temp<a[j];j--)a[j+1]=a[j]; a[j+1]=temp; }}voidmain(){ inta[12]={9,3,7,23,5,17,13,11,1,15,21,19},j; for(j=0;j<12;j++)printf("%d",a[j]);printf("\n"); selection(a,12); //bubble(a,12); insertion(a,12); for(j=0;j<12;j++)printf("%d",a[j]);printf("\n");}8.2.3指向多维数组的指针和指针变量1、多维数组的地址如定义:inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};说明:a,a[0],a[1],a[2]:本身不占内存,不存放数据,仅表示地址a:代表整个数组首地址,设为2000a[0] 1357a[1] 9111315a[2] 17192123

实际地址 (2000) a[0] 第0行首址:即数组a的首址2000(2008) a[1] a+1 第1行首址:a+1×4×2=2008(2016) a[2] a+2 第2行首址:a+2×4×2=2016说明:a,a[0],a[1],a[2]:本身不占内存,不存放数据,仅表示地址a[0]、a[1]、a[2]是一维数组名,而数组名代表数组首地址因此:a[0]表示0行0列元素的地址:&a[0][0]a[1]表示1列0列元素的地址:&a[1][0]a[2]表示2行0列元素的地址:&a[2][0]2000120023200452006720089201011201213201415201617201819202021202223a[0]+0a[0]+1a[0]+2a[0]+3a+0a+1a+2a[2]+0a[1]+3举例:二维数组元素及地址的输出#include<stdio.h>voidmain(){ inti,j,a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}; printf("a=%x,a[0]=%x,a[1]=%x,a[2]=%x\n",a,a[0],a[1],a[2]); printf("a+0=%x,a+1=%x,a+2=%x\n",a+0,a+1,a+2); for(i=0;i<3;i++) for(j=0;j<4;j++) printf("%x,%x,%x\n",*(a+i)+j,a[i]+j,&a[i][j]); for(i=0;i<3;i++) for(j=0;j<4;j++) printf("%d,%d,%d\n",a[i][j],*(a[i]+j),*(*(a+i)+j));}2、指向多维数组的指针变量(1)指向数组元素的指针变量举例:用指针变量顺序输出数组元素的值#include<stdio.h>voidmain(){ inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int*p; for(p=&a[0][0];p<=&a[2][3];p++) printf("%4d",*p); printf("\n"); for(p=a[0];p<a[0]+12;p++) printf("%4d",*p); printf("\n"); for(p=a[0];p<a[0]+12;p++) printf("addr=%x,value=%d\n",p,*p);}运行结果:

13579111315192123addr=ffc2,value=1addr=ffc4,value=3addr=ffc6,value=5addr=ffc8,value=7addr=ffca,value=9addr=ffcc,value=11addr=ffce,value=13addr=ffd0,value=15addr=ffd2,value=17addr=ffd4,value=19addr=ffd6,value=21addr=ffd8,value=23由此可见:顺序输出数组元素方法简单而指定输出数组元素则要进行地址的计算如二维数组为n×m(n为行,m为列)首元素地址为a[0]a[i][j]在数组中相对位置的计算公式:

i*m+j(m为每行元素个数)位移量的计算:a[1][1]=1*4+1=5a[2][3]=2*4+3=11若初值:p=a[0]则:*(p+1*4+1)=*(p+5)a[1][1]*(p+2*4+3)=*(p+11)a[2][3]a[2][3]mi=2nj=3a[1][1](2)指向包含m个元素的一维数组的指针变量①若p是数组(一或二维)元素的指针变量,则p++,指向下一元素.②若p是包含m个元素的一维数组指针,

如定义:(*p)[4];

则p只能指向包含m个元素的一维数组,p++指向下一个一维数组.

●p的值是该一维数组的首地址.

●p不能指向一维数组中的任一元素,某行第j个元素只能通过(*p)[j]访问。a[0]a[1]a[2]p,ap+1p+2举例:输出二维数组任一行任一列元素的值。#include<stdio.h>voidmain(){ inta[3][4]={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,&j); printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j)); p=p+1; printf("a[1][3]=%d\n",(*p)[3]); p=p+1; printf("a[2][2]=%d\n",(*p)[2]);}输入:i=1,j=1输出:a[1][1]=11a[1][3]=15a[2][2]=211357911131517192123a,a+0,p+0a+1,p+1a+2,p+28.3指针和字符串8.3.1常用字符串处理函数(string.h)1、字符串输入输出(1)scanf(格式串,输入参数表) 使用%s(2)printf(格式串,输出参数表) 使用%s(3)gets(字符数组)(4)gets(字符数组或字符串常量)例8-12(P174)2、字符串的复制、连接、比较、求长度(1)字符串复制strcpy(字符数组,字符数组或字符串常量)(2)字符串连接strcat(字符数组,字符数组或字符串常量)(3)字符串比较strcmp(字符串,字符串)(4)字符串长度strlen(字符串)

例8-13(P176)8

温馨提示

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

评论

0/150

提交评论