1 / 68

第七章 指针

第七章 指针. 7 .1 初识指针 7 .2 指针与函数 7.3 二维数组与指针 7.4 指针数组和指向指针的指针 7.5 指向函数的指针 7.6 动态数组. 7.1 初识指针.  什么是 指针 ? 地址 称为指针. 房间地址 — 指针. 409 房间. 轻松小屋. 房间名 — 变量 编程时定义 编译时指定地址. 住的人 — 值 可以发生变化. int sum; sum=7; 变量名为 sum, sum 有确定的地址 &sum, sum 值为 7 通过 sum 和 &sum 都可以访问到 7

reece-lucas
Download Presentation

第七章 指针

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. 第七章 指针 7.1 初识指针 7.2 指针与函数 7.3二维数组与指针 7.4指针数组和指向指针的指针 7.5指向函数的指针 7.6 动态数组

  2. 7.1 初识指针 什么是指针? 地址称为指针 房间地址—指针 409房间 轻松小屋 房间名—变量 编程时定义 编译时指定地址 住的人—值 可以发生变化

  3. int sum; sum=7; 变量名为sum, sum有确定的地址&sum, sum值为7 通过sum和&sum都可以访问到7 地址空间的大小(有哪些房间号)和变量的具体地址分别由硬件系统和编译系统决定

  4. 2000 2000 10 i_point i 指针变量 专门用于存放地址的变量称为指针变量 int i; i=10; 假设&i为2000; 定义: int *i_point; i_point=&i;

  5. 2000 2000 10 i_point i int i; i=10; 假设&i为2000; 定义: int *i_point; i_point=&i; 用*i_point表示所指向的存储单元的值 即i的值,通过i_point可以访问i,称为间接访问

  6. 4个字节,可以放int、 float类型数据 8个字节, 放double类型数据 1个字节, 放char类型数据 首地址只有一个,存储空间大小和存储方式? 定义指针变量也需要指出指向数据的类型 指针变量定义: 类型 *标识符

  7. pointer_i i pointer_j j 指针变量的定义与初始化 指针变量定义: 类型 *标识符 例: int i,j; float x; int *pointer_i, *pointer_j; float *pf; 在程序中可以赋值: pointer_i=&i; pointer_j=&j; pf=&x; 初始化: int a,*p=&a ; float x,*pf=&x;

  8. point_1=&a不能缺少,否则point_1是个悬空的指针 指针变量的使用 int main( ) {int a,b; int *point_1,*point_2; a=100; b=10; point_1=&a; point_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*point_1,*point_2); return 0; } 涵义不同

  9. int a,b; int *p1,*p2; a=100; b=10; p1=&a; p2=&b; 比较: a=5; *p1=5; p1=5; 比较: p1=&a; *p1=a; *p1=&a;

  10. p1 a b p2 阅读程序 int 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); return 0; } 3 5

  11. a 数组与指针 数组的首地址-----数组的指针 数组元素的地址----数组元素的指针 int a[10]; int *p,*s,i; p=&a[0]; s=&a[5]; &a[0]与a等价 p s

  12. int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int a[6]={0,11,22,33,44,55}; b 200 1 a 值 204 2 数组的内存组织 100 0 208 3 地址 212 1 4 104 11 216 5 108 220 22 6 224 7 112 33 228 8 232 116 9 44 236 1 10 120 55 240 11 244 12

  13. 若p=&a[0]或p=a p指向数组a的第0个元素a[0] C语言规定: p+i表示数组第i个元素a[i]的地址 值相当于 a+i*sizeof(a[0]) 因此: 指针p+i、a+i均指向a[i] *(a+i) 、*(p+i) 就是a[i]

  14. 引用数组元素的方法 (1)下标法 a[i] (2)指针法:p[i]、*(a+i)、*(p+i) 注意:数组名是指针变量? int a[10],i,s=0; int *p; for (p=a; p<a+10; p++) scanf("%d",p); for (p=a,i=0; i<10; i++) s+=*(p+i); for (p=a; p<a+10; p++) printf("%4d",*p); 指针法 int a[10]、p=a不能少

  15. 下标法 int a[3][4],s=0; int *p; p=&a[0][0]; for (i=0; i<3; i++) for(j=0; j<4; j++) scanf("%d",p+i*4+j); for(p=&a[0][0]; p<&a[0][0]+12; p++) s+ =*p; for (i=0; i<3; i++) {p=&a[i][0]; for(j=0; j<4; j++) printf("%4d",*(p+j)); } int a[3][4],s=0; for (i=0; i<3; i++) for(j=0; j<4; j++) scanf("%d",&a[i][j]); for (i=0; i<3; i++) for(j=0; j<4; j++) s+ = a[i][j]; for (i=0; i<3; i++) for(j=0; j<4; j++) printf("%4d",a[i][j]); 指针法

  16. b[0][0]是第0个元素 b[0][1]是第1个元素 b[0][2]是第2个元素 b[0][3]是第3个元素 b[1][0]是第4个元素 b[1][1]是第5个元素 b[1][2]是第6个元素 b[1][3]是第7个元素 b[2][0]是第8个元素 b[2][1]是第9个元素 b[2][2]是第10个元素 b[2][3]是第11个元素 int b[3][4]; 3 5 9 7 b 8 10 7 2 1 4 3 6 b[i][j]是第?个元素 i*4+j

  17. int main() { int b[3][4],c[4][3]; int i,j; int *p,*s; p=&b[0][0];s=&c[0][0]; for(i=0; i<3; i++) for(j=0; j<4; j++) scanf("%d",p+i*4+j); for(i=0; i<3; i++) for(j=0; j<4; j++) *(s+j*3+i)=*(p+i*4+j); for(i=0; i<4; i++) {for(j=0; j<3; j++) printf("%d",*(s+i*3+j); printf("\n"); } }

  18. 指向字符串的指针变量 char s[ ]="abcdefgh"; char *p; char *string= "I love china!"; p=s; puts(p); printf("%s\n",string); string是一个字符指针变量 编译时把字符串常量的首地址送给string

  19. 字符指针与字符数组的差别 1.初始化 char str[ ]= "abc"; char *p= "abc"; 区分差别 2.赋值 char *a, str[20]; a= "abc"; str= "abc"; ………………error 3.指针变量的值可以改变 而数组名表示的地址是不能变化的

  20. char s[20]="abcdefgh"; char *p; p=s; gets(p); puts(p); printf("%s\n",p); char a[20],b[20]; char *p1,*p2; p1=a; p2=b; for(; *p1!='\0'; p1++,p2++) { *p2=*p1; } *p2= '\0';

  21. 对一个字符串的操作: 定义存放一个字符串的数组 char s[20]; 定义指针变量: char *ps; ps=s; 输入一个字符串 gets(ps); 输出一个字符串 puts(ps); 比较两个字符串 strcmp(ps,"abc") 字符串复制 strcpy(ps, "china");

  22. 对多个字符串的操作 char strs[6][10]; for(i=0; i<6; i++) gets(strs[i]); char *p; p= &strs[0][0] ; for(i=1; i<6; i++) if(strlen(p)<strlen(&strs[0][0] +i*10)) p=&strs[0][0] +i*10; printf("the longest string is %s\n",p);

  23. 7.2 指针与函数 一、指针与指针变量作形参 int strlength(char *str) { int len=0; while(*str) str++, len++; return len; } int main( ) { char string[20]; int length; gets(string) length=strlength(string); printf("%d",length); return 0; } int strlength(char *str) { int *p=str; while(*str) str++; return str-p; }

  24. p1 p2 p2 p_1a p_2 b a p1 3 p b 8 void swap(int *p1,int *p2) {int p; p=*p1; *p1=*p2; *p2=p; } int main() {int a,b; int *p_1,*p_2; scanf("%d %d",&a,&b); p_1=&a; p_2=&b; if (a<b) swap(p_1,p_2); printf("a=%d,b=%d\n",a,b); } 8 3 3

  25. void swap(int x, int y) {int t; t=x; x=y; y=t; } 比较! void swap(int *p1,int *p2) {int p; p=*p1; *p1=*p2; *p2=p; } void swap(int *p1, int *p2) {int *p; p=p1; p1=p2; p2=p; } void swap(int *p1, int *p2) { int *p; *p = *p1; *p1 = *p2; *p2 = *p; }

  26. 以下程序的运行结果是? sub(int x,int y,int *z) {*z=y-x;} int main( ) {int a,b,c; sub(10,5 &a); sub(7,a,&b); sub(a,b,&c); printf("%d,%d,%d\n",a,b,c); } 练 习

  27. void Insert(int a[], int n,int x) { int *p=NULL; p=a+n-1; while(*p>x&&p>=a) { *(p+1)=*p; p--;} *(p+1)=x; } int main() { int a[10],x; int *p; printf("Enter 9 number:"); for(p=a; p<a+9; p++) scanf("%d",p); printf("find:"); scanf("%d",&x); Insert(a,9,x); printf("After insert"); for(p=a; p<a+10; p++) printf("%3d",*p); }

  28. void copy_string(char to[ ], char from[ ]) {......... } void copy_string(char *to,char *from) {for(; *form!= '\0'; from++, to++) *to=*from; *to= '\0'; } void copy_string(char *to,char *from) {while(*to++=*from++)!= '\0'); }

  29. 从10个数中找出最大值和最小值 int max,min; void max_min_value(int array[ ],int n) {int *p; max=min=*array; for (p=array+1;p<array+n; p++) {if (*p>max) max=*p; else if (*p<min) min=*p; } } int main() {int i,number[10]; printf("enter 10 date:\n"); for (i=0; i<10; i++) scanf("%d",&number[i]); max_min_value(number,10); printf("max=%d,min=%d\n",max,min);}

  30. void max_min_value(int *array,int n,int *p1,int *p2) {int *p; *p1=*p2=*array; for (p=array+1;p<array+n; p++) {if (*p>*p1) *p1=*p; else if (*p<*p2) *p2=*p; } } int main( ) {int i,number[10],max,min; printf("enter 10 date:\n"); for (i=0; i<10; i++) scanf("%d",number+i); max_min_value(number,10,&max,&min); printf("max=%d,min=%d\n",max,min); return 0; }

  31. 参数为数组名、指针作用是一样的 void sort(int x[ ],int n) void sort(int *x, int n) { int i,j,k,t; for (i=0; i<n-1; i++) {k=i; for (j=i+1; j<n; j++) if (x[j]>x[k]) k=j; if (k!=i) {t=x[i]; x[i]=x[k]; x[k]=t;} } } { int i,j,k,t; for (i=0; i<n-1; i++) {k=i; for (j=i+1; j<n; j++) if (*(x+j)>*(x+k)) k=j; if (k!=i) {t=*(x+i); *(x+i)=*(x+k); *(x+k)=t;} } } { int i,j,k,t; for (i=0; i<n-1; i++) {k=i; for (j=i+1; j<n; j++) if (*(x+j)>*(x+k)) k=j; if (k!=i) {t=*(x+i); *(x+i)=*(x+k); *(x+k)=t;} } } { int i,j,k,t; for (i=0; i<n-1; i++) {k=i; for (j=i+1; j<n; j++) if (x[j]>x[k]) k=j; if (k!=i) {t=x[i]; x[i]=x[k]; x[k]=t;} } }

  32. 在一个有序的数组中插入一个元素,插入后仍然有序在一个有序的数组中插入一个元素,插入后仍然有序 0 1 2 3 4 5 6 7 2 9 15 20 26 38 47 72 插入23 2 9 15 20 26 38 47 72 72 72 2 9 15 20 26 38 47 47 47 72 2 9 15 20 26 38 38 38 47 72 2 9 15 20 26 26 23 26 38 47 72

  33. 二、返回地址的函数 返回地址的函数定义: 类型 *函数名(参数表) char*strcat (char*, const char*); char*strcpy (char*, const char*);

  34. int main( ) {int a[10]={7,1,2,99,4,5,6,0,8,3}; int *pmax,t; pmax=max(a,10); printf("Max=%d",*pmax); } int *max(int *a, int n) {int *pt=a, i; for(i=0; i<n; i++) if(*pt<*(a+i)) pt=a+i; return(pt); }

  35. 0 1 2 3 4 5 6 7 8 9 10 11 7.3 二维数组与指针 二维数组元素的地址 int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; 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] 地址 100104108 112 116 120 124 128 132 136 140 144

  36. p p p p p p p p p p int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; int *p; p=&a[0][0]; 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] 元素指针(列指针)

  37. 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] int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; a a[0] a[1] a[2] (1)C语言认为a是由a[0]、a[1]、a[2]组成的一维数组 a是这个数组的名字 (2)a[0]、a[1]、a[2]又分别是一个有4个元素的一维数组 a[0]、a[1]、a[2]分别是这些数组的名字

  38. 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] 0 1 2 3 4 5 6 7 8 9 10 11 int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; a a[0] a[1] a[2] 二维数组有两种指针: a、a+i、&a[i]为指向一维数组的指针,称为行指针 a[i]、&a[i][j]、*(a+i)+j、*(a+i)为指向数组元素的指针,称为元素指针(列指针)。

  39. 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] a a[0] 有如下地址: a a+0 a+1 a+2 &a[0] &a[1] &a[2] a[0] a[1] a[2] *(a+0) *(a+1) *(a+2) &a[0][0] &a[1][0] &a[2][0] 其中a、a[0] 、&a[0]、&a[0][0]的值相同 a[i] 、&a[i]的存储单元均不存在, 只是一种表示地址的方法 a[1] a[2]

  40. 指向一维数组的指针 int main() {static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i,j; p=a+0; printf("input i(0-2),j(0-3)"); scanf("%d,%d",&i,&j); printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j)); return 0; } 注意: (*p)[4]与*p[4]不等价 p+i+j不表示a[i][j]的地址 p+i与*(p+i)不等价

  41. int a[M][N], i,j,(*p)[N]; int (*p)[4]; for (i=0; i<3; i++) {p=a+i; for (j=0; j<4; j++) printf("%4d",*(*p+j)); printf("\n"); } p=a; *(*(p+i)+j)  a[i][j] p=a+i; *(*p+j)  a[i][j] p=*a; p=&a[i][j];

  42. 有一个班,班上有3名同学,各学4门课, 查询哪个同学哪门课的成绩最高? int main() { float score[3][4]={ {65,67,70,60},{80,87,90,81}, {90,99,100,98}}; int maxrow,maxcol; average(score,3,4,&maxrow,&maxcol); printf("student %d course %d is excellent", maxrow, maxcol); }

  43. void average(float (*p)[4],int m, int n, int *pr, int *pc) { int i,j; float max=p[*pr][*pc]; *pr=0; *pc=0; for (i=0; i<m;i++) for(j=0; j<n; j++) if( max<*(*(p+i)+j)) {max=*(*(p+*pr)+*pc); *pr=i; *pc=j; } } 若函数定义为: void average(float *p,int m, int n, int *pr, int *pc) 该如何实现和调用?

  44. 对多个字符串的操作 char strs[6][10]; for(i=0; i<6; i++) gets(strs[i]); char (*t)[10]; t=strs; for(i=1; i<6; i++) if(strlen(*t)>strlen(*(strs+i))) t=strs+i; printf("the shortest string is %s\n",*t);

  45. 输入英文的星期几,在查找星期表后输出其对应的数字 char weekDay[7][10] = {"Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday"}; 表示串"Sunday"的地址: WeekDay[0] *(WeekDay+0)

  46. main() { int i, pos; int findFlag = 0; char x[10]; char weekDay[][10] = {"Sunday","Monday","Tuesday", "Wednesday","Thursday","Friday","Saturday"}; printf("Please enter a string:"); scanf("%s", x); for (i=0; i < 7 && !findFlag; i++) { if (strcmp(x, weekDay[i]) == 0) { pos = i; findFlag = 1; } } if (findFlag) printf("%s is %d\n", x, pos); else printf("Not found!\n"); }

  47. int x,*p; p=&x; s a 1 3 5 7 9 7.4 指针数组和指向指针的指针 指针数组 每一个元素是指针的数组 int a[5],*s[5]; s[i]=a+i; s[i]=&a[i]; p x 指针数组定义方式: 类型 *标识符[常量表达式][………..]

  48. s a 1 3 5 7 9 int a[5],*s[5],i,max; for(i=0; i<5; i++) s[i]=a+i; for(i=0; i<5; i++) scanf("%d",s[i]); max=*s[0]; for(i=1; i<5; i++) if(*s[i]>max) max=*s[i]; a各元素的地址:&a[i] a+i s[i] *(s+i) a各元素的值: a[i] *(a+i) *s[i] **(s+i)

  49. int main() {void sort(char *name[ ], int n); void print(char *name[ ], int n); static char *name[ ]={"Follow me","BASIC", "Great Wall","FORTRAN","Computer Design"}; int n=5; sort(name, n); print(name, n); return 0; }

  50. 300 100 500 400 70

More Related