失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 指针数组 数组指针 函数指针 指针函数 函数指针数组

指针数组 数组指针 函数指针 指针函数 函数指针数组

时间:2023-10-16 18:31:01

相关推荐

指针数组 数组指针 函数指针 指针函数 函数指针数组

曾经的我是一个摆男,一言不合就开摆,直到我遇见了电子厂。。。。发生了一些不可描述的事,让我看清了社会的真相。。。

进入正题!

分析时的两个步骤:是什么?怎么用?

是什么?

1、指针数组:本质是数组,数组中存储的每个元素是指针

怎么用?

以遍历数值指针数组为例,int* arr[4] = { &num1,&num2,&num3,&num4 };就是数值指针数组

void t1(){int num1 = 10;int num2 = 20;int num3 = 30;int num4 = 40;int* arr[4] = { &num1,&num2,&num3,&num4 };int n = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0;i < n;i++){printf("%3d", *arr[i]);}printf("\n");}int main(int argc,char *argv[]){t1();return 0;}

输出的时候为:*arr[i] 因为*()等价于[],所以也可以写成:**(arr + i)

这里讲一下:&arr[i] == (arr+ i) 然后*arr[i] == **(arr + i)

不要搞混了

以遍历字符串指针数组为例,int* arr[4] = { "tienan","nuoshou","wanhao","jianmo" };就是字符串指针数组

#include <stdio.h>void t2(){char *arr[4] = {"tienan","nuoshou","wanhao","jianmo",};char* brr[4] = { "铁男","诺手","腕豪","剑魔" };int n = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0;i < n;i++){printf("%10s", arr[i]);//printf("%10s",*(arr + i));//选一种输出即可}printf("\n");for (i = 0;i < n;i++){printf("%10s", brr[i]);}printf("\n");//想把tienan的e打印出来怎么办?/***************难点******************///第一种,数组的方式printf("%10c\n",*(arr[0] + 2));//解析:arr[0]是“tienan”这个首元素的首字母地址,直接指向t,+2之后指向e,把e的打出来取*//第二种,指针的方式printf("%10c\n",*(*arr + 2));//解析:arr是数组首元素地址,指向第一个元素,也就是”tienan“,*arr是取到第一个元素的第一个字母内容,也就是t,也就是*arr 和arr[0]等价,再+2之后指向e,把e打印出来再取*//思考:下面这个输出什么?printf("%10c\n",**arr + 2);printf("\n");}int main(int argc,char *argv[]){t2();return 0;}​

输出的时候为:arr[i]

因为字符串输出的时候是给首地址,所以输出少一个 *

为什么输出的是v? 因为*arr是取到 t 嘛,再取 * 是把它打印出来,**arr + 2就是打印 t 后面ASCII码值 +2 的字母。

arr是数组的首元素地址,&arr是数组的首地址,它们两个表示的地址相同,但是概念不同。对首地址取 * ,得到数组首元素地址。也就是说 *&arr 和 arr 等价。所以,对首地址 +1 ,偏移一个数组;对首元素 +1 ,偏移一个元素,对 *(首元素)+1 ,偏移一个字母。BUT!!对于数组指针来说,数组名只代表第0行的行地址(有些人说是第一行,无所谓,就是最开始的那一行),接下来要讲的是数组指针

继续!

2、数组指针:本质是指针,指向一个数组,指针的值是数组的地址

以数组指针遍历数值数组元素为例

#include <stdio.h>void t3(){int arr[2][3] = {1,2,3,4,5,6};int (*p)[3] = arr;//写成int (*p)[3] = &arr;也行,但是要报警告//写成int (*p)[3] = NULL;p = arr也行,这个不报警告//下面输出0行1列元素,也就是2,两种方式可任选一种printf("arr[0][1] = %d\n",*(*(p + 0) + 1));//*(*(p+0) + 1) == *(arr[0] + 1) == arr[0][1]//printf("arr[0][1] = %d\n",arr[0][1]);//这种是数组的方式//下面看+1后偏移多少printf("arr[0][0] = %d\n",**p);printf("arr[a][b] = %d\n",*(*(p+0)+0) + 1);//(**p + 1)printf("arr[c][d] = %d\n",**(p + 1));printf("arr[e][f] = %d\n",*(*p + 1));//下面看指向的地址printf("%p\n",**p);printf("%p\n",**p + 1);printf("%p\n",**(p + 1));printf("%p\n",*(*p + 1));//下面是数组指针遍历数组元素int i,j;for(i = 0;i < 2;i++){for(j = 0;j < 3;j++){printf("%3d",*(*(p + i) + j));//printf("%3d",arr[i][j]);}}printf("\n");//也可以用这种方式连续输出for(i = 0;i < 6;i++){printf("%3d",*(*p + i));}printf("\n");}int main(int argc, char *argv[]){ t3();return 0;}

继续!

3、函数指针:本质是指针,指向一个函数,指针的值是函数的地址

以下是函数指针普通用法

#include <stdio.h>int fun_jia(int a,int b){return a+b;}void t4(){int (*p)(int,int) = fun_jia;//写成int (*p)(int a,int b)也行//写成int (*p)(int x,int y) = &fun_jia;也行//写成int (*p)(int x,int y) = fun_jia;也行//写成int (*p)(int,int) = NULL;p = fun_jia;也行printf("%d\n",fun_jia(1,2));//输出的fun_jia(1,2)不能取地址!}int main(int argc, char *argv[]){ t4();return 0;}

以下是函数指针进阶用法

#include <stdio.h>int fun_jia(int a,int b){int c = a + b;return c;//或者直接写成return a + b;}int fun_jian(int a,int b){return a - b;}//新定义一个函数,用函数指针调用上面定义的函数int func(int a,int b,int(*p)(int,int)){return p(a,b);}void t4(){printf("%2d\n",func(1,2,fun_jia));printf("%2d\n",func(1,2,fun_jian));}int main(int argc, char *argv[]){t4();return 0;}

注意:上面我没写函数申明,但依然没有问题。是因为主函数在最下面。

继续!

4、指针函数:本质是函数,函数的返回值是指针。

#include <stdio.h>#include <stdlib.h>//malloc要用#include <string.h>//memset要用int *fun_jia(int a,int b);int *fun_jia(int a,int b){ int *p = (int *)malloc(sizeof(int));//在堆区申请空间,但不自动清0if(p == NULL)//预防空间申请失败,堆区满了就可能失败{return 0;//如果没有这个判断语句,如果p == NULL,就会报错} memset(p,0,sizeof(int));//手动清0*p = a + b;return p;free(p);//释放堆区空间,不想用了就释放} void t5(){int *p = fun_jia(1,2);//int *p = NULL;//p = fun_jia(1,2);//写成int *p = fun_jia(1,2);也行printf("%d\n",*p);}int main(int argc, char *argv[]){t5();return 0;}

继续!

5、函数指针数组:本质是数组,每个元素是函数地址,指针指向一个函数,指针的值是函数的地址,相当于函数指针int(*p)(int,int) = fun_jia;组合成数组的形式!而函数指针数组指针(指向函数指针数组的指针),它的每个元素是函数指针。别搞混了。。。

#include <stdio.h>int fun_jia(int a,int b);int fun_jian(int a,int b);int fun_jia(int a,int b){return a+b;}int fun_jian(int a,int b){return a-b;}void t6(){int (*p[2])(int,int) = {fun_jia,fun_jian};//定义函数指针数组//数组肯定要遍历嘛int i;for(i = 0;i < 2;i++){printf("%3d",p[i](1,2));}printf("\n");}int main(int argc, char *argv[]){t6();return 0;}

这里输入写成:int (*p[2])(int,int) = {&fun_jia,&fun_jian}; 也行。

这里输出写成:printf("%3d",(*(p + i))(1,2)); 也行。

难吗,不难!只写了4个小时。睡觉!

如果觉得《指针数组 数组指针 函数指针 指针函数 函数指针数组》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。