在一条指令中声明更多指针的运算符优先级

Posted

技术标签:

【中文标题】在一条指令中声明更多指针的运算符优先级【英文标题】:Operator Precedence in declaring more pointers in one instruction 【发布时间】:2019-12-16 22:15:35 【问题描述】:

我想了解为什么在同一行上声明更多具有相同数据类型的指针时,我必须在每个标识符前添加一个星号。

Here 是我阅读的地方


另一件可能会引起你注意的是这行:

int * p1, * p2;

这声明了前面示例中使用的两个指针。但请注意,每个指针都有一个星号 (*),以便两者都具有 int* 类型(指向 int 的指针)。 由于优先规则,这是必需的。请注意,如果代码是:

int * p1, p2;

p1 确实是 int* 类型,但 p2 是 int 类型。为此目的,空间根本不重要。但无论如何,对于大多数有兴趣在每个语句中声明多个指针的指针用户来说,只需记住每个指针放一个星号就足够了。甚至更好:对每个变量使用不同的语句。


operator precedence

问题:这里使用什么规则,这是什么优先级?它是关于逗号还是星号?我想不通。

【问题讨论】:

FWIW 有关此的规则是 here 。这是关于语言的语法是如何工作的,而不是运算符优先级。 【参考方案1】:

没有任何优先规则。简单声明的语法看起来像

decl-specifier-seq init-declarator-listopt ; 

符号 * 属于不属于 decl-specidier-seq 的声明符,例如类型说明符 int

所以你可以例如重写声明

int * p1, * p2;

喜欢

int ( * p1 ), ( * p2 );

( *p1 ) 和 ( *p2 ) 是 decalartors(在这种情况下,括号是多余的)

你可能不会写例子

( int * ) p1, p2;

编译器会报错。

声明更复杂的类型时需要括号。例如,让我们声明一个指向数组的指针

int ( *p )[N];

其中 N 是某个常数。

因此您可以将声明符括在括号中。

让我们考虑一个更复杂的声明:一个函数返回一个指向函数的指针,并将另一个函数作为参数

void ( *f( int cmp( const void *, const void * ) )( int *a );

至于优先级然后构建声明符的规则在语法中描述它们

例如

如果你会写

int * a[10];

那么它是一个包含 10 个 int * 类型元素的数组。

但是如果你会写

int ( *a[10] ); 

然后它是一个包含 10 个指针的数组,指向 int 类型的对象。

如果你会写

int ( *a )[10];

那么它是一个指向 10 个整数数组的指针。

考虑到 typedef 也是一个 decl 说明符。

例如这个 typedef

typedef int *intPtr;

你可以重写

int typedef *intPtr;

甚至喜欢

int typedef ( *intPtr );

声明的另一个例子。让我们考虑一个多维数组。 in 可以声明为

int ( ( ( a )[N1] )[N2] );

尽管括号是多余的。但是,它们可以帮助理解数组如何隐式转换为指向表达式中第一个元素的指针。

例如,如果你有一个数组

int a[N1][N2];

然后要获得指向其第一个元素的指针声明,您可以重写声明,例如

int ( a[N1] )[N2];

现在用a[N1] 替换*a(或例如*p)。

int ( *p )[N2] = a;

【讨论】:

【参考方案2】:

没有优先规则本身;相反,这条规则规定int 部分适用于所有变量,而* 仅适用于紧随其后的那个。

规则的一般版本是声明中的所有说明符都适用于被声明的每个实体。说明符包括constexprstatic 等关键字,以及表示int 等类型的关键字和用户定义的类型名称。像 *& 这样的运算符会修改类型说明符以创建更复杂的类型,但是一次只能应用于一个实体。

【讨论】:

【参考方案3】:

这里不涉及运算符优先级。实际上也没有运营商。运算符对表达式进行操作,但这是一个声明。

声明的语法是:

T D1, D2, D3, D4;

意思相同:

T D1; T D2; T D3; T D4;

地点:

T声明说明符:没有符号,只有关键字(例如 intconststatic)和/或 typedef-names。 Dn 是一个声明符,即一个标识符(变量的名称),可能带有*[](parameter-list) 或以各种方式附加的分组括号。

在您的第一个示例中,Tint,声明符是 *p1*p2

【讨论】:

不应该是声明说明符 int* 吗?这不是数据类型吗? 好的,我在下面读到 sigm * 属于声明符而不是声明说明符!

以上是关于在一条指令中声明更多指针的运算符优先级的主要内容,如果未能解决你的问题,请参考以下文章

一条指令在cpu中的执行流程(理解CPU组成)

Linux 进程管理 进程优先级管理

C语言中30多个运算符的优先级顺序

C中的指针操作和运算符优先级

运算符的优先级以及,运算符

指针符号和自增符号的优先级