C++ 二级指针的理解
来源:互联网 发布:软件项目管理方法 编辑:程序博客网 时间:2024/06/09 18:04
二级指针是指向指针的指针。
首先我们先来看一段代码
#include "stdafx.h"#include <iostream>using namespace std;int main(){ int i=3; int ** p = (int**)&i; //定义一个二级指针p,指向i int *q = &i; cout<<"hello"<<endl; cout<<"*p = "<<(int)*p<<endl<<"&i = "<<&i<<endl; cout << "*q = " << *q << endl; cout << (int*)i << endl; //cout << **p << endl; return 0;}
在上面代码中,
int ** p = (int**)&i;
要说明一点就是,这里的指针p和&i的关系,实际上是p始终指向i,不管前面定义了多少个*
(比如int***p = (int***)&i,指向i的还是p,*p等于i
)也就是说,定义的* 只是返回类型。
而*p等于i,如果尝试这么做
cout << **p << endl;
这里就是将i的值当成 指针,然后去寻找这个值所指向的那个地方,其实是很危险的,因为我们知道*p指向内存的哪里,所以最好不要尝试这么做。
再来说一个例子,关于定义一个指向函数指针的指针的二级指针。
我们通常通过 typedef
关键字来帮助我们实现指向函数指针的指针。比如通过以下的方法:
typedef int func(int);typedef func* func_ptr;typedef func_ptr* func_ptr_ptr;func_ptr_ptr p;
这个方法很实用,但是现在,我们需要从二级指针的角度出发,来帮助我们完成这个定义。
首先我们来看一下最初的定义:
int a;
这定义了一个整型。
int *p;
这定义了一个指向整数的指针。那么这个指针怎么变成整数呢?很简单,只需要 *p 就可以了。我们惊奇的发现,定义时和使用时的形式是一模一样的。这不是个巧合,是语言设计者有意为之的。
int *p 的意思就是让 *p 为整形。那么 p 自然是指向整数的指针了。
再来看一个的例子。
int (*p)(int);
这个p是什么我们不知道,但我们知道 (*p)(int)
是个整数,所以, *p
是个 返回整数的函数。而p
就是指向这种函数的指针啦。那么如何定义函数指针的指针呢?简单点说,就是加个 * 就行了。假如不幸的是,我们一开始加错了地方,变成了:
int *(*p)(int);
我们来用我们的脑袋检验一下(你需要熟悉运算符优先级(这里又有一个口诀:小括号的运算级最高)): *(*p)(int)
是个整数,所以 (*p)(int)
是个整数的指针。 所以 *p
是个函数,返回一个整数指针,所以p
是个函数指针。
那么我们,将*
挪一下地方。 int (**p)(int)
;
再来检验一下:(**p)(int)
是个整数。 **p
是个函数,返回一个整数。于是 *p
是个函数的指针。 p
是个函数指针的指针。
有的时候,有的人会直接这样定义函数的指针的指针:
int **p(int);
他还振振有词:这很显然呀。我们来看看他错在哪里:小括号的优先级最高,当你写下这个语句的时候: **p(int)
实际上是先执行 p(int)
的,所以,这个定义就是 **p(int)
是个整数,所以 *p(int)
就是整数的指针,而p(int)
就是指针的指针,所以p
就是函数的指针(实际上最后一步是个语法糖。不过我们这里就不追究啦)
当然也可以这样理解,从变量名开始,顺时针螺旋阅读类型。
int(*((*ptr(int,int))))(int);
先从ptr 是……开始:
从ptr开始,向右阅读,遇到(int,int),说明ptr是一个函数,接受参数(int,int)。
ptr 是 一个函数 接受(int,int) 返回……
然后转到左边,遇到*,代表ptr的返回值是个指针。
ptr 是 一个函数 接受(int,int) 返回 一个指针,指向……
目前的情况大概是:
int(*((ptr)))(int);
去掉两对括号后:
int(*ptr)(int);
右边遇到),再到左边,遇到了*,代表这又是个指针。现在我们有:
ptr 是 一个函数 接受(int,int) 返回 一个指针,指向 一个指针 指向……
再向右,遇到(int),代表接下来是一个函数。现在有:
ptr 是 一个函数 接受(int,int) 返回 一个指针,指向 一个指针 指向 一个函数 接受(int) 返回……
再转一圈,遇到最后的int。完整的ptr的类型是:
ptr 是 一个函数 接受(int,int) 返回 一个指针,指向 一个指针 指向 一个函数 接受(int) 返回int或者可以换一个语序:
ptr 是 一个接受(int,int)返回(一个指向(一个指向(一个接受(int)返回int的函数)的指针)的指针)的函数。
构造一段代码来测试一下这个结果:
int foo(int){return 0;} //一个接受(int)返回int的函数decltype(&foo) address_of_foo=&foo; //一个指向(一个接受(int)返回int的函数)的指针int(*((*ptr(int,int))))(int) { //一个接受(int,int) 返回(一个指向(一个指向(一个接受(int)返回int的函数)的指针)的指针)的函数 return &address_of_foo; //一个指向(一个指向(一个接受(int)返回int的函数)的指针)的指针}
那么怎么才能把这个转换成一般人能读懂的代码呢,其实加一个alias就可以大大增强可读性:
using FuncType = int(int);
FuncType** ptr2(int,int);
简单易懂。
(int(*p)(int) //p是一个指针,接收一个int,返回一个整型int* p(int) //p是一个函数,接收一个int,返回一个指针,指向int(返回int型指针)
其中部分内容来源于https://www.zhihu.com/question/38955439/answer/79101717
作者:王霄池
来源:知乎
https://www.zhihu.com/question/65116993/answer/227939489
作者:Harry Nu
来源:知乎
- C/C++中二级指针的理解
- C/C++中二级指针的理解
- C/C++中二级指针的理解
- 二级指针的理解
- 二级指针的理解
- C语言的二维数组和二级指针的理解
- 关于C语言中二级指针的理解
- 关于二级指针的理解
- C++ 二级指针的理解
- C+= 指针理解的通关测试:指针数组,数组指针,指针函数,函数指针,二级指针
- 深入理解指针以及二级指针(指针的指针)
- 今天对二级指针的深入理解
- 二级指针理解 + static的特殊用法
- 理解二级指针
- 理解二级指针
- c 语言函数传参的三种方式及二级指针的理解
- 关于C的二级指针的问题
- C语言二级指针(指向指针的指针)
- DS:对称矩阵
- Vessels CodeForces
- nginx去掉index.php 只需2个步骤。
- 学习系列-DLL
- Java swing 仿QQ实现系统托盘图标(下)
- C++ 二级指针的理解
- [数论] LOJ #508. 「LibreOJ NOI Round #1」失控的未来交通工具
- Spring Aop基础
- 堆的使用,自己确定数组的大小和值,然后求和
- DOM编程-节点操作(一)
- Javascript中获取数组最大值和最小值以及最大值和最小值的下标 没学对象前的最简单最基本的方法
- 归档、压缩
- VMware ESXi 体系结构探索
- DOM编程-节点操作(二)