680 likes | 846 Views
第七章 指针. 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
E N D
第七章 指针 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 地址空间的大小(有哪些房间号)和变量的具体地址分别由硬件系统和编译系统决定
2000 2000 10 i_point i 指针变量 专门用于存放地址的变量称为指针变量 int i; i=10; 假设&i为2000; 定义: int *i_point; i_point=&i;
2000 2000 10 i_point i int i; i=10; 假设&i为2000; 定义: int *i_point; i_point=&i; 用*i_point表示所指向的存储单元的值 即i的值,通过i_point可以访问i,称为间接访问
4个字节,可以放int、 float类型数据 8个字节, 放double类型数据 1个字节, 放char类型数据 首地址只有一个,存储空间大小和存储方式? 定义指针变量也需要指出指向数据的类型 指针变量定义: 类型 *标识符
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;
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; } 涵义不同
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;
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
a 数组与指针 数组的首地址-----数组的指针 数组元素的地址----数组元素的指针 int a[10]; int *p,*s,i; p=&a[0]; s=&a[5]; &a[0]与a等价 p s
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
若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]
引用数组元素的方法 (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不能少
下标法 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]); 指针法
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
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"); } }
指向字符串的指针变量 char s[ ]="abcdefgh"; char *p; char *string= "I love china!"; p=s; puts(p); printf("%s\n",string); string是一个字符指针变量 编译时把字符串常量的首地址送给string
字符指针与字符数组的差别 1.初始化 char str[ ]= "abc"; char *p= "abc"; 区分差别 2.赋值 char *a, str[20]; a= "abc"; str= "abc"; ………………error 3.指针变量的值可以改变 而数组名表示的地址是不能变化的
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';
对一个字符串的操作: 定义存放一个字符串的数组 char s[20]; 定义指针变量: char *ps; ps=s; 输入一个字符串 gets(ps); 输出一个字符串 puts(ps); 比较两个字符串 strcmp(ps,"abc") 字符串复制 strcpy(ps, "china");
对多个字符串的操作 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);
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; }
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
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; }
以下程序的运行结果是? 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); } 练 习
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); }
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'); }
从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);}
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; }
参数为数组名、指针作用是一样的 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;} } }
在一个有序的数组中插入一个元素,插入后仍然有序在一个有序的数组中插入一个元素,插入后仍然有序 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
二、返回地址的函数 返回地址的函数定义: 类型 *函数名(参数表) char*strcat (char*, const char*); char*strcpy (char*, const char*);
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); }
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
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] 元素指针(列指针)
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]分别是这些数组的名字
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)为指向数组元素的指针,称为元素指针(列指针)。
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]
指向一维数组的指针 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)不等价
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];
有一个班,班上有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); }
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) 该如何实现和调用?
对多个字符串的操作 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);
输入英文的星期几,在查找星期表后输出其对应的数字 char weekDay[7][10] = {"Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday"}; 表示串"Sunday"的地址: WeekDay[0] *(WeekDay+0)
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"); }
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 指针数组定义方式: 类型 *标识符[常量表达式][………..]
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)
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; }
300 100 500 400 70