1 / 80

指 针

指 针. C 程序设计中使用指针可以 : 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 能直接处理内存地址 得到多于一个的函数返回值 能方便的使用数组和字符串. 内存. 0. …. 2000. 2001. 2002. 2003. 2005. …. 内存中每个字节有一个编号 ----- 地址. 地址和指针的概念 变量与地址. 程序中 : int i=3; float k=3.5;. 3. 变量 i. 编译或函数调用时为其分配内存单元. 3.5. 变量 k.

eyal
Télécharger la présentation

指 针

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 指 针 C程序设计中使用指针可以: • 使程序简洁、紧凑、高效 • 有效地表示复杂的数据结构 • 动态分配内存 • 能直接处理内存地址 • 得到多于一个的函数返回值 • 能方便的使用数组和字符串

  2. 内存 0 …... 2000 2001 2002 2003 2005 …... 内存中每个字节有一个编号-----地址 地址和指针的概念 • 变量与地址 程序中: int i=3; float k=3.5; 3 变量i 编译或函数调用时为其分配内存单元 3.5 变量k 在程序中是通过变量名来对内存单元进行存取操作的

  3. …... 整型变量i 2000 10 2001 2002 2003 变量i_pointer 2004 2000 指针变量 2005 2006 …... • 直接访问与间接访问 • 直接访问:按变量地址存取变量值 • 间接访问:通过存放变量地址的变量去访问变量 例i=3; -----直接访问 3 20 例i_pointer=&I; *i_pointer=20; -----间接访问

  4. …... 整型变量i 2000 10 2001 2002 2003 变量i_pointer 2004 2005 变量地址(指针) 指针变量 2006 地址存入 指针变量 指向 …... 变量值 变量 • 变量的指针与指向变量的指针变量 • 指针:一个变量的地址 • 指针变量:专门存放变量地址的变量叫~ 指针 变量的内容 变量的地址 2000 指针变量

  5. *i_pointer i_pointer 10 2000 &i_pointer i …... 整型变量i 2000 10 2001 2002 2003 变量i_pointer 2004 2000 指针变量 2005 2006 …... 含义: 取变量的地址 单目运算符 优先级: 2 结合性:自右向左 含义:取指针所指向变量的内容 单目运算符 优先级: 2 结合性:自右向左 • 两者关系:互为逆运算 • &与*运算符 • 含义 i_pointer &i &(*i_pointer) i *i_pointer *(&i) i_pointer=&i=&(*i_pointer) i=*i_pointer =*(&i) i_pointer-----指针变量,它的内容是地址量 *i_pointer----指针所指的目标变量的值,它的内容是数据 &i_pointer---指针变量占用内存的地址

  6. …... 整型变量i 2000 10 2001 整型变量k 2002 2003 变量i_pointer 2004 2005 2000 指针变量 2006 …... 例k=i; --直接访问 k=*i_pointer; --间接访问 例k=i; k=*i_pointer; 10

  7. i i *i_pointer *i_pointer i_pointer i_pointer 变量i 变量i &i &i i_pointer i_pointer 2000 2000 3 3 i=3; i=3; *i_pointer=3 *i_pointer=3 *i_pointer *i_pointer 指针变量 指针变量与其所指向的变量之间的关系 • 指针变量的定义 • 一般形式: [存储类型]数据类型 *指针名; 例 int*p1,*p2; float *q ; static char *name; 表示定义指针变量 不是‘*’运算符 合法标识符 指针变量本身的存储类型 指针的目标变量的数据类型 注意: 1、int *p1, *p2;与 int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值

  8. 例int *p=&i; int i; 例 int i; int *p=&i; 赋给指针变量, 不是赋给目标变量 变量必须已说明过 类型应一致 • 指针变量的初始化 一般形式:[存储类型]数据类型 *指针名=初始地址值; 例 int i; int *p=&i; int *q=p; 用已初始化指针变量作初值

  9. …... 整型变量i 2000 10 2001 2002 2003 指针变量p 2004 2005 随机 2006 …... • 指针变量的引用 例 main( ) { int i=10; int *p; *p=i; printf(“%d”,*p); } 危险! 例:通过指针变量访问整形变量main( ) { int i=10,k; int *p; p=&k; *p=i; printf(“%d,%d”,k,*p); } 指针变量必须先赋值,再使用

  10. …... 整型变量a f86 10 f87 指针变量pa f88 f86 f89 f8a f8b f8c …... 例 指针的概念 运行结果: a:10 *pa:10 &a:f86(hex) pa:f86(hex) &pa:f88(hex) main() { int a; int *pa=&a; a=10; printf("a:%d\n",a); printf("*pa:%d\n",*pa); printf("&a:%x(hex)\n",&a); printf("pa:%x(hex)\n",pa); printf("&pa:%x(hex)\n",&pa); }

  11. …... 2000 指针变量p1 2002 2004 指针变量p 指针变量p2 整型变量a 整型变量b 2006 2008 …... 例 输入两个数,并使其从大到小输出 main() { int *p1,*p2,*p,a,b; scanf("%d,%d",&a,&b); p1=&a; p2=&b; if(a<b) { p=p1; p1=p2; p2=p;} printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); } 2008 2006 2006 2008 2006 5 9 运行结果:a=5,b=9 max=9,min=5 不交换整型变量的值,而是交换两个指针变量的值

  12. 指针变量作为函数参数——地址传递 • 特点:共享内存,“双向”传递 例将数从大到小输出 swap(int x,int y) { int temp; temp=x; x=y; y=temp; } main() { int a,b; scanf("%d,%d",&a,&b); if(a<b) swap(a,b); printf("\n%d,%d\n",a,b); } 值传递 运行结果:5, 9

  13. …... (main) 2000 2002 指针p2 指针pointer_2 指针pointer_1 指针p1 整型变量a 整型p 2004 2006 整型变量b 2000 2008 2002 (swap) 200A 200C 200E ... 2010 例将数从大到小输出 swap(int *p1, int *p2) { int p; p=*p1; *p1=*p2; *p2=p; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b)swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); } 9 5 5 9 2000 2002 COPY 5

  14. …... (main) 2000 2002 指针pointer_2 指针pointer_1 整型变量a 2004 2006 整型变量b 2008 200A 200C 200E ... 2010 例将数从大到小输出 swap(int *p1, int *p2) { int p; p=*p1; *p1=*p2; *p2=p; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b)swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); } 9 5 5 9 2000 地址传递 2002 运行结果:9,5

  15. …... (main) 2000 2002 pointer_2 指针p pointer_1 指针p1 指针p2 整型a 2004 2006 整型b 2000 2008 2002 (swap) 200A 200C **** 200E ... 2010 例将数从大到小输出 swap(int *p1, int *p2) { int *p; p=p1; p1=p2; p2=p; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("%d,%d",*pointer_1,*pointer_2); } 5 9 地址传递 2000 2002 COPY 2002 2000 2000 运行结果:5,9

  16. a Pointer_1 (*Pointer_1) 5 &a Pointer_2 b (*Pointer_2) 9 &b 例将数从大到小输出 /*ch9_32.c*/ swap(int x,int y) { int t; t=x; x=y; y=t; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(*pointer_1,*pointer_2); printf("\n%d,%d\n",a,b); } 值传递 运行结果:5,9

  17. 指针与数组 指向数组元素的指针变量 p array[0] array[1] array[2] array[3] ... array[9] 整型指针p &array[0] 例 int array[10]; int *p; p=&array[0]; // p=array; 或 int *p=&array[0]; 或 int *p=array; 数组名是表示数组首地址的地址常量

  18. 如int i, *p; p=1000; () i=p; () • 指针的运算 • 指针变量的赋值运算 • p=&a; (将变量a地址p) • p=array; (将数组array首地址p) • p=&array[i]; (将数组元素地址p) • p1=p2; (指针变量p2值p1) • 不能把一个整数p,也不能把p的值整型变量 指针变量与其指向的变量具有相同数据类型

  19. 指针的算术运算: a数组 p a[0] p+1,a+1 a[1] a[2] a[3] a[4] p+i,a+i a[5] a[6] a[7] a[8] p+9,a+9 a[9] 例 p指向float数,则 p+1  p+1 4 例 p指向int型数组,且p=&a[0]; 则p+1 指向a[1] 1 例 int a[10]; int *p=&a[2]; p++; *p=1; 例 int a[10]; int *p1=&a[2]; int *p2=&a[5]; 则:p2-p1=3; • pi  p id (i为整型数,d为p指向的变量所占字节数) • p++, p--, p+i, p-i, p+=i, p-=i等 • 若p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d • p1+p2 无意义

  20. 指针变量的关系运算 • 若p1和p2指向同一数组,则 • p1<p2 表示p1指的元素在前 • p1>p2 表示p1指的元素在后 • p1==p2 表示p1与p2指向同一元素 • 若p1与p2不指向同一数组,比较无意义

  21. 地址 p[0] a[0] a[0] a[0] *p *a 元素 地址 元素 *(p+1) *(a+1) p[1] a[1] a[1] a[1] *(p+2) *(a+2) p[2] a[2] a[2] a[2] p a a[3] a[3] p+1 a+1 p+2 a+2 a[9] a[9] p[9] *(p+9) *(a+9) a[9] ... ... p+9 a+9 指针法 下标法 [] 变址运算符 a[i] *(a+i) • 数组元素表示方法 a[i]  p[i]  *(p+i) *(a+i)

  22. pa a[0] 1 a[1] 2 a[2] 3 a[3] 4 a[4] 5 例 数组元素的引用方法 main() { int a[5],*pa,i; for(i=0;i<5;i++) a[i]=i+1; pa=a; for(i=0;i<5;i++) printf("%d\n",i,*(pa+i)); for(i=0;i<5;i++) printf("%d\n",i,*(a+i)); for(i=0;i<5;i++) printf("%d\n",i,pa[i]); for(i=0;i<5;i++) printf("%d\n",i,a[i]); for(;pa<(a+5);pa++) printf(“%d\n”,*pa)}

  23. a 0 5 1 8 p p 2 7 3 6 4 2 5 7 6 3 注意:1、指针变量的运算 例 void main() { int a []={5,8,7,6,2,7,3}; int y,*p=&a[1]; y=(*--p)++; printf(“%d ”,y); printf(“%d”,a[0]); } 6 输出:5 6 *(p++)与 *(++p)的不同(*p)++ a[0]++

  24. a 0 5 1 8 p p p p p p p p 2 7 3 6 4 2 5 7 6 3 注意:2、指针的当前值 main() { int i,*p,a[7]; p=a; for(i=0;i<7;i++) scanf("%d",p++); printf("\n"); for(i=0;i<7;i++,p++) printf("%d",*p); } p=a; 指针变量可以指到数组后的内存单元

  25. 实参 形参 数组名 数组名 数组名 指针变量 指针变量 数组名 指针变量 指针变量 • 数组名作函数参数 • 数组名作函数参数,是地址传递 • 数组名作函数参数,实参与形参的对应关系

  26. 0 1 2 3 4 5 6 7 8 9 i j i j i j i j i j 3 7 9 11 0 6 7 5 4 2 2 4 5 7 6 0 11 9 7 3 例 将数组a中的n个整数按相反顺序存放 void inv(int x[], int n) { int t,i,j,m=(n-1)/2; for(i=0;i<=m;i++) { j=n-1-i; t=x[i]; x[i]=x[j]; x[j]=t; } } main() { int i,a[10]={3,7,9,11,0,6,7,5,4,2}; inv(a,10); printf("The array has been reverted:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); } m=4 实参与形参均用数组

  27. a数组 x 2 a[0] 3 i i i i 4 a[1] 7 5 a[2] 9 7 a[3] 11 p=x+m 6 a[4] 0 0 6 a[5] 11 7 a[6] 9 5 a[7] j j j j 7 4 a[8] j i 2 3 a[9] 例 将数组a中的n个整数按相反顺序存放 void inv(int *x, int n) { int t,*p,*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; } } main() { int i,a[10]={3,7,9,11,0,6,7,5,4,2}; inv(a,10); printf("The array has been reverted:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); } 实参用数组,形参用指针变量

  28. 例 将数组a中的n个整数按相反顺序存放 void 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,a[10],*p=a; for(i=0;i<10;i++,p++) scanf("%d",p); p=a;inv(p,10); printf("The array has been reverted:\n"); for(p=a;p<a+10;p++) printf("%d",*p); } 实参与形参均用指针变量

  29. 例 将数组a中的n个整数按相反顺序存放 void inv(int x[], int n) { int t,i,j,m=(n-1)/2; for(i=0;i<=m;i++) { j=n-1-i; t=x[i]; x[i]=x[j]; x[j]=t; } } main() { int i,a[10],*p=a; for(i=0;i<10;i++,p++) scanf("%d",p); p=a;inv(p,10); printf("The array has been reverted:\n"); for(p=arr;p<arr+10;p++) printf("%d ",*p); } 实参用指针变量,形参用数组

  30. 一级指针变量与一维数组的关系 • int *p 与 int q[10] • 数组名是指针(地址)常量 • p=q; p+i 是q[i]的地址 • 数组元素的表示方法:下标法和指针法, 即若p=q, 则 p[i]  q[i]  *(p+i)  *(q+i) • 形参数组实质上是指针变量,即int q[ ]  int *q • 在定义指针变量(不是形参)时,不能把int *p 写成int p[]; • 系统只给p分配能保存一个指针值的内存区(一般2字节);而给q分配2*10字节的内存区

  31. 例 int a[]={1,2,3,4,5,6,7,8,9,10},*p=a,i; 数组元素地址的正确表示:(A)&(a+1) (B)a++ (C)&p (D)&p[i]  数组名是地址常量 p++,p-- () a++,a-- () a+1, *(a+2) ()

  32. int array[10]; array • 指针与二维数组 • 二维数组的地址 对于一维数组: (1)数组名array表示数组的首地址,即array[0]的地址; (2)数组名array是地址常量 (3)array+i是元素array[i]的地址 (4)array[i]  *(array+i)

  33. *(a[0]+1) *(*(a+0)+1) 2000 a 2000 a[0] a[0][0] 2002 a[0]+1 a[0][1] *(a+0)+1 a[0][2] a[0][3] 2008 a+1 2008 a[1] a[1][0] 2010 a[1]+1 a[1][1] *(a+1)+1 a[1][2] a[1][3] 2016 a+2 2016 a[2] a[2][0] 2018 a[2]+1 a[2][1] *(a+2)+1 a[2][2] a[2][3] 行指针与列指针 int a[3][4]; 对于二维数组: (1)a是数组名, 包含三个元素 a[0],a[1],a[2] (2)每个元素a[i] 又是一个一维 数组,包含4个 元素

  34. int a[3][4]; 2000 2000 a a[0][0] a[0] 2002 a[0][1] a[0][2] a[0][3] 2008 2008 a+1 a[1][0] a[1] 2010 a[1][1] a[1][2] a[1][3] 2016 a+2 2016 a[2] a[2][0] 2018 a[2][1] a[2][2] a[2][3] • 对二维数组 int a[3][4],有 • a-----二维数组的首地址,即第0行的首地址 • a+i-----第i行的首地址 • a[i]  *(a+i)------第i行第0列的元素地址 • a[i]+j  *(a+i)+j -----第i行第j列的元素地址 • *(a[i]+j)  *(*(a+i)+j)  a[i][j] • a+i=&a[i]=a[i]=*(a+i) =&a[i][0], 值相等,含义不同 • a+i  &a[i],表示第i行首地址,指向行 • a[i]  *(a+i)  &a[i][0],表示第i行第0列元素地址,指向列

  35. int a[3][4]; 行指针 a[0][0] a[0][1] 列指针 a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] 地址表示: (1) a+1 (2) &a[1][0] (3) a[1] (4) *(a+1) (5)(int *) (a+1) 地址表示: (1) &a[1][2] (2) a[1]+2 (3) *(a+1)+2 (4)&a[0][0]+1*4+2 二维数组元素表示形式: (1)a[1][2] (2)*(a[1]+2) (3)*(*(a+1)+2) (4)*(&a[0][0]+1*4+2)

  36. 表示形式 地址 含义 a 2000 二维数组名,数组首地址 2000 a[0],*(a+0),*a 第0行第0列元素地址 2008 a+1 第1行首地址 2008 第1行第0列元素地址 a[1],*(a+1) 2012 第1行第2列元素地址 a[1]+2,*(a+1)+2,&a[1][2] 第1行第2列元素值 13 *(a[1]+2),*(*(a+1)+2),a[1][2]

  37. p int a[3][4]; a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] p=*a; p=&a[0][0]; p=(int *)a; p=a; a[2][1] a[2][2] a[2][3] 例 指向二维数组元素的指针变量 main() { static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int *p; for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0) printf("\n"); printf("%4d ",*p); } } • 二维数组的指针变量 • 指向二维数组元素的指针变量 p=*a; p=&a[0][0]; p=*(a+0); p=a;

  38. p a int a[3][4]; p[0]+1或 *p+1 a[0][0] *(*p+1)或 (*p)[1] a[0][1] a[0][2] p+1 a+1 a[0][3] a[1][0] p[1]+2或 *(p+1)+2 a[1][1] *(*(p+1)+2) a[1][2] p+2 a+2 a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] • 可让p指向二维数组某一行 • 如 int a[3][4], (*p)[4]=a; p的值是一维数组的 首地址,p是行指针 ( )不能少 int (*p)[4]与int *p[4]不同 • 指向一维数组的指针变量 • 定义形式: 数据类型 (*指针名)[一维数组维数]; 例 int (*p)[4]; 一维数组指针变量维数和 二维数组列数必须相同

  39. p p p int a[3][4]; a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] p=a[0]; p=*a; p=&a[0][0]; p=&a[0]; a[2][1] a[2][2] a[2][3] 例 一维数组指针变量举例 main() { static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int i,j,(*p)[4]; for(p=a,i=0;i<3;i++,p++) for(j=0;j<4;j++) printf("%d ",*(*p+j)); printf("\n"); }  p[0][j] p=a[0]; p=*a; p=&a[0][0]; p=&a[0];

  40. q q q p p p 3 4 2 1 3 4 5 6 5 6 7 8 例 二维数组与指针运算 main() { int a[3][4]={{1,2,3,4},{3,4,5,6},{5,6,7,8}}; int i; int (*p)[4]=a,*q=a[0]; for(i=0;i<3;i++) { if(i==0) (*p)[i+i/2]=*q+1; else p++,++q; } for(i=0;i<3;i++) printf("%d,",a[i][i]); printf("%d,%d\n",*((int *)p),*q); } 2 运行结果:2,4,7,5,3

  41. 若int a[3][4];int (*p1)[4]=a;int *p2=a[0]; 实参 形参 数组名a 数组名int x[][4] 数组名a 指针变量int (*q)[4] 指针变量p1 数组名int x[][4] 指针变量p1 指针变量int (*q)[4] 指针变量p2 指针变量int *q • 二维数组的指针作函数参数 • 用指向变量的指针变量 • 用指向一维数组的指针变量 • 用二维数组名

  42. 79 60 52 65 80 87 90 81 90 99 100 98 p p 例 3个学生各学4门课,计算总平均分,并输出第n个学生成绩 函数说明 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.2f\n",aver); } void search(float (*p)[4], int n) { int i; printf(" No.%d :\n",n); for(i=0;i<4;i++) printf("%5.2f ",*(*(p+n)+i)); } main() { void average(float *p,int n); void search(float (*p)[4],int n); float score[3][4]= {{65,67,79,60},{80,87,90,81}, {90,99,100,98}}; average(*score,12); search(score,2); } 列指针 行指针 float p[][4]  p[n][i]

  43. void search(float (*p)[4], int n) { int i,j,flag; for(j=0;j<n;j++) { flag=0; for(i=0;i<4;i++) if(*(*(p+j)+i)<60) flag=1; if(flag==1) { printf("No.%d is fail,his scores are:\n",j+1); for(i=0;i<4;i++) printf("%5.1f ",*(*(p+j)+i)); printf("\n"); } } } p 79 60 52 65 80 87 90 81 90 99 100 98 main() { void search(float (*p)[4], int n); float score[3][4]={{...},{...},{...}}; search(score,3); } 例 3个学生各学4门课,计算总平均分,并查找一门以上课 不及格学生, 输出其各门课成绩  p[j][i]

  44. 二维数组与一维数组指针变量的关系 • 如 int a[5][10] 与int (*p)[10]; 二维数组名是一个指向有10个元素的一维数组的指针常量 p=a+i 使 p指向二维数组的第i行 *(*(p+i)+j)  a[i][j] 二维数组形参实际上是一维数组指针变量, 即 int x[ ][10]  int (*x)[10] 变量定义(不是形参)时两者不等价 系统只给p分配能保存一个指针值的内存区(一般2字节);而给a分配2*5*10字节的内存区

  45. string string[0] I string[1] string[2] l string[3] o string[4] v string[5] e string[6] string[7] C string[8] h string[9] i string[10] n string[11] a string[12] ! string[13] \0 例 main( ) { char string[]=“I love China!”; printf(“%s\n”,string); printf(“%s\n”,string+7); } • 指针与字符串 • 字符串表示形式 • 用字符数组实现

  46. string I l o string v e C h i n a ! \0 • 用字符指针实现 字符指针初始化:把字符串首地址赋给string  char *string; string=“I love China!”; 例 main( ) { char *string=“I love China!”; printf(“%s\n”,string); string+=7; while(*string) { putchar(string[0]); string++; } } *string!=0

  47. b b to y I a a o from I u a m a a m r a e a t a t e e a s a c t c h u h e d e r r e . n . \0 t t \0 . . \0 \0 void copy_string(char from[],char to[]) { int i=0; while(from[i]!='\0') { to[i]=from[i]; i++; } to[i]='\0'; } main() { char a[]="I am a teacher."; char b[]="You are a student."; printf("string_a=%s\n string_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); } 例 用函数调用实现字符串复制 void copy_string(char *from,char *to) { for(;*from!='\0';from++,to++) *to=*from; *to='\0'; } main() { char *a="I am a teacher."; char *b="You are a student."; printf("string_a=%s\nstring_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); } (1)用字符数组作参数 • 字符串指针作函数参数 (2)用字符指针变量作参数

  48. 字符指针变量与字符数组 char *cp; 与char str[20]; • str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址 • char str[20]; str=“I love China!”; () char *cp; cp=“I love China!”; () • str是地址常量;cp是地址变量 • cp接受键入字符串时,必须先开辟存储空间 例 char str[10]; scanf(“%s”,str); () 而 char *cp; scanf(“%s”, cp); () 改为: char *cp,str[10]; cp=str; scanf(“%s”,cp); ()

  49. scanf(“%s”,str); printf(“%s”,str); gets(str); puts(str); 字符串与数组关系 • 字符串用一维字符数组存放 • 字符数组具有一维数组的所有特点 • 数组名是指向数组首地址的地址常量 • 数组元素的引用方法可用指针法和下标法 • 数组名作函数参数是地址传递等 • 区别 • 存储格式:字符串结束标志 • 赋值方式与初始化 • 输入输出方式:%s %c char str[10],*cp; int a[10],*p; str=“Hello”; () cp=“Hello!”; () a={1,2,3,4,5}; () p={1,2,3,4,5}; () char str[]={“Hello!”}; () char str[]=“Hello!”; () char str[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘!’}; () char *cp=“Hello”; () int a[]={1,2,3,4,5}; () int *p={1,2,3,4,5}; ()

  50. max 指令1 指令2 …... • 指向函数的指针变量 • 定义形式: 数据类型 (*指针变量名)(); • 如 int (*p)(); • 指针与函数 • 函数指针:函数在编译时被分配的入口地址,用函数名表示 ( )不能省 int (*p)() 与 int *p()不同 • 函数指针变量赋值:如p=max; 专门存放函数入口地址 可指向返回值类型相同的不同函数 函数返回值的数据类型 • 函数调用形式: c=max(a,b);  c=(*p)(a,b);  c=p (a,b); • 对函数指针变量pn, p++, p--无意义 函数指针变量指向的函数必须有函数说明

More Related