当前位置: 首页 > article >正文

C:浅谈数组指针的声明

1. 背景

由于C语言中有数组指针和指针数组,一时间容易混淆,本文试图从语言设计者的角度出发给出一种较为简单的解释办法。

2. 数组和指针声明

我们假设我们只研究 int 相关的变量,那么好,我们现在知道,我们可以声明 int 类型的指针和数组:

int arr[5];
int *p_int;

我们假设我们自己就是C语言的设计师。把这门编程语言设计到这里,一切都是那么和谐。为什么呢?因为我们天然地把指针放在变量的左侧,数组中括号放在变量的右侧。两者清晰明了,且异常简洁。

然后我们面临一个问题:怎样声明一个指针数组?也就是数组中都是指针。

3. 指针数组

本着编译器解析源码的逻辑一致的原则,数组嘛,我们就让它这么写:

int *p_int_arr[5];

到这里,一切都比较和谐,我们为自己的机智感到满意。虽然有的人认为这样有歧义,但是你还是解释到:[]在结合性上比*的优先级高 ,所以大家还是适应一下吧,因为这样写,能保证数组表示一致呀,毕竟数组是需要批量处理的变量啊。

可紧接着,一个新问题就来了—— 怎么声明数组指针呢?就是指向数组的指针

4. 数组指针可能的两种设计

我们之前设计指针时,都希望指针放在变量名的左侧,那么数组指针,我这么写不就行了?

int [5] *i_arr_p; // 错误写法

可这样写不行,我们刚刚还说把数组中括号放在右边,马上这就放到了左边,这样不就更混乱了嘛?

你突然想到,在操作符优先级的控制中,有一个叫小括号的好工具,它可以让优先级低的先去结合。

故你写下:

int (*i_arr_p) [5];

于是你告诉大家,为了保证指针永远在左边,数组永远在右边,那么我设计了这个声明方式。它的含义在于:我先定义了它是一个指针,后说明它指向了一个数组。

可一时间群情激愤,程序员们的抗议声不绝于耳。

不知过了多少年,一个优秀的程序员说:“由于数组在右,指针在左,数组优于指针,括号还可以改变优先级,我们何不整理出一个右左法则?”

5. 右左法则

The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

右左法则:首先从最里面的圆括号(应该是未定义的标识符)看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

我们先判断一个变量最终是数组还是指针,然后再看补充说明的其它内容。

第一步就是距离变量名最近的是什么它就是什么,且数组比指针优先级高,小括号内被优先解析,记住这个核心的原则,再去补充这个变量其它的声明内容,你就彻底搞懂这个法则了。

比如:

举例解释
int *a;只包含指针,当然是指针类型,然后再去看 int
int a[5];只包含数组,当然是 int 数组了
int *a[5];虽然两者都有,但数组优于指针,所以是 int * 数组
int (*a)[5];虽然两者都有,但变量所在的小括号内只有指针,故为指针,指向了 int 数组
int (*a)(int);先看变量所在的小括号,发现是指针,且是函数指针
int (*a[5])(int);小括号内数组优先级高,所以首先是数组,然后数组中是指针,每个指针还都是函数指针。

以上的情况可以覆盖大部分情况!这就是右左法则,至此,你已经彻底搞懂如何去解析一个变量的声明了。


http://www.kler.cn/news/359017.html

相关文章:

  • CODESYS面向对象编程:方法/动作/属性的使用
  • MyBatis 动态 SQL 详解
  • Mac通过键盘选取内容
  • 京东云主机和云服务器有啥区别?轻量云主机就是轻量应用服务器吗?
  • 编写Python 自动化安装openGauss 数据库方法和代码 (2)
  • Lua条件语句
  • MongoDB Shell的使用
  • ADMEMS矩阵
  • 什么是凸二次规划问题
  • CORS跨域访问的坑
  • 05DSP学习-利用sys配置中断-以EPWM中断为例
  • 基于docker运行windows系统
  • 使用LSPatch+PlusNE修改手机软件
  • 新款任天堂switch游戏机方案,支持4K60HZ投屏方案,显示器,手柄方案
  • 软考高级系统架构设计师 知识产权
  • 软件测试工程师必会sql知识点总结(mysql特点总结)
  • 经典文献阅读之--RGBD GS-ICP SLAM(结合ICP和3D GS构建最快的稠密SLAM)
  • kafka脚本工具使用
  • 记录一次hiveserver2卡死(假死)问题
  • 学习eNSP对提升就业竞争力有多大帮助?