Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在一条指令中声明多个指针时的运算符优先级_C++_Pointers_Operator Precedence - Fatal编程技术网

C++ 在一条指令中声明多个指针时的运算符优先级

C++ 在一条指令中声明多个指针时的运算符优先级,c++,pointers,operator-precedence,C++,Pointers,Operator Precedence,我想理解为什么在同一行上声明更多具有相同数据类型的指针时,必须在每个标识符之前添加星号 这是我读书的地方 另一件可能引起您注意的事情是: int*p1,*p2 这声明了前面示例中使用的两个指针。但请注意,每个指针都有一个星号(*),以便两者都具有int*类型(指向int的指针)由于优先规则,这是必需的。请注意,如果代码为: int*p1,p2 p1确实是int*类型,但p2是int类型。对于这一点,空格根本不重要。但不管怎样,只要记住在每个指针上放一个星号,对于大多数对每个语句声明多个指针感兴

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

这是我读书的地方


另一件可能引起您注意的事情是:

int*p1,*p2

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

int*p1,p2

p1确实是int*类型,但p2是int类型。对于这一点,空格根本不重要。但不管怎样,只要记住在每个指针上放一个星号,对于大多数对每个语句声明多个指针感兴趣的指针用户来说就足够了。或者更好:对每个变量使用不同的语句



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

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


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

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


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

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

声明的语法是:

T D1, D2, D3, D4;
指与以下内容相同:

T D1; T D2; T D3; T D4;
其中:

  • T
    是声明说明符:没有符号,只有关键字(例如
    int
    const
    static
    )和/或typedef名称
  • Dn
    是一个声明符,也就是一个标识符(变量名称),可能带有
    *
    []
    (参数列表)
    或以各种方式附加的分组括号

在第一个示例中,
T
int
,声明符是
*p1
*p2
这里不涉及运算符优先级。事实上,也没有运营商。运算符对表达式进行操作,但这是一个声明

声明的语法是:

T D1, D2, D3, D4;
指与以下内容相同:

T D1; T D2; T D3; T D4;
其中:

  • T
    是声明说明符:没有符号,只有关键字(例如
    int
    const
    static
    )和/或typedef名称
  • Dn
    是一个声明符,也就是一个标识符(变量名称),可能带有
    *
    []
    (参数列表)
    或以各种方式附加的分组括号

在第一个示例中,
T
int
,声明符是
*p1
*p2
没有任何优先规则。简单声明的语法如下所示

decl-specifier-seq init-declarator-listopt ; 
符号*属于声明符,不属于decl specifier seq,例如类型说明符
int

例如,您可以重写声明

int * p1, * p2;

其中,
(*p1)
和(*p2)是十位数字(在这种情况下,括号是多余的)

例如,你不可以写作

( int * ) p1, p2;
编译器将发出一个错误

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

int ( *p )[N];
其中N是某个常数

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

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

void ( *f( int cmp( const void *, const void * ) )( int *a );
至于优先级,那么构建声明符的规则在语法中描述了它们

比如说

( int * ) p1, p2;
如果你愿意写

int * a[10];
int ( *a[10] ); 
int ( *a )[10];
然后它是一个包含10个元素的数组,类型为
int*

但是如果你愿意写

int * a[10];
int ( *a[10] ); 
int ( *a )[10];
然后它是一个10个指针的数组,指向
int
类型的对象

如果你愿意写

int * a[10];
int ( *a[10] ); 
int ( *a )[10];
然后它是一个指向10个整数数组的指针

考虑到typedef也是decl说明符

例如,这个typedef

typedef int *intPtr;
你可以像这样重写

int typedef *intPtr;
甚至像

int typedef ( *intPtr );
声明的另一个例子。让我们考虑多维数组。可以这样声明

int ( ( ( a )[N1] )[N2] );
尽管括号也是多余的。但是,它们可以帮助理解数组如何隐式转换为指向表达式中第一个元素的指针

例如,如果您有一个数组

int a[N1][N2];
然后,要获得指向其第一个元素的指针声明,可以重写该声明,如

int ( a[N1] )[N2];
现在用
a[N1]
代替
*a
(例如*p)


没有任何优先规则。简单声明的语法如下所示

decl-specifier-seq init-declarator-listopt ; 
符号*属于声明者