C/C++编译器如何区分*运算符(指针、解引用运算符、乘法运算符)的用途?
How does the C/C++ compiler distinguish the uses of the * operator (pointer, dereference operator, multiplication operator)?
在 C 和 C++ 语言中,编译器如何区分 *
用作指针 (MyClass* class
) 和用作乘法运算符 (a * b
) 或何时是取消引用运算符 (*my_var
)?
这取决于它的使用上下文,为了简单的解析它会查看左右单词以了解符号是什么。
该语言的句法由语法产品树定义,这些产品本质上赋予某些运算符的应用优先于其他运算符的应用程序的优先级或“优先级”。这在表达式可能不明确时特别方便(因为,比如说,使用的两个运算符由相同的词法标记表示)。
但这只是 lexing 和 parsing。任何特定操作是否实际上在语义上有效要到编译后期才能确定;特别是,给定两个指针 x
和 y
,表达式 *x *y
将无法编译,因为您不能将 *x
乘以 y
,而不是因为有一个缺少运算符,否则可能是取消引用,然后是另一个取消引用。
进一步阅读维基百科页面:Lexer_hack。
其他有趣的读物 Lexer-Hack Enacademic link。
- deferencing
*
运算符是一元运算符,因此在一般情况下编译器将应用隐式规则。例如
int a;
int *ptr = &a;
*ptr = 5;
- 乘法运算符
*
是一个二元运算符,因此在一般情况下,编译器将应用乘法运算,前提是操作数支持它,例如:
int a;
int b;
int c = a*b;
- 对于更复杂的操作,如果运算符 precedence 不够用,您可能需要通过使用括号来帮助编译器理解您的意思,例如:
int a = 1;
int b[2] = {2,3};
int *aPtr = &a;
int *bPtr = b;
int c = *aPtr * *(bPtr+1);
在 C 和 C++ 语言中,编译器如何区分 *
用作指针 (MyClass* class
) 和用作乘法运算符 (a * b
) 或何时是取消引用运算符 (*my_var
)?
这取决于它的使用上下文,为了简单的解析它会查看左右单词以了解符号是什么。
该语言的句法由语法产品树定义,这些产品本质上赋予某些运算符的应用优先于其他运算符的应用程序的优先级或“优先级”。这在表达式可能不明确时特别方便(因为,比如说,使用的两个运算符由相同的词法标记表示)。
但这只是 lexing 和 parsing。任何特定操作是否实际上在语义上有效要到编译后期才能确定;特别是,给定两个指针 x
和 y
,表达式 *x *y
将无法编译,因为您不能将 *x
乘以 y
,而不是因为有一个缺少运算符,否则可能是取消引用,然后是另一个取消引用。
进一步阅读维基百科页面:Lexer_hack。
其他有趣的读物 Lexer-Hack Enacademic link。
- deferencing
*
运算符是一元运算符,因此在一般情况下编译器将应用隐式规则。例如
int a;
int *ptr = &a;
*ptr = 5;
- 乘法运算符
*
是一个二元运算符,因此在一般情况下,编译器将应用乘法运算,前提是操作数支持它,例如:
int a;
int b;
int c = a*b;
- 对于更复杂的操作,如果运算符 precedence 不够用,您可能需要通过使用括号来帮助编译器理解您的意思,例如:
int a = 1;
int b[2] = {2,3};
int *aPtr = &a;
int *bPtr = b;
int c = *aPtr * *(bPtr+1);