C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】


指针的进阶(3)-总结数组和指针

  • 前言
  • 7、指向函数指针数组的指针
    • 7.1 用语法来解析—前置定语
    • 7.2 定义
    • 7.3 指向函数指针数组的指针的应用
  • 8、总结数组和指针
    • 8.1 数组小结
    • 8.2 指针小结
    • 8.3 数组指针套娃小结
  • 总结

前言 本文接着上文,继续学习指针进阶的知识点:指向函数指针数组的指针。
这基本上是最后一个知识点了。学完就对前面所学的数组和指针进行复习,知识点要常温常新:
  • 指向函数指针数组的指针
  • 总结数组和指针
7、指向函数指针数组的指针 7.1 用语法来解析—前置定语 乍得一看这个标题,这就是数组和指针的相互套娃呀,都惊呆了。
我们知道中文分析长难句的时候有语法,英语长难句也用语法分析,将长难句抽丝剥茧,化为简单句。
中文是一种语言,英语也是语言,C也是语言,下面用语法从字面意思分析指向函数指针数组的指针:
  1. 指针是一个名词,前面一坨(指向…的)是前置定语,用来修饰指针的。因此可以干掉定语,整个就剩指针了。
  2. 指向函数指针数组的指针说大白话,就是一个指针
C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
文章图片

  1. 这个前置定语又可拆分成,函数指针 + 数组。函数指针是名词,又作前置定语,修饰数组。
    因此可以干掉定语部分,就剩指针了。
  2. 说白了函数指针数组就是一个数组
    C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
    文章图片

  3. 最终结果简化成指向数组的指针
7.2 定义 指向函数指针数组的指针:
  • 首先它是一个指针
  • 这个指针指向一个数组
  • 这个数组是函数指针数组
  • 数组里的每一个元素都是函数指针
  • 函数指针就是函数的地址,指针指向一个函数
  • 也可理解为指针保存了函数的地址,对指针解引用就能调用这个函数了
void test(const char* str) { printf("%s\n", str); } int main() { //函数指针pfun void (*pfun)(const char*) = test; //函数指针的数组pfunArr void (*pfunArr[5])(const char* str); pfunArr[0] = test; //指向函数指针数组pfunArr的指针ppfunArr void (*(*ppfunArr)[5])(const char*) = &pfunArr; return 0; }

画图分析更加一目了然:
C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
文章图片

7.3 指向函数指针数组的指针的应用 在了解了反复套娃的定义后,举一个例子来说明它的作用:
应用上一篇博文的例子:简易计算器【C语言进阶5——指针的进阶(2)】6、函数指针数组
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; }int main() { 上一一篇文章用了函数指针数组 int (*pfarr[4])(int, int) = {Add,Sub,Mul,Div}; 这一次加油改进,应用了指向函数指针数组的指针,代码长度又可以减少了 int (*(* p3)[4])(int, int) = &pfarr; //p3是一个指向函数指针数组的指针 int i = 0; for (i = 0; i < 4; i++) { //*p3是解引用,拿到函数指针数组的数组名 *(p3)=*(p3+0)=p3[0] //(*p3)[i]相当于pfarr[i],拿到了,数组的第i个元素,就是第几个函数的地址 int ret = p3[0][i](3, 4); //传参数就能直接调用函数 //int ret = (*p3)[i](3, 4); //传参数就能直接调用函数 printf("%d\n", ret); } return 0; }

这种数组和指针相互套娃的定义,了解就行了,遇到了能看懂就可以了,用到的情况还是比较少的。上面的例子完全就是符合内容的例子。
8、总结数组和指针 数组和指针应用广泛,知识点密集,容易混淆和遗忘,需要经常复习,因此,再次运用类比的方法,画图总结数组和指针:
8.1 数组小结
  • 整型数组
  • 字符型数组
  • 指针数组
  • 二维数组
    C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
    文章图片

    其中,二维数组在基础阶段学过:
  • 理解arr[2][3]是一个2行3列的数组,每个元素都是int型
  • 学完指针后,我们换一个角度取理解它,使得对二维数组的认识升华了一个层次
int main() { int arr[2][3] = { {1,2,3},{4,5,6}}; printf("%d\n", sizeof(arr)); //arr单独使用,求取的是整个数组的大小,24个字节 printf("%d\n", sizeof(arr+1)); //arr不是单独使用,代表的是首元素的地址,arr+1 就是第二个元素的地址,即第二行数组的地址,地址就是4/8 个字节 printf("%d\n", sizeof(arr[0])); //arr[0]是第一行数组的数组名,单独使用,求取的是第一行数组的大小,12个字节 printf("%d\n", sizeof(arr[0] + 1)); //arr[0]不是单独使用,arr[0] + 1就是第一行第二个元素的地址,地址就是4/8 个字节 printf("%d\n", sizeof(arr[0][1])); //第一行第二个元素的大小,4个字节 return 0; }

【C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】】从调试中可以看到:
  • 数组arr[2][3]的类型是:int[2][3]
  • 数组有两个元素 arr[0] 和 arr[1]
  • arr[0]的类型是int [3],代表的是第一行数组,表示有3个元素,每个元素的类型是:int
  • arr + 1,类型是:int[3]*,表示数组第二个元素 arr[1] 的地址,指向第二行数组
  • arr[0]+ 1,类型是:int*,表示的是第一行数组第二个元素的地址
C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
文章图片

8.2 指针小结
  • 整型指针
  • 浮点型指针
  • 字符型指针
  • 数组指针
  • 函数指针
    C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
    文章图片
8.3 数组指针套娃小结
  • 存放数组指针的数组
  • 存放函数指针的数组
  • 指向函数指针数组的指针
C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
文章图片

C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
文章图片

总结 数组和指针应用广泛,知识点密集,比较复杂,并且容易遗忘,要反复复习,温故而知新,要打下坚固的基础,不能盲目的赶学习进度,要按照自己的学习进度来,不要与别人比较。
在基础阶段学习了数组和指针的相关知识,就是进阶阶段相关知识点的基础,并且升华了一下。
到此为止,指针相关的知识点学习就告一段落了,下一篇将更新数组和指针的应用举例,从代码上来复习所学知识。
推荐一个在线画图的网页,之前用自动的画图,但是文字都是成图片了,不能直接编辑。今天尝试了网页绘图,保存默认的格式导出后,下一次打开还能直接编辑文字,感觉用的比画图好一些。
Flowchart Maker & Online Diagram Software

    推荐阅读