首页 > 编程语言 >参诸文籍, 带你深入理解C/C++复杂指针声明

参诸文籍, 带你深入理解C/C++复杂指针声明

时间:2024-08-21 10:22:03浏览次数:14  
标签:pp 指向 int 声明 C++ 运算符 文籍 参诸 指针

参诸文籍, 带你深入理解C/C++复杂指针声明

本文参考的相关文章已置于页脚
在这里插入图片描述

文章目录

一. 引言

大家是不是曾经遇到像int * (* (*fp1) (int) ) [10];一样的复杂指针声明? 是不是看着这种声明表达式就头晕? 本文将结合C/C++运算符优先级右左原则(即, The Right-Left Rule)引导你逐步理解C/C++的复杂指针声明.

Note:本文参考的相关文章已在页脚放出, 部分文章为英文版本.


二. C/C++ 运算符优先级

Note:此处仅展示本文可能涉及的运算符, 完整内容请参考微软文档 - C++ 内置运算符、优先级和关联性

  • 指针声明:int *。
  • 取址运算符:&。
  • 间接访问运算符:*。
  • 其他运算符: []、()。
  • 这些运算符的优先级按照从高到低的顺序依次为:[]   ()    *    &

三. 简单表达式

int *p;
int **pp;
int *(*pp); // 等效于第二行, 因为*这种一元运算符本就是从右至左的结合顺序.

一. int *p;

*一元操作符, 作用是声明一个指针.这个语句声明p是一个指向int类型的指针, 有个问题需要弄清楚?是那一部分把p变成指针的呢?

  • int *这个整体?
  • *?

答案是*, *会先和p结合, 声明p是一个指针, 至于p指针指向的是什么类型的数据呢?由int指定.我们在分析时一定要注意这一点, 还不懂的话, 稍后讲解右左原则时,会详细讲解.

二. int **pp;

因为类似于 *++这样的一元运算符遵循从右至左的结合顺序(所以, int *(*pp);的效果与int **pp;一样), 所以int **pp;可以这样理解.

    1. 右侧第一个*先与pp结合, 代表pp是一个指针.
    1. 现在已经知道pp是一个指针了, 由于从右至左的结合顺序, 接下来右侧第二个*将代表p指针所指向的类型, 即一个指针, 那么这个pp指针所指向的指针指向的是什么类型呢?我们看到前面有个int, 那就是pp一个指向指向int类型的指针的指针, 我知道你可能有点头晕, 但你先别晕.

四. 解读 C 声明的“右左”规则[重要]

(一)、符号含义

  • *:表示“指向……的指针”,且始终位于左侧。
  • []:表示“……的数组”,始终位于右侧。
  • ():表示“返回……的函数”,始终位于右侧。

(二)、解读步骤

步骤 1

找到标识符,此为起始点。然后在心里默念“标识符是”,开始构建声明语句。

步骤 2
  1. 观察标识符右侧的符号。
    • 若发现“()”,则知道这是一个函数的声明,此时表述为“标识符是函数返回……”。
    • 若发现“[]”,则表述为“标识符是……的数组”。
  2. 持续向右侧推进,直到没有符号或者遇到右括号“)”。若遇到左括号,即使括号中间有东西,也视为“()”符号的开始部分。
步骤 3
  1. 观察标识符左侧的符号。
    • 如果不是特殊符号(如上述提到的*[]()),直接表述出来。
    • 如果是特殊符号,则按照符号含义表翻译为对应的英文表述。
  2. 持续向左侧推进,直到没有符号或者遇到左括号“(”。

(三)、示例

(1)int *p[];示例
  1. 找到标识符“p”,此时表述为“p 是”。
  2. 向右侧移动,遇到“[]”,变为“p 是数组的”。
  3. 向左侧移动,遇到“*”,变为“p 是数组的指针指向”。
  4. 继续向左侧移动,完成最终表述“p 是数组的指针指向 int”(或者表述为“p 是一个数组,其中每个元素的类型是指向 int 的指针”)。
(2)int *(*func())();示例
  1. 找到标识符“func”,表述为“func 是”。
  2. 向右侧移动,遇到“()`,变为“func 是函数返回”。
  3. 向左侧移动,遇到“*”,变为“func 是函数返回指针指向”。
  4. 再次向右侧移动,变为“func 是函数返回指针指向函数返回”。
  5. 再次向左侧移动,变为“func 是函数返回指针指向函数返回指针指向”。
  6. 最后向左侧移动,完成最终表述“func 是函数返回指针指向函数返回指针指向 int”。
(3)int (*(*fun_one)(char *,double))[9][20];示例

按照规则解读为“fun_one 是指针指向函数(该函数接收(char *,double)参数并返回指针指向大小为 9 的数组的大小为 20 的 int 数组)”。

Allright, 你应该已经知道怎么理解这些复杂指针声明了!请您老给个三连吧!!!

在这里插入图片描述

五. 相关文章

  • 《理解C语言中指针的声明以及复杂声明的语法》By TimeShatter (CSDN)
  • 《The "Right-Left" Rule》By Rick Ord
  • 《How to interpret complex C/C++ declarations》By
    Vikram A Punathambekar

标签:pp,指向,int,声明,C++,运算符,文籍,参诸,指针
From: https://blog.csdn.net/weixin_54444518/article/details/141377588

相关文章

  • C++运算符优先级
    优先级操作符描述例子结合性1()[]->.::++--调节优先级的括号操作符数组下标访问操作符通过指向对象的指针访问成员的操作符通过对象本身访问成员的操作符作用域操作符后置自增操作符后置自减操作符(a+b)/4;array[4]=2;ptr->age=34;obj.age=34;Class::ag......
  • BST 二叉搜索树 BinarySearchTree C++实现(递归/非递归)
    目录二叉搜索树基本概念常用结论用途二叉搜索树的性能分析二叉搜索树的操作查找插入删除代码实现BSTree.hpptest.cc二叉搜索树基本概念二叉搜索树(BST,BinarySearchTree)二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树......
  • 排序算法 排序性能测试代码(随机数调整,高精度时间) - C++
    目录测试工具源码testsort测试工具C++11标准库<chrono>中高精度计时器,时间精度可以达到1纳秒.C++11标准库<random>中随机数生成器,可以实现各类随机数,本测试主要用于实现9成随机数下排序性能源码源码我拆分成两部分,一部分为测试,一部分为sort源码.合并一起使用test......
  • VSCode系列 - 如何用VSCode搭建C++高效开发环境(1)
    VSCode是笔者用过的最好用的开发工具,没有之一。笔者14年的码龄生涯中,先后用过Eclipse、IntelliJIDEA、WebStorm、PyCharm、VisualStudio(2010/2013/2015)、NetBeans、SublimeText等,但自从用VSCode之后,就再没换过其他工具,一直用到现在有5年多的时间。1.本文目标这篇文......
  • C/C++计算一元二次方程ax²+bx+c=0的根,作业作弊神器
    //在日常计算中,我们通常要计算一元二次方程的根,当系数为整数时,硬着头皮算算就行,但如果系数位小数,有没掌握一定解题技巧,求根会变得异常困难,那么我们可以借助计算机的力量进行强行破解,只需在控制台上输入对应系数即可求根,大大提高计算效率。废话不多说上代码!!记得支持一下喔~~~//......
  • 【C++二分查找 前缀和 】1292. 元素和小于等于阈值的正方形的最大边长
    本文涉及的基础知识点C++二分查找C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例包括课程视频LeetCode1292.元素和小于等于阈值的正方形的最大边长给你一个大小为mxn的矩阵mat和一个整数阈值threshold。请你返回元素总和小于或等于阈值的正方形区......
  • C++——STL——string容器
    string的头文件#include<string>string的初始化1.默认初始化,此时该字符串为空字符串strings1;2.s2是s1的副本strings2(s1)//构造函数3.等价于s3(s1),则s3是s1的副本strings3=s1;4.s4的字面值是"nihao"strings4("nihao");//构造函数5.与上行代码是等价的string......
  • [C++] template+struct 组合使用小技巧
    1.简单说明  struct+template的组合可以让我们使用同一个结构体名称(注意:只是名称相同,但是本质上已经不同了),实现不同的结构体功能,可以将其理解为设计模式中的工程模式。2.代码示例  首先,声明一个枚举类型,用于区别结构体,然后使用template+struct,声明一个结构体,只声明不实现......
  • C++基础用法
    容器vector定义#include<vector>usingnamespacestd;vector<type>name;//type为数据类型,如int,string等,name为vector标识访问通过下标访问通过迭代器访问vector<type>::iteratorit;例如:vector<int>::iteratorit=vi.begin();......
  • 从零开始学习C++(0)
    这是什么?要先学习C++,我们要先了解C++是什么这是WikiPedia的解释,我们来提炼一下:C++是一种高级语言。C++是C语言的扩展升级版。C++是面向对象语言。下载环境简单了解一下后,我们来下载C++编译器环境。目前有很多种编译器,例如:Dev-C++CodeBlocksVSCVSred......