因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既着名又常用的方法。不过,右左法
则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用
来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
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 (*func)(int *p);
首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看
右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是 int。
int (*func)(int *p, int (*f)(int*));
func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。
int (*func[5])(int *p);
func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰 func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
int (*(*func)[5])(int *p);
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
int (*(*func)(int *p))[5];
func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
要注意有些复杂指针声明是非法的,例如:
int func(void) [5];
func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。
int func[5](void);
func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。
作为练习,下面列几个复杂指针声明给读者自己来解析。
int (*(*func)[5][6])[7][8];
int (*(*(*func)(int *))[5])(int *);
int (*(*func[7][8][9])(int*))[5];
实际当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层
分解,增强可读性,例如对于声明:
int (*(*func)(int *p))[5];
可以这样分解:
typedef int (*PARA)[5];
typedef PARA (*func)(int *);
这样就容易看得多了。
答案,同时给出用typedef的分解方法:
int (*(*func)[5][6])[7][8];
func是一个指向数组的指针,这类数组的元素是一个具有5X6个int元素的二维数组,而这个二维数组的元素又是一个二维数组。
typedef int (*PARA)[7][8];
typedef PARA (*func)[5][6];
int (*(*(*func)(int *))[5])(int *);
func是一个函数指针,这类函数的返回值是一个指向数组的指针,所指向数组的元素也是函数指针,指向的函数具有int*形参,返回值为int。
typedef int (*PARA1)(int*);
typedef PARA1 (*PARA2)[5];
typedef PARA2 (*func)(int*);
int (*(*func[7][8][9])(int*))[5];
func是一个数组,这个数组的元素是函数指针,这类函数具有int*的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素
的数组。
typedef int (*PARA1)[5];
typedef PARA1 (*PARA2)(int*);
typedef PARA2 func[7][8][9];
文章转载自: http://c.chinaitlab.com/skill/803431.html
分享到:
相关推荐
C语言右左法则----复杂指针解析 C语言中的指针声明可以非常复杂,以至于让人难以理解和解析。为了解决这个问题,右左法则被引入,以帮助开发者更好地理解和解析复杂的指针声明。右左法则是一个简单却非常实用的方法...
右左法则是一种解析C语言中复杂指针声明的方法,它不是C语言标准的一部分,而是根据标准中的声明规则归纳出来的。该法则的英文原文是:“The right-left rule: Start reading the declaration from the innermost ...
需要注意的是,有些复杂指针声明是非法的,例如: int func(void) [5]; func 是一个返回值为具有 5 个 int 元素的数组的函数。但 C 语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个...
本文将深入探讨如何理解和使用复杂指针,特别是通过右左法则来解析声明。 首先,我们要明白,指针的基本概念是一个变量,它存储的是另一个变量的地址。当我们看到一个声明如`int *p;`,我们知道`p`是一个指向整型...
通过对上述示例的分析,我们可以看出右左法则确实是一种非常有效的方法,可以帮助我们理解复杂指针声明的意义。当然,在实际编程中,为了避免过多地使用复杂的指针声明,通常会采用`typedef`等语法糖来简化代码的...
本文将深入探讨“复杂指针”的概念,以及如何使用“右左法则”来解析和理解复杂的指针声明。 复杂指针声明通常涉及指针、数组和函数的嵌套组合,它们的解析需要遵循一定的规则。右左法则是一种流行的方法,用于理解...
总的来说,“右左法则”是一种简单但非常有效的解析复杂指针声明的方法。通过遵循这一法则,我们可以轻松地理解并正确解释各种复杂的指针声明,这对于学习和使用C语言来说是非常宝贵的技能。希望通过对本篇学习笔记...
总之,理解和应用右左法则可以帮助我们解析C语言中复杂的指针声明,这对于阅读和编写涉及指针操作的代码至关重要。通过逐步分析声明的各个部分,我们可以准确地理解变量的类型和它所表示的数据结构。在实际编程中,...
右左法则是C语言中解析指针声明的重要方法,它的英文原文是:The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, ...
右左法则是一个非常著名的用于解析复杂指针声明的方法。尽管它并不是C语言标准的一部分,但却是根据C语言的标准声明规则归纳出来的。简单来说,这个方法帮助我们按照一定的顺序来阅读和理解复杂的声明。 - **步骤一...
因此,本文将详细讨论C语言中的复杂声明,包括右左法则、typedef逐步分解方法,帮助C语言的初学者准确把握复杂指针声明的解析。 一、右左法则 右左法则是一种解析复杂声明的方法,该方法可以帮助程序员快速并正确...
在C语言中,正确理解和解析复杂的指针声明是至关重要的,因为它们经常出现在高级编程技巧和数据结构中。右手法则是解析这些声明的一种方法,它能够帮助程序员避免混淆,更清晰地理解指针、数组和函数之间的关系。...
对于更复杂的指针声明,我们可以通过所谓的“右左法则”来进行解析。该法则的核心在于按照一定的顺序逐步解析声明中的每一部分。具体步骤如下: - **右左法则**: - 从最内部的括号开始阅读。 - 首先向右读,然后...
- 解析复杂声明时,通常使用右左法则:从未定义的标识符开始,先看右边的括号,再看左边的*号,遇到括号就转向内部解析。 4. **例子解析**: - `int (*func)(int *p);`func是一个函数指针,它指向接受一个整型...
在C和C++语言中,我们可以使用右左法则来解析复杂类型的声明。右左法则的基本原则是,从右到左读取类型声明,遇到括号时,先解析括号内的类型,然后继续从右到左读取。 C和C++语言中的复杂类型声明方式非常多样化,...
- 右左法则:从变量标识符开始阅读,向右遇到变量名时转向左,遇到圆括号时调转阅读方向。解析完括号内容后跳出,重复至整个声明解析完毕。 2. 数组首地址的理解: - 对于数组名a,a是数组首元素的首地址,即a[0]...
右左法则是一种用于解析复杂指针声明的有效方法。其核心思想是从最内层的圆括号开始,按照一定的顺序解析整个声明。 1. **步骤解析**: - **步骤1**:从最内侧的圆括号开始读。 - **步骤2**:向右读,遇到圆括号...
本文将带领读者逐步解析C/C++中的复杂函数声明,包括使用typedef、const关键字以及函数指针的高级用法,并教授掌握“右左法则”,从而准确理解任何C/C++声明。 ### 基础知识 在开始解析复杂声明之前,我们需要了解...