1、Chapter 8 善于利用指针,Contents,8.6 返回指针值的函数,8.7 指针数组和多重指针,8.8 动态分配内存和指向它的变量,8.5 指向函数的指针,通过指针引用二维数组,a34 = 1, 2, 3, 4 , 5, 6, 7, 8 , 9,10, 11,12 ;,由三个1维数组组成,分别是a0 a1 a2P246图8.19,图8.20和表8.2比较好的复习资料。,通过指针引用二维数组,1 65514,2 65516,3 65518,4 65520,5 65522,6 65524,7 65526,8 65528,a,a+1,a+2,a0,a0+1,a0+2,a0+3,a是行指针,
2、a0,a1,a2是列指针,9 65530,10 65532,11 65534,12 65536,通过指针引用二维数组,1 65514,2 65516,3 65518,4 65520,5 65522,6 65524,7 65526,8 65528,a,a+1,a+2,a0,a0+1,a0+2,a0+3,a是行指针,a0,a1,a2是列指针,9 65530,10 65532,11 65534,12 65536,* &,行指针 列指针,通过指针引用二维数组,1 65514,2 65516,3 65518,4 65520,5 65522,6 65524,7 65526,8 65528,a,a+1,a+
3、2,a0,a0+1,a0+2,a0+3,a12,9 65530,10 65532,11 65534,12 65536,通过指针引用二维数组,1 65514,2 65516,3 65518,4 65520,5 65522,6 65524,7 65526,8 65528,a,a+1,a+2,a0,a0+1,a0+2,a0+3,a12 a + 1,9 65530,10 65532,11 65534,12 65536,通过指针引用二维数组,5 65522,6 65524,7 65526,8 65528,a+1,a+2,a1,a12 a + 1 *(a+1),9 65530,10 65532,11 65
4、534,12 65536,通过指针引用二维数组,5 65522,6 65524,7 65526,8 65528,a+1,a+2,a1+2,a12 a + 1 *(a+1) *(a+1)+2,9 65530,10 65532,11 65534,12 65536,通过指针引用二维数组,5 65522,6 65524,7 65526,8 65528,a+1,a+2,a1+2,a12 a + 1 *(a+1) *(a+1)+2 *(*(a+1)+2),9 65530,10 65532,11 65534,12 65536,通过指针引用二维数组,5 65522,6 65524,100 65526,8 65
5、528,a+1,a+2,a1+2,a12 a + 1 *(a+1) *(a+1)+2 *(*(a+1)+2)=100,9 65530,10 65532,11 65534,12 65536,例8.11 输出二维数组的有关数据,void main() int a34 = 1,2,3,4,5,6,7,8,9,10,11,12;printf(“%u ,%un”,a,*a); printf(“%u ,%un”,a0,*(a+0);printf(“%u ,%un”, ,1 65514,2 65516,3 65518,4 65520,5 65522,6 65524,7 65526,8 65528,a,a+1
6、,a+2,a0,a0+1,a0+2,a0+3,9 65530,10 65532,11 65534,12 65536,指向二维数组元素的指针,实质,整型指针。,例8.12 用指向元素的指针变量输出二维数组各元素的值。,p = a0; 或 p = ,p a0+12; p+ 或 p p+,指向由m个元素组成的1维数组的指针,引例8.13 int a34 = ; int (*p)4; / 表示定义一个数组,4表示数组中有4个元素,int表示数组为整型数组。*表示p是一个指针变量。 p = a; / a可以赋给p,因为=两边类型一致并且可以通过p间接访问a。,指向由m个元素组成的1维数组的指针,为什么一
7、定要为数组定义一个指针变量, 然后进行p=a;再进行p+的操作?,因为数组名a是一个常量,表示数组的首地址, 不能进行a+的操作。,指向由m个元素组成的1维数组的指针,为什么一定要为数组定义一个指针变量, 然后进行p=a;再进行p+的操作?,因为数组名a是一个常量,表示数组的首地址, 不能进行a+的操作。,不能忽略的一个程序: int a4=1,3,5,7; int (*p)4; p=,二维数组做实参,行指针变量做形参,例8.14,float score34 = ; search(score,3);,void search(float (*p)4,n) / 用n接收要处理的行数 for(i=0
8、;in;i+)for(j=0;j4;j+)pij = 100; / *(*(p+i)+j)=100,二维数组做实参,行指针变量做形参,例8.14,float score34 = ; search(score,3);,void search(float (*p)4,n) / 用n接收要处理的行数 for(i=0;in;i+)for(j=0;j4;j+)pij = 100; / *(*(p+i)+j)=100,p= score,“=”两边类型一致,如果定义指向函数的指针变量。 模仿指向m个元素的一维数组指针变量int (*p)4,8.5指向函数的指针,编译时,编译系统为函数代码分配一段存储空间,
9、这段存储空间的起始地址(入口地址),称作 这个函数的指针。,int max(int , int)int (*p)(int , int),如果定义指向函数的指针变量。 模仿指向m个元素的一维数组指针变量int (*p)4,8.5指向函数的指针,编译时,编译系统为函数代码分配一段存储空间, 这段存储空间的其实地址(入口地址),称作 这个函数的指针。,int max(int , int)int (*p)(int , int),此时,可以将max赋给p, 因为类型一致。 p= max,8.5指向函数的指针,int max(int , int)int (*p)(int , int),此时,可以将max赋
10、给p, 因为类型一致。 p= max,例8.22 用函数求整数a和b的大者。,int a,b,c; int max(int,int); int (*p)(int ,int); p = max; /获得max函数入口 scnaf(“%d%d%d”, /去执行max函数,int max(int x, int y) ,例8.22 输入两个整数,然后让用户选择 1或2,选1时,调用max,选2时,调用min,int a,b,c,n;int max(int,int);int min(int,int); int (*p)(int ,int); scanf(“%d%d%d”,int max(int x, i
11、nt y) ,int min(int x, int y) ,用函数指针作函数参数,void fun(int (*x1)(int), int (*x2)(int) int a,b,i=3,j=5;a = (*x1)(i); /间接执行函数f1b = (*x2)(j); /间接执行函数f2 int f1(int n) int f2(int n) ,fun(f1,f2);,用函数指针作函数参数,fun(f1,f2);,x1 = f1,x2=f2,void fun(int (*x1)(int), int (*x2)(int) int a,b,i=3,j=5;a = (*x1)(i); /间接执行函数f
12、1b = (*x2)(j); /间接执行函数f2 int f1(int n) int f2(int n) ,例8.24 输入1,调用max;输入2,调用min输入3,调用add,int fun(int x,int y, int (*p)(int) int result;result = (*p)(x,y);return result; ,if(n=1) fun(a,b,max);,if(n=2) fun(a,b,min);,if(n=3) fun(a,b,add);,int max(int x, int y) ,int min(int x, int y) ,int add(int x, int
13、 y) ,8.6 指针作函数的返回值,一般形式: int * fun(),引例,自定义函数fun,找出二维数组a中 最小值,并将该最小值的地址作为结果返回给主调函数。,int* fun(int arr4) int *q= ,int a34=5,8,6,2,7,4,9,6,5,4,1,3; int *pmax; pmax=fun(a); printf(“%d ”,*pmax);,8.6 指针作函数的返回值,阅读例8-25,26中,观察函数search的返回值类型, 观察return的结果,并注意主调函数中怎样接收结果。,8.8 动态分配内存,需要时申请,不需要时释放。 目的:提高内存的利用率。,
14、malloc(100) /开辟100字节的空间,返回值为空间首地址。,函数原型: void *malloc(unsigned int) / #include “alloc.h”,应用中,将返回值强制转换成需要的类型。 如:int *pp = (int *)malloc(100); 类似于int p50,区别是静态和动态,内存利用率不同。,8.8 动态分配内存,需要时申请,不需要时释放。 目的:提高内存的利用率。,malloc(100) /开辟10字节的空间,返回值为空间首地址。,函数原型: void *malloc(unsigned int) / #include “alloc.h”,应用中,
15、将返回值强制转换成需要的类型。 如:int *pp = (int *)malloc(50*sizeof(int); 类似于int p50,区别是静态和动态,内存利用率不同。,8.8 动态分配内存,需要时申请,不需要时释放。 目的:提高内存的利用率。,malloc(100) /开辟10字节的空间,返回值为空间首地址。,int *p; p=(int *)malloc(10*sizeof(int); for(i=0;i10;i+) scanf(“%d”,p+i);,8.8 动态分配内存,需要时申请,不需要时释放。 目的:提高内存的利用率。,(2)calloc(10,2) /通常用来保存一个1维数组,int *p; p=(int*)calloc(10,2); for(i=0;i10;i+) scanf(“%d”,p+i);,calloc通常用于动态数组的使用, 而malloc通常用于开辟链表或者树和图中的一个节点。,8.8 动态分配内存,需要时申请,不需要时释放。 目的:提高内存的利用率。,(3)free(p); /不需要时,释放空间,(4)realloc(p,50); / 对malloc或calloc重新分配内存可扩大,可缩小。起始地址与malloc和calloc不一定相同。,Thank You !,BHJSJ,