1 / 39

第 8 章 指 针

第 8 章 指 针. 8.1 指针的基本概念 8.2 指针和指针变量 8.3 一维数组和指针 8.4 指针数组 8.5 指针与函数 8.6 指针的指针 8.7 指针 与二维数组 8.8 main() 函数的参数. 第 8 章 指针. 8.1 指针的基本概念. 指针就是地址,是一种数据类型。 它是用来表示另外变量的地址。 “直接访问”方式:按变量地址直接对变量的值进行存取。

karli
Download Presentation

第 8 章 指 针

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. 第8章 指 针 • 8.1 指针的基本概念 • 8.2 指针和指针变量 • 8.3 一维数组和指针 • 8.4指针数组 • 8.5 指针与函数 • 8.6 指针的指针 • 8.7 指针与二维数组 • 8.8 main()函数的参数

  2. 第8章 指针 8.1 指针的基本概念 指针就是地址,是一种数据类型。它是用来表示另外变量的地址。 “直接访问”方式:按变量地址直接对变量的值进行存取。 “间接访问”方式:在访问变量时,不直接按变量的地址取其值,而将变量的地址存放在另一个存储单元中,要访问某变量时,先访问存放该变量地址的存储单元,再间接地访问变量,对变量进行存取操作。 返回章目录

  3. 第8章 指针 8.2 指针和指针变量 可以用运算符“*”来定义指针变量,也可以用“*”表示“指向”关系来使用指针变量。 8.2.1 指针变量的定义 指针变量是专门用于存放地址的变量,C语言将它定义为“指针类型”。定义指针变量的一般格式为:类型标识符 * 指针变量名 例如: int * p ; 我们说:p 是指向整型数据的指针,p的值是整型变量的地址。

  4. 第8章 指针 8.2.2 指针变量的赋值 与指针有关的运算符有两个: 运算符“&”:求变量的地址;*求指针所指变量的值。 可以用赋值语句使一个指针变量指向一个变量,例如: int i,j,*p1; p1=&i ; j = *p1; 也可以在定义指针变量的同时对其赋值,例如: int i=3 , *p1=&i ; int *p1=&i 相当于:int *p1; p1 = &i;

  5. 第8章 指针 指针变量的赋值 (1)指针变量定义和赋值注意: 例如: int i,*p, *p1=&i; *p=i ; 或 *p = *p1; 危险动作!,不知p指向那里,不能它赋值 应该:int *p, j; p=0; 或p=‘\0’; 或 p=NULL 或 p=&j; 然后,*p=i; 先让它指到一个“安全”地带,再给它赋与内容 (除0以处,不能把非地址整型值赋给指针) (2)指针变量互相赋值: int i=3 , *p1,*p2 ; p1=&i; p2 = p1; 使指针变量p2指向p1所指变量, p1,p2同时指向i变量。

  6. 第8章 指针 x d d 例:指针运算符 void main( ) { int d,x,*p,*q; d=5;p=&d; x=*p; printf("x=%d\n",x); *p=7; printf(“d=%d\n",d); q=p; printf(“*q=%d\n",*q); } q q p

  7. 第8章 指针 *和&是互逆运算。 已知:int a,*p; p=&a; 请考虑: *&a 与 a的关系 *&p 与 &*p 与p的关系 指针运算符: “*”和“&”优先级相同,自右向左运算。 “&”只能用于变量和数组元素。 void main( ) { int d,p; d=4; p=*&d; printf("p=%d\n",p); }

  8. 第8章 指针 8.2.3 指针变量的引用 可以通过指针运算符“*”引用指针变量,指针运算符可以理解“指向”的含义。 例:交换指针还是交换所指变量? void main( ) { int a=10,b=8,t,*p1,*p2,*pt; p1=&a;p2=&b; t=*p1;*p1=*p2;*p2=t; printf ("a =%d,b=%d\n",a,b); a=10; b=8; /*归位*/ pt=p1;p1=p2;p2=pt; printf("a=%d,b=%d\n",a,b); }

  9. 第8章 指针 8.2.4 指针变量作为函数参数 函数的参数是一般变量或常数时,函数实参向形参是单向值传递。 函数的参数是数组名时,则将实参数组名传递给形参数组名,数组名表示数组中第1个元素的地址,故这种传递是地址的传递。 函数参数也可以是指针变量,其作用是将变量的地址传到另一函数中去。 返回章目录

  10. 第8章 指针 指针变量作函数参数示例1:使函数返回多个值 void main( ) {int a=10,b=8; f(&a, &b); printf("a=%d,b=%d\n",a,b); } void f(int *x, int *y) /*函数f的功能是什么?*/ { *x=*x*2;*y=*y*2; }“遥控”作用。 x和y说:你只要让我指向你,我通过改变我指的内容,就能改变你!(类似文件副本与快捷方式)

  11. 第8章 指针 指针变量作函数参数示例2: 完善求一元二次方程根的函数getroot void main( ) {int a=3,b=8,c=2; float x1,x2; getroot(a, b,c,&x1,&x2); printf(“x1=%f,x2=%f\n",x1,x2); } void getroot(int a,int b,int c,float *root1, float *root2) { 补充内容; }

  12. 第8章 指针 指针变量作函数参数示例3:交换两个整数 void main( ) {int a=10,b=8; swap(&a,&b); printf(“%d,%d”,a,b) } void main( ) {int a=10,b=8; swap(a,b); printf(“%d,%d”,a,b) } void swap(int *x,int *y) {int t; /*用int *t行吗 */ t=*x;*x=*y;*y=t; }能交换 void swap(int x,int y) {int t; t=x;x=y;y=t; } 不能交换 void swap(int *x,int *y) {int *t; t=x; x=y; y=t; }不能交换 void swap(int *x,int *y) {int *t,q;t=&q; *t=*x;*x=*y;*y=*t; }能交换

  13. 第8章 指针 8.3 一维数组和指针 8.3.1 一维数组与指针 指针可以指向数组或数组元素. 一维数组中,第1个元素如a[0]的地址,即该数组的起始地址。可以用数组名方式,通过指向运算符“*”引用数组元素,也可以将指针变量指向一维数组,通过指针变量引用数组元素。例如: int a[10] , *p ; /* 定义a数组和指针变量p */ p=a ; /* a数组首地址→p */ 或p=&a[0] 使p指向了数组 a

  14. 第8章 指针 一维数组和指针示例 p+i是 a[i]的地址 ; *(p+i)是a[i]的值 . void main( ) {int *p1,*p2,*p3; static int a[ ]={1,2,3,4,5}; p1=a;p2=&a[2]; p3=p2+2; printf("a[ ]=%d\n",p1); printf("%d:%d\n",p2,*p2); printf("%d:%d\n",p3,*p3); } 结果: a[ ]=2003 2007:3 2011:5

  15. 第8章 指针 数组名常指针法: void main() {int a[]={1,2,3,4,5}; int i; for(i=0;i<5;i++) printf("%d\t", *(a+i)); } 不能使用a++ 指向数组的指针作为函数参数示例:下标法 void main() {int a[]={1,2,3,4,5}; int i; for(i=0;i<5;i++) printf("%d\t",a[i]); }

  16. 第8章 指针 两指针: void main() {int a[]={1,2,3,4,5}; int i,*p=a,*q=a+4; for(;p<=q;p++) printf("%d\t",*p); } 指针变量指向数组访问法: void main() {int a[]={1,2,3,4,5}; int i,*p=a; for(i=0;i<5;i++,p++) printf("%d\t",*p); }

  17. 第8章 指针 8.3.2 指向数组的指针作为函数参数 数组名作为函数参数,实现函数间地址的传递。指向数组的指针也可以作为函数参数,数组名和指针都是地址。在作为函数参数时有以下几种情况: 实参 形参 数组名 数组名 指针变量 指针变量 在实参向形参传递中,应保证其类型的一致性。 返回章目录

  18. 第8章 指针 形参,实参均为数组名: void inv(int x[],int n) {int t; int i,j; for(i=0;i<(n-1)/2;i++) {j=n-1-i;/*后边的下标*/ t=x[i];x[i]=x[j];x[j]=t; } }P237 数组名或指针作为函数形参与实参示例:逆置元素 void main() {int a[]={1,2,3,4,5}; int inv(int x[],int 5); inv(a,5); for(i=0;i<5;i++) printf("%d\t",a[i]); }

  19. 第8章 指针 形参指针,实参数组名: void inv(int *x,int n) {int *i,*p,*j; int t,m=(n-1)/2; i=x;j=x+n-1;p=x+m for(;i<=p;i++,j--) {t=*i;*i=*j;*j=t; } /*i左p终j右*/ }P238 数组名或指针作为函数形参与实参示例:逆置元素 void main() {int a[]={1,2,3,4,5}; int inv(int x[],int n); inv(a,5); for(i=0;i<5;i++) printf("%d\t",a[i]); }与前同

  20. 第8章 指针 8.3.3 指针与字符串 C语言中,一个字符串可以存放在一个字符数组中,数组名表示该字符串第一个字符存放的 地址,也可以将字符串的首地址赋给一个字符型指针变量中,该指针变量便指向这个字符串,或者说,指针变量可以指向任一字符串的首地址。 例如: char *str="I love China" ; 或 char *str ; str="I love China" ; char str[]= ="I love China" ; 可以 char str[20]; str[20]="I love China" ; 不可以

  21. 第8章 指针 main( ) {static char *p,s[ ]=" abcdef\n "; p=s; printf("%s\n",p); while(*p!=‘\0’) {printf("%c",*p++);} } 指向字符数组示例: 打印字符串 main( ) {static char s[ ]=" abcdef\n "; printf("%s\n",s); } main( ) {char *s=" abcdef\n "; printf("%s\n",s); } 注意: char s[ ] char *s

  22. 第8章 指针 指针与字符串例:字符串复制 void str_cpy(char *s,char *t) /*char s[],char t[]*/ {while(*t!=0) /*while(*t)*/ {*s=*t;s++;t++;} /* *(s++)=*(t++) */ *s='\0'; } void main() {char *str2;char str1[80]; str2=“welcome“; str_cpy(str1,str2); puts(str1); }

  23. 第8章 指针 8. 4 指针数组 由指针构成的数组。定义形式为: 类型标识符 *指针变量名[ ] ; 例如: char *p[ 13] ; p是一个有13个元素的数组,每个元素都是指向char类型的指针。 *p[i]可存取一个字符; p[i]可存取一个字符串。 当处理长度不等的字符串时,数组指针很方便。 返回章目录

  24. 第8章 指针 指针数组例1 #include <stdio.h> void main( ) {int i; int a=10, b=8; int *p1=&a,*p2=&b; int *x[2]; x[0]=p1,x[1]=p2; printf("*x[0]=%d\n",*x[0]); printf("*x[1]=%d\n",*x[1]); }把一群指针纳入数组进行管理 返回章目录

  25. 第8章 指针 指针数组例2 void main( ) {int i; int a[]={1,2,3}; int b[]={3,4,5}}; int *p[2]; /*p 是数组,元素是指针*/ p[0]=a;p[1]=b; printf("%d,%d,%d\n",*p[0],*(p[0]+1),*(p[0]+2)); printf("%d,%d,%d\n",*p[1],*(p[1]+1),*(p[1]+2)); } 返回章目录

  26. 第8章 指针 指针数组例3 void main( ) {int n; char *day-name( ); scanf(“%d”,&n); printf(“%d day:%s\n”,n,day-name(n)); } char *day-name(int n) {char *name[ ]={“illegal day”,”Mon”,”Tues”,”Wen”,”Thurs”, ”Friday”,”Sat”,”Sun”}; return((n<1|n>7)?name[0]:name[n]);| }函数返回一个指向包含第N天名字的字符串的指针。 name指针数组存储字符串列表。各串不等,由系统计数。

  27. 第8章 指针 指针数组例4 while(n--) { printf("%s",digt[x[n]]); printf("%s",dw[n]); } } #include <stdio.h> void main() /*整数人民币转换,不完善*/ { char *digt[]={" ","一","二","三","四","五","六","七","八","九"}; char *dw[]={"元","十","百","千","万"}; int m; int n=0,x[5]; scanf("%d",&m); while(m!=0) { x[n]=m%10; /*printf("%d\t",x[n]); */ m=m/10; n++; }

  28. 第8章 指针 8.5 指针与函数 8.5.1 指向函数的指针 指向函数的指针叫做函数指针。一个函数在编译时被分配给一个入口地址,这个入口地址称为函数的指针。可以定义一个指向函数的指针变量,将函数入口地址赋予指针变量,然后通过指针变量调用此函数。 指向函数的指针变量定义形式为: 类型标识符 (*指针变量名)( ) ; ↑ 函数返回值的类型 例如: int (*p)( ) ; P表示一个指向函数的指针,P指向的函数返回整型数据。 返回章目录

  29. 第8章 指针 而 int *p( ) ; 表示p是一个函数,返回整型指针的函数。前者是指针,后者是函数。函数指针可用来传递函数。 void main( ) {int (*pi)( int x); int prnx(int x); pi=prnx; /*不加 ( )*/; (*pi)(123); } prnx(int x ) { printf("%d\n",x); } 返回章目录

  30. 第8章 指针 例2: 由用户指定分别求x2-2和 x3-2x+5的值 double f1(double x ) {return (x*x-2);} double f2(double x ) { return (x*x*x-2*x+5); } void main( ) {int i;double x; double (*fp)(double); scanf("%d%lf",&i,&x); if(i==1) fp=f1; else fp=f2; printf("f(x)=%lf ",(*fp)(x)); }

  31. 第8章 指针 8.5.2 返回指针的函数 例: #include <stdio.h> void main( ) {int i; int *p; int *f(int x,int y); p=f(10,8); printf("max=%d\n",*p); } int *f(int x,int y) { int *q; if(x>y) q=&x; else q=&y; return(q); }

  32. 第8章 指针 8.6 指针的指针称二级指针。即一个指针存放另一指针的地址。 例: #include <stdio.h> void main() { int a=3; int *p1=&a; int **pp; pp=&p1; printf("**p=%d\n",**pp); printf("*p1=%d\n",*p1); }

  33. 第8章 指针 8.7 指针与二维数组 二维数组中: a+i,a[i],*(a+i),&a[i],&a[i][0] 它们都表示地址,且地址值是相等的,但指针类型不同。 a+i和&a[i]指向行,表示第i行首地址; a[i]和*(a+i)用于指向列,表示第i行第0列元素地址。 a[i]+j和*(a+i)+j表示第i行第j列元素地址,见表8-1。

  34. 第i行j列元素地址 第i行j列元素值 a[i]+j *(a[i]+j) *(a+i)+j *(*(a+i)+j) &a[i][j] a[i][j] 第8章 指针 表8-1 第i行第j列元素地址及其元素值

  35. 第8章 指针 指针与二维 数组例: #include <stdio.h> void main() {int a[2][3]={{1,2,3},{4,5,6}}; int *p=a; printf("a=%d,a[0]=%d,&a[0]=%d,p=%d\n",a,a[0],&a[0],p); printf("*a=%d,**a=%d,*a[0]=%d,*p=%d\n",*a,**a,*a[0],*p); printf("a[1]=%d,a+1=%d\n",a[1],a+1); printf("*a[1]=%d,*(a+1)=%d\n",*a[1],*(a+1)); printf("a[0]+1=%d,p+1=%d\n",a[0]+1,p+1); printf("*(a[0]+1)=%d,*(p+1))=%d\n",*(a[0]+1),*(p+1)); printf("*(p+5)=%d,*(*(a+1)+1))=%d\n",*(p+5),*(*(a+1)+1)); }

  36. 第8章 指针 说明: a指向第0行首址,即&a[0] a+1指向第1行首址,即&a[1] a+i指向第i行首址,即&a[i] *a指向0行0列首址a[0][0] *(a+1)指向1行0列a[1][0] *(a+i)指向i行0列a[i][0] *(a+i)+j,a[i]+j指向a[i][j] *(*(a+i)+j),*(a[i]+j)即a[i][j] 从值上看:a 和*a, a+1和*(a+1)相等。 但a+1 与 *a+1不同。前者走1行,后者走1列。 上例中,a指针加1跨度大,p和a[i]跨度小

  37. 第8章 指针 8. 8 main()函数的参数 main(int agrc,char *argv[ ]) argc是整型数,表示命令行参数个数,命令名为第一个参数,故 argc至少为1。 argv是指向命令行参数(含命令名)字符串的指针数组。argv[0], argv[1], argv[2]分别指命令名,第2参数,第3参数. 例: void main(int agrc,char *argv[ ] ) {int i; for(i=1;i<argc;i++) printf(“%s%c”,argv[i], (i<agrc-1)? ’ ‘ : ’\n’ ); }

  38. 第8章 指针 main()函数的参数 例: void main(int agrc,char *argv[ ]) {int i,n; n=agrc; for(i=0;i<n;i++) printf(“%s”,argv[i] ); } 返回章目录

  39. 第8章 指针 指针小结 定义 意义 int i; 整型变量 int *p; 指向整型数据的指针 int *p[n]; 由n个指向整型数据的指针组成的指针数组 int (*p)[n]; 指向n个整型数据的数组的指针 int p( ); 返回整型数据的函数 int *p( ); 返回整型指针的函数 int (*p)( ); 指向整型函数的指针(函数指针)

More Related