【C++ 深入浅出】如何分析 int (*p)(int); 等复杂指针类型

写在前面:我写博客主要是为了对知识点的总结、回顾和思考,把每篇博客写得通俗易懂 是我的目标,因为能让别人看懂,才是真的学会了

从Math到CS的跨专业经历,让我格外珍惜学习时间,更加虚心好学,而分享技术和知识是快乐 的,非常欢迎大家和我一起交流学习,期待与您的进一步交流

背景

在学习C++指针时,我们经常会遇到一些比较复杂的指针类型定义,很多人可能一直是一知半解的,比如下面这11个类型,你能否分析清楚p是什么类型

1int p;
2int *p;
3int p[4];
4int *p[4];
5int (*p)[4];

6int **p;
7int p(int); // 函数声明
8int *p(int); // 函数声明
9int (*p)(int); // 函数指针
10int *(*p(int))[4];

11const int * const p; // 指向常量的常量指针

那下面我会一个个详细地分析,这样以后再遇到指针类型分析,就不用害怕了

复杂类型分析原则

从变量名开始,根据运算优先级结合,一步一步分析

  • 如果是指针,下一步就考虑指向什么
  • 如果是数组,下一步就考虑元素大小是多少,元素类型是什么
  • 如果是函数,下一步就考虑参数是什么类型,返回值类型是什么

基本上掌握了这个原则,90%的复杂类型你都能分析得明明白白


例1

int p;

这是一个普通的整型变量

例2

int *p;

我们从变量名p开始分析,与它结合的是*所以p是一个指针,那接下来就是指针指向什么了,与int结合,说明指针所指向的内容是int型的,因此p是一个指向整型数据的指针

例3

int p[4];

从变量名p开始,先与[],表明p是一个数组,元素个数是4,接下来就是数组的元素是什么类型了,与int结合,说明元素的类型是整型,因此p是一个由整型数据组成的数组

例4

int *p[4];

从变量名p开始,因为[]优先级比*高,所以p先与[]结合说明p是个数组,元素个数是4,接下来就是数组的元素是什么类型了,与*结合,说明元素的类型是指针,接下来就是指针指向什么了,与int结合说明指针指向int型数据,因此p是一个由指向int型指针组成的数组

例5

int (*p)[4];

从变量名p开始,因为()的存在,所以会先与*结合,而不是[],说明p是一个指针,接下来就是指针指向什么了,与[]结合说明指针指向一个数组,元素大小是4,接下来就是数组的元素是什么类型了,与int结合,说明元素的类型是整型,因此p是一个指向由int型数据组成的数组的指针

例6

int **p;

从变量名p开始,先与*结合,说明p是一个指针,接下来就是指针指向什么了,与*集合说明指针p指向的元素是指针,然后与int结合,说明这个指针指向int型数据,因此p是一个指向指针(指向int型数据)的指针

例7

int p(int);

从变量名p开始,与()结合,说明p是一个函数,函数的参数是int,接下来就是函数的返回值类型是什么了,与int结合,说明返回值类型是int,因此p是一个函数,参数是int,返回值类型是int

例8

int *p(int);

从变量名p开始,由于优先级会先与()结合,则p是个函数,参数是int,接下来就是函数的返回值类型是什么了,与*集合说明是一个指针,然后与int结合,说明指针指向int,因此p 是一个函数,参数是int,返回值类型是一个指向int型数据的指针

例9

int (*p)(int);

从变量名p开始,由于优先级会先与*结合(第一个()就是来改变优先级的),说明p是一个指针,接下来就看指针指向什么,与()结合说明指针p指向一个函数,函数的参数是int,返回值是int,因此p是一个指向有一个整数参数且返回类型是整型的函数的指针(函数指针)

例10

int *(*p(int))[4];

从变量名p开始,与()结合说明p是一个函数,参数是int,再与*结合说明返回值是一个指针,然后再与[]结合,说明指针指向一个数组,元素大小是4,与*结合说明元素类型是指针,最后与int结合说明指针指向int型,因此p是一个参数为int型数据,返回值为一个指向由int型指针组成的数组的函数

例11

const int * const p; // 指向常量的常量指针

从变量名p开始,const说明p是一个常量对象,然后和*结合说明p是个指针,因此p是个常量指针,然后再与int结合说明,指针指向的是int对象,最后和const结合说明这个int对象是常量对象,因此p是指向int型常量的常量指针

更多解释请看
【C++ const引用和const指针详解】 (const int *p;) (int const *p;) (int *const p;)三者的区别


补充:定义变量的同时赋值

int a = 3;

int *p; // 定义
p = &a // 赋值

// 等价于int *p = &a; // 定义的同时赋值

上面的代码其实很简单,之所以提这个是想说,如果遇到定义的同时赋值,你一个清楚是在给谁赋值(定义部分的变量名)

这句话什么意思呢?

  • 比如int *p = &a;,定义部分的变量是p,那你赋值就要给一个地址(指针),因为p是指针,所以必须用地址给p赋值

  • 再复杂点的
    int p[4] =如果让你定义的同时并赋值,那你应该赋什么值。既然变量名p是个数组,你就应该赋值一个数组,即int p[4] = {1, 2, 3, 4};

int *p;
int *&r = p;  

r是个引用,相对于给指向int型的指针起别名。右边是赋值,所以必须用指针给r“赋值”

发布了239 篇原创文章 · 获赞 80 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104249258
今日推荐