第10章第3节 §103数组的指针和指向数组的指针变量(重点) 数组中 数组的指针数组的起始地址(第一个元素的的地址) 的指针(数组的元素指针数组元素的地址 指向数组元素的指针 1指向数组元素的指针的定义—与指向变量的指针相同 a[10 float b[10] 注:指针指向的类型应 int "p float * 与数组的类型一致 2.指针变量赋初值 数组元素的地址:&a[2]—元素22的地址 数组名:数组名a—数组的首地址起始地址),即第一个元素a0 的地址 &a[0 可在定义指针变量时赋初值 int al 等效inta0;等效imtl10;等效inta/10l; &a|0 nt p=&a[0 P-a
第10章第3节 §10.3 数组的指针和指向数组的指针变量(重点) 数组的指针——数组的起始地址(第一个元素的的地址) 数组的元素指针——数组元素的地址 数组中 的指针 一. 指向数组元素的指针 1.指向数组元素的指针的定义——与指向变量的指针相同 int a[10]; int *p; float b[10]; float *i; 注:指针指向的类型应 与数组的类型一致 2. 指针变量赋初值 数组元素的地址: &a[2]——元素a[2]的地址 数组名: 数组名 a —— 数组的首地址(起始地址),即第一个元素 a[0] 的地址。 a &a[0] 可在定义指针变量时赋初值 等效 int a[10]; int *p=a; int a[10]; int *p=&a[0]; int a[10]; int *p; p=a; int a[10]; int *p; p=&a[0]; 等效 等效
第10章第3节 二、通过指针引用数组元素 [9] 1.元素的地址及指向元素的指针 设:inta[0; int*p=&ao 注:元素在内存中 1)元素a地址的表示 2是顺序排列的 &all a+1(地址表示) pt1(指针表示) 实际地址: d*1 &a1tp+d1(d基类型所占字节数。如:it.2,0为等。) 故 a+i(地址表示) 实际地址: &ail a +d*i p+i(指针表示) 2)元素a[的值 i偏移量。叫“变址 l→{"a+)(地址表示) (p+i)(指针表示) 推广:I变址运算符(下标运算符)功能:一等数一“x+
二. 通过指针引用数组元素 第10章第3节 1. 元素的地址及指向元素的指针 设: int a[10]; int *p=&a[0] ...... a[0] a[1] a[2] a[3] a[9] p 1)元素a[i]地址的表示 &a[1] a +1 (地址表示) p+1 (指针表示) 故: &a[i] a + i (地址表示) p + i (指针表示) 实际地址: &a[1] a +d*1 p+d*1 (d——基类型所占字节数。如:int 为2,float为4等。) 实际地址: &a[i] a +d*i p+d*i 2)元素a[i]的值 a[i] *(a +i) (地址表示) *(p+i) (指针表示) i——偏移量。叫“变址” 注: 元素在内存中 是顺序排列的! [ ]——变址运算符(下标运算符) 功能: x[i] *(x+i) 等效 推广:
第10章第3节 故:*(p+i)一→pli 称为:→带下标的指针 2.引用数组元素的方法 特点 ①直接引用元素(下标法):a[il 直观,运行速度慢 ②地址法 (a+ 特点 ③指针法: (p+i)或p[i →运行速度快,易出错 例:向数组中各元素输入数据,然后输出所有元素 1.下标法 2.地址法 mainO main (0 i int a 10b, i f int a[ 10], i; for(i=0;i<10;i++ for(i=0;i<10;i++) scanf(“%od”,&a[i); scanf(“%d”,(a+i) printf((“n”); printf(“n”) for(i=0;i<10;i++) for(i=0;i<10;i++) printf(“%d”,ali); printf((“%d”,*(a+i); printf((“n”); printf((“Ⅶn”)
第10章第3节 故: *(p+i) p[i] 称为: 带下标的指针 2. 引用数组元素的方法 ①直接引用元素(下标法): a[i] ②地址法: *(a+i) ③指针法: *(p+i) 或 p[i] 直观,运行速度慢 特点 运行速度快,易出错 特点 例:向数组中各元素输入数据,然后输出所有元素 1. 下标法 main() { int a[10], i; for(i=0; i<10; i++) scanf(“%d”,&a[i]); printf(“\n”); for (i=0; i<10; i++) printf(“% d”, a[i]); printf(“\n”); } 2. 地址法 main() { int a[10], i; for(i=0; i<10; i++) scanf(“%d”, (a+i)); printf(“\n”); for (i=0; i<10; i++) printf(“% d”, *(a+i)); printf(“\n”); }
第10章第3节 3.指针法 2 main 1) mainO fint a 10l, i, *p; f int a[ 10, *p; p-a or(p=a;p<(a+10);p++) for(i=0;i<10;i++) scanf(“%od”,p); scanf(“%d”,p+i); printf((“n”); printf(“Ⅶn”); for(p=a;p<(a+10);p++) for(i=0;i<10;i++) printi(“%d”,*p); printf(“%d”,*(p+i); printf(“n”); printf(“Ⅶn”); 或 3)maino f int a[ 10 i, *p; P- for(i=0;i<10;i计+) scanf“0 od,p++); orIn tf(“n”); 方法较多,要特别注意! P-a for(i=0;i<10;i++) printf((“%d”,*(p++); printf((“n”); 或 p++
第10章第3节 3. 指针法 main() { int a[10], *p ; for(p=a; p<(a+10); p++) scanf(“%d”, p); printf(“\n”); for(p=a; p<(a+10); p++) printf(“% d”, *p)); printf(“\n”); } main() { int a[10], i, *p ; p=a; for(i=0; i<10; i++) scanf(“%d”, p+i); printf(“\n”); for(i=0; i<10; i++) printf(“% d”, *(p+i)); printf(“\n”); } 或 p[i] main() { int a[10], i, *p ; p=a; for(i=0; i<10; i++) scanf(“%d”, p++); printf(“\n”); p=a; for(i=0; i<10; i++) printf(“% d”, *(p++)); printf(“\n”); } *p++ 或 方法较多,要特别注意!! 1) 2) 3)
第10章第3节 注意:有关指针变量的运算设:p=&al p+→*(p+)→先取p即a,然后再p+1→p即p指向ai+1l p-→*(p-)→先取*即a[i,然后再p-1→p即p指向ai- *(++p)一*先p+1→p即p指向ai+,然后再取即ai计1 (-p)一先p-1→p即p指向ai1l,然后再取*p即ali- p+二 a山+ p) a]-- 三,数组名作函数参数 数组名作函数参数,相当于将实参数组的首地址传给形参数组,然后实参 数组和形参数组同占相同的内存单元,故形参数组中各元素值的改变,将 影响到实参数组。 四种方式 1.形参和实参均为数组名 形参和实参均为指针变 量 3.形参用指针变量,实参 4.形参用数组名,实参为 为数组名 指针变量
第10章第3节 注意:有关指针变量的运算 *p++ *p-- *(p++) *(p--) 先取*p 即a[i], 然后再p+1→p 即p指向a[i+1] 先取*p 即a[i], 然后再p-1→p 即p指向a[i-1] 设:p=&a[i] *(++p) *(--p) 先p+1→p 即p指向a[i+1] , 然后再取*p 即a[i+1] 先p-1→p 即p指向a[i-1] , 然后再取*p 即a[i-1] (*p)++ (*p)-- a[i]++ a[i]-- 三 . 数组名作函数参数 数组名作函数参数,相当于将实参数组的首地址传给形参数组,然后实参 数组和形参数组同占相同的内存单元,故形参数组中各元素值的改变,将 影响到实参数组。 四种方式 1. 形参和实参均为数组名 形参和实参均为指针变 量 2. 形参用指针变量,实参 为数组名 3. 形参用数组名,实参为 指针变量 4
第10章第3节 例10-7:对数组中前n个数进行反序排列(即:前n个元素首尾对调) 1.形参和实参均为数组名 2.形参和实参均为指针变量 void inv(intl, int n) void inv(int*p, int n) Inti,j,t; Rint*i,*j, t; for(i=0,j=n-1; i<j; i++, j-) for(i=p, j=p+n-l; i<j; i++, j-) tt=xil; t xXl x=t; maino maint inta10}={1,2,3,4,5,6,7,8,9,10};inta10={1,2,3,4,5,6,7,8,9,10}; Int n, 1; int n, p; printf(“ input n=”) p-a, scanf(“%od”,&n); printf(“ input n=”); nv(a, n scanf(“%d”,&m); for(i=0;i<10;i++) inv(p, n); print(“%d”,a[i); for(p=a; p<a+10; p++) printf((“%d”,*p);
void inv(int *p, int n) {int *i, * j, t; for(i=p, j=p+n-1; i<j; i++, j--) {t=*i; *i=*j; *j=t;} } main() {int a[10]={1,2,3,4,5,6,7,8,9,10}; int n, *p; p=a; printf(“input n=”); scanf(“%d”,&n); inv (p,n); for(p=a; p<a+10; p++) printf(“%d”,*p); } 第10章第3节 例10-7:对数组中前 n 个数进行反序排列(即:前n个元素首尾对调) 1. 形参和实参均为数组名 void inv(int x[], int n) {int i, j, t; for(i=0, j=n-1; i<j; i++, j--) {t=x[i]; x[i]=x[j]; x[j]=t;} } main() {int a[10]={1,2,3,4,5,6,7,8,9,10}; int n, i; printf(“input n=”); scanf(“%d”,&n); inv (a,n); for(i=0; i<10; i++) printf(“%d”,a[i]); } 2. 形参和实参均为指针变量
第10章第3节 3.形参用指针变量,实参 4.形参用数组名,实参为 为数组名 指针变量 void inv(int*p, int n) void inv(intx[l, int n) Rint*1*j,t IntI for(i=p, j=p+n-1; i<j; i++,j--) for(i=0,j=n-1; i<j; i++,j--) it Rt=xi i=xjl; lj=t maint (0 ainO inta10={1,2,3,4,5,6,8,9,10} inta10|={1,2,3,4,56,7,8,9,10}: int n, *p: int n. i: P-a, p input n=”); scanf(( %d,&n); printf("input n scanf(“%d”,&n inv(a, n) inv(p, n); for(i=0;i<10;i++) for(p=a; p<a+10; p++) printi(“%d”,a[); printi(“%od”,p):
第10章第3节 形参用指针变量,实参 为数组名 3. void inv(int *p, int n) {int *i, * j, t; for(i=p, j=p+n-1; i<j; i++, j--) {t=*i; *i=*j; *j=t;} } main() {int a[10]={1,2,3,4,5,6,7,8,9,10}; int n, i; printf(“input n=”); scanf(“%d”,&n); inv (a,n); for(i=0; i<10; i++) printf(“%d”,a[i]); } 形参用数组名,实参为 指针变量 4. void inv(int x[], int n) {int i, j, t; for(i=0, j=n-1; i<j; i++, j--) {t=x[i]; x[i]=x[j]; x[j]=t;} } main() {int a[10]={1,2,3,4,5,6,7,8,9,10}; int n, *p; p=a; printf(“input n=”); scanf(“%d”,&n); inv (p,n); for(p=a; p<a+10; p++) printf(“%d”,*p); }
第10章第3节 习题讲解:P25810.3 void inpt(int * Rint J; maino for(j=0;jmax)max=*(i+k); y=k; 9 最小值的位置 if ((i+ k <min) min=*(i+k);x=k; y最大值的位置 (i+0);*(i+0)=*(i+x); t*(i+9);*(i+9)=*(i+y);*(i+y)=t; void outp〔intb|) fint for(〔i=0;i<10;i++) printi(“%4d”,b[i);
第10章第3节 习题讲解:P258 10.3 void inpt(int *i) {int j; for(j=0; jmax) {max=*(i+k); y=k;} if (*(i+k)<min) {min=*(i+k); x=k;} } t=*(i+0); *(i+0)=*(i+x); *(i+x)=t; t=*(i+9); *(i+9)=*(i+y); *(i+y)=t; } void outp (int b[]) {int i; for (i=0; i<10; i++) printf(“%4d”,b[i]); } main() {int a[10], *p; p=a; inpt(p); process(p); outp(p);} x,y用于记位置 x—最小值的位置 y—最大值的位置
第10章第3节 四.指向多维数组的指针和指针变量(以二维数组为例) 1.多维数组的地址两种地址,∫行地址 列地址即元素地址 设有二维数组:inta34}={{1,2,34},{5,6,7,8},(9,10,112} C中认为:可将二维数组分成两个一维数组。 ajol a[01[01 a(01[11 a[01[21 a[01[31 分成四个元 inta34-分成三个元了a素 素 a(1|[01 a(11[11 a[11[21 a(1 131 a 2 a2|01a212|2]|a23 a0的地址→a+0 a|0的地址→a1+0→*(a+0)+0→*a a|1的地址→a+1行地址2a0的地址→a0+1→*a+1 列地址 a|0的地址→a0+2→*(a+1)+2 (即元素 a2]的地址→a+2 地址) a2]的地址→a2]+3→*a+2)+3 a[ij的 &alli a[ij的 a iljl 地址 ai+ 值 (ai+j) (a+i)+ *(*(a+i)+j)
四. 指向多维数组的指针和指针变量(以二维数组为例) 第10章第3节 1. 多维数组的地址 行地址 列地址(即元素地址) 两种地址 设有二维数组: int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 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] C中认为:可将二维数组分成两个一维数组。 int a[3][4] a[0] a[1] a[2] 分成三个元 素 分成四个元 素 a[0]的地址→a+0 a[1]的地址→a+1 a[2]的地址→a+2 行地址 a[0][0]的地址→a[0]+0 →*(a+0)+0→*a a[0][1]的地址→a[0]+1 →*a+1 a[0][2]的地址→a[0]+2→*(a+1)+2 ...... a[2][3]的地址→a[2]+3 →*(a+2)+3 列地址 (即元素 地址) a[i][j]的 地址 &a[i][j] a[i]+j *(a+i)+j a[i][j]的 值 a[i][j] *(a[i]+j) *(*(a+i)+j)
第10章第3节 注意:地址值相同,而意义不同的情况 地址→404406408410 0l a[oJ[1] a[02]a[0JB31 如有inta[3]4] 412414416 418 a 420422424 426 行地址: a[2oa2a22]a213 404 a+1 412 地址值相同,但意义不同 a+2 420 列地址: a即*(a+0)+0 a|0J+0→&a001 404 (a+1)即*(a+1)+0→a110→&a[1] 412 (a+2)即*(a+2)+0a2+0→&a[2|0 420
注意:地址值相同,而意义不同的情况 第10章第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] 404 406 408 410 412 414 416 418 420 422 424 426 地址 如有: int a[3][4] 行地址: a 404 a+1 412 a+2 420 列地址: *a 即*(a+0)+0 a[0]+0 &a[0][0] 404 *(a+1) 即*(a+1)+0 a[1]+0 &a[1][0] 412 *(a+2) 即*(a+2)+0 a[2]+0 &a[2][0] 420 地址值相同, 但意义不同