指针作为函数参数 : 原因 : 1 需要修改一个或多个值,( 用 return 语句不能解决问题 ) 2 执行效率的角度
使用方法 : 在函数原型以及函数首部中需要声明能够接受指针值的形参, 具体的写法为 : 数据类型 * 形参名 如果有多个指针型形参, 则用逗号分隔, 例如 : void swap(int *p1, int *p2) 它说明了形参 p1 p2 是指向整型变量的指针
在函数调用时, 只需要用指针变量名作为实参即可 例如有变量声明 : int * n1, *n2;. swap(n1, n2);/* 函数调用 */
在 C 语言中, 实参与形参之间的结合是单向的 值传递 方式 指针变量作函数参数也必须遵循这一规则 调用函数不能改变实参指针变量的值, 但可以改变实参变量所指向的变量的值
#include <stdio.h> int cubebyvalue(int); main() int number=5; printf("the original value of number is %d\n",number); number=cubebyvalue(number); printf("the new value of number is %d\n",number); return 0; int cubebyvalue(int n) int k= n*n*n; n=10; return k;
Main 调用 cubebyvalue 之前 Main() Number=5 Int cubebyvalue(int n) int number=5; return n*n*n; number=cubebyvalue(number); N 无确定值 Main 调用 cubebyvalue 之后 Main() Number=5 Int cubebyvalue(int n) int number=5; return n*n*n; number=cubebyvalue(number); N=5
cubebyvalue 计算了参数 n 的立方之后 Main() Number=5 Int cubebyvalue(int n) int number=5; return n*n*n;//125 number=cubebyvalue(number); N=5 从 cubebyvalue 返回到 main 之后 Main() Number=5 Int cubebyvalue(int n) int number=5; return n*n*n; number=cubebyvalue(number);125 n 无确定值
Main 完成给 number 赋值之后 Main() Number=125 Int cubebyvalue(int n) int number=5; return n*n*n; number=cubebyvalue(number); n 无确定值
#include <stdio.h> void cubebyreference(int *); main() int number=5; printf("the original value of number is %d\n",number); cubebyreference(&number); printf("the new value of number is %d\n",number); return 0; void cubebyreference(int * n) Int k; *n= *n * *n * *n; n=&k;
Main 调用 cubebyreference 之前 Main() Number=5 Int cubebyreference(int * n) int number=5; *n= *n * *n * *n; cubebyreference(&number); N 无确定值 Main 调用 cubebyreference 之后以及在计算 *n 的立方之前 Main() Number=5 Int cubebyreference(int * n) int number=5; *n= *n * *n * *n; cubebyreference(&number); N
Main 调用 cubebyreference 之后以及在计算 *n 的立方之后 Main() Number=125 Int cubebyreference(int * n) int number=5; *n= *n * *n * *n; cubebyreference(&number); N Main 调用 cubebyvalue 之后以及从 cubebyreference 返回 Main() Number=125 Int cubebyvalue(int * n) int number=5; *n= *n * *n * *n; cubebyreference(&number); N 无确定值
#include <stdio.h> void swap(int *,int *); main() int a,b; int *aptr, *bptr; printf("please input two integers:\n"); scanf("%d%d",&a,&b); aptr=&a; bptr=&b; if (a<b) swap(aptr,bptr); printf("\n%d,%d\n",*aptr,*bptr); return 0; void swap(int * n1,int *n2) int p; p=*n1; *n1=*n2; *n2=p;
void swap(int * n1,int *n2) int *p; *p=*n1; *n1=*n2; *n2=*p; void swap(int *n1,int *n2) int *p; p=n1; n1=n2; n2=p;
#include <stdio.h> void swap(int,int); main() int a,b; int *aptr, *bptr; printf("please input two integers:\n"); scanf("%d%d",&a,&b); aptr=&a; bptr=&b; if (a<b) swap(a,b); printf("\n%d,%d\n",*aptr,*bptr); return 0; void swap(int n1,int n2) int p; p=n1; n1=n2; n2=p;
a a[0] 多维数组的地址 a[0][0] a[0][1] a[0][2] a[0][3] a a[0][0] a[0][1] a[0] a[1] a[2] 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[i],a+i 二维数组元素的地址 : &a[0][0],a[0],a[1],a[2] *(a+i)+j &a[i][j],a[i]+j 二维数组元素值 :a[i][j],*(a[i]+j) *(*(a+i)+j) 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[1] a[2]
a[0]-------a00,a01,a02,a03 a[1]-------a10,a11,a12,a13 a[2]-------a20,a21,a22,a23 a[0]+0, a[0] +1, a[0]+2, a[0] +3==&a[0][3] a[1]+0, a[1] +1, a[1]+2, a[1] +3==&a[1][3] a[2]+0, a[2] +1, a[2]+2, a[2] +3==&a[2][3] *(a+2)+0, *(a+2) +1, *(a+2) +2, *(a+2) +3==&a[2][3] a[0],a[1],a[2] *a *(a+1) *(a+2)
int a[3]; a[0],a[1],a[2] a a+1 a+2 *a *(a+1) *(a+2) int *p, (*p1)[4]; P+1; p1+1; p=a;
1 含义 : 一个指针变量可以指向二维数组的元素, 而二维数组的元素也可以表示成指针的形式. 2 分析以下的程序 int aa[3][3]=2,4,6; main() int i,*p=&aa[0][0]; for(i=0;i<2;i++) if(i==0) aa[i][i]=*p+1; else ++p; printf( %d,,*p); 运行结果为 :3,0 指向二维数组元素的指针
分析以下的程序 main() int a[3][4]= 1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=*(a+0),a[0],&a[0][0];p<a[0]+12;p++) if((p-a[0])%4==0) printf(( \n ); printf( %4d,*p);
1 含义: 指针所指的是包含 m 个元素的一维数组 p,a 也即指向二维数组行的指针 2 表示方法 : 数据类型 (* 指针变量 )[ 数组元素个数 ] 3 引用方法 : 分析以下的程序 main() static int a[3][4]= 1,3,4,7,9,,11,13,15,17,19,21,23; int (*p)[4]=a,i,j,k=0; for(i=0;i<3;i++) for(j=0;j<4;j++) k=k+*(*(p+i)+j); printf( %d\n,k); 指向二维数组行的指针 p+1 p+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] a[0] a[1] a[2]
对 *(*(p+i)+j) 的理解 : p+i 相当于 a 数组的第 i 行的首地址 ; *(p+i) 相当于 a 数组的第 i 行第 0 个元素的地址 ; 等价于 a[i]; *(p+i)+j 相当于 a 数组第 i 行第 j 列的元素的地址 ; 等价于 &a[i][j] 等价于 p[i]+j 等价于 a[i]+j *(*(p+i)+j) 等价于 a[i][j]
例 exp7_18: 分析以下的程序 main() int a[2][3],(*p)[3]; int k=0,j; p=a; for(;k<2;k++) for(j=0;j<3;j++) *(p[k]+j)=(k+1)*(j+1); printf( %d\n,*(p[1]+2)); 运行结果为 :6
小结 : 表示形式 a a[0],*(a+0),*a a+1 a[1],*(a+1) a[1]+2,*(a+1)+2 &a[1][2] *(a[1]+2), *(*(a+1)+2), a[1][2] 含义二维数组名, 数组首地址第 0 行第 0 列元素的地址第 1 行首地址第 1 行第 0 列元素的地址第 1 行第 2 列元素的地址第 1 行第 2 列元素的值
1. 二维数组名作数组的参数 : 分析以下的程序 int fun(int *p) int i,j; for(i=0;i<3;i++) for(j=0;j<4;j++) return 0; *(p++)=i+j; main() int a[3][4]=1,2; 二维数组的指针作函数的参数 fun(a[0]); printf( %d\n,a[2][3]);
2. 指向二维数组的行指针作函数的参数分析以下的程序 #include <stdio.h> void fun(int (*)[3], int); int main() int a[3][3],(*p)[3]; p=a+1; fun(a,3); printf("%d\n",*(p[1]+2)); return 0; void fun(int (*p)[3],int size) int i,j; for(i=0; i<size; i++) for(j=0; j<3; j++) *(*(p+i)+j)=(i+1)*(j+1);
指向多维数组的指针 : 难点在于地址计算 ( 以二维数组为例 ) a[3][4]=2,3,4,5,4,5,6,7,1,4,5,6; 1 a 为首地址, 是常量, 对 a 进行算术运算, 以一维数组在内存中所占的内存单元为偏移量 : 假设 a 为 2000,2 字节字长 ; 则 a+1 为 2008 2 对于二维数组 a 而言, 是由 3 个一维数组组成的 : a[0],a[1],a[2] a[0],a[1],a[2] 是相应一维数组的首地址,*(a+0)= =a[0], *(a+1)= =a[1],*(a+2)= =a[2] 3 对于 a[0],a[1],a[2] 的算术运算以一整型元素为偏移量 : a[0]+1 为 2002
3 (a+0)+2 与 *(a+0)+2 不同, 前者使指针定位于第三行, 而后者使指针定位于第一行第三个元素 4 a+i=a[i]=*(a+i)=&a[i]=&a[i][0] 尽管在数值上相等, 但具有不同的含义 ; a+i=&a[i] 相同, 他们在行移动 a[i]=*(a+i)=&a[i][0] 相等, 它们已定位至列 ; 5 对于数组的描述而言, 一维数组只需一下标, 而二维数组则需要两个下标, 这对于确定指针定位非常有意义 : 6 当 a 有一个整型量在进行算术运算时, 则以一维数组为偏移量 ; 如果有两个整型量在进行算术运算, 则以一个基类型元素为偏移量, 区别它们只需加上一整型值 例如 :a[i] 与 a+i a[i]+2,a+i+2, 前者已经有两个下标, 而后者仍然是一个下标
指向数组元素的指针变量 地址的移动以基类型元素为偏移量
#include <stdio.h> #include <time.h> #include <stdlib.h> main() int a[3][4]; int *p; srand(time(null)); for (p=*a;p<*a+12;p++) *p=rand() % 100; printf("data items in original order\n"); for (p=*a;p<*a+12;p++) printf("%5d",*p); for (p=&a[0][0];p<a[0]+12;p++) if((p-a[0])%4==0) putchar('\n'); printf("%4d",*p); putchar('\n'); return 0;
指向一维数组的指针变量 地址的移动以一维数组为偏移量
#include <stdio.h> #include <time.h> #include <stdlib.h> main() int a[3][4]; int (*p)[4], i, j; p=a; srand(time(null)); for (i=0;i<3;i++) for (j=0;j<4;j++) *(*(p+i)+j)=rand() % 100; printf("data items in original order\n"); for (i=0;i<3;i++) for (j=0;j<4;j++) printf("%5d",*(*(p+i)+j)); putchar('\n'); putchar('\n'); return 0;