C/C++ 编译器如何区分 * 运算符(指针、解引用运算符、乘法运算符)的使用?

Pin*_*ker 12 c c++ c++-faq lexical-analysis lexer

在 C 和 C++ 语言中,编译器如何区分*何时用作指针 ( MyClass* class)、何时用作乘法运算符 ( a * b) 或何时用作解引用运算符 ( *my_var)?

Zig*_*zor 19

这取决于使用它的上下文,对于简单的解析,它查看左右单词以了解符号是什么。

该语言的语法由语法产生式树定义,这些产生式本质上赋予某些运算符的应用优先于其他运算符的应用的优先级或“优先级”。这在表达式可能有歧义时特别方便(因为,例如,使用的两个运算符由相同的词法标记表示)。

但这只是词法分析解析。任何特定操作是否实际上在语义上有效直到编译后才决定;特别是,由于两个指针xy,表达式*x *y将无法编译,因为你不能乘*xy,而不是因为有什么,否则可能已经取消引用紧接着又提领丢失的运算符。

进一步阅读维基百科页面:Lexer_hack

在这个Lexer-Hack Enacademic链接上还有其他有趣的读物。


Jea*_*lle 5

  • deferencing*运算符是一元运算符,因此在微不足道的情况下,编译器将应用隐式规则。例如
int a;
int *ptr = &a;
*ptr = 5;
Run Code Online (Sandbox Code Playgroud)
  • 乘法运算符*是一个二元运算符,因此在微不足道的情况下,编译器将应用乘法,前提是操作数支持它,例如:
int a;
int b;
int c = a*b;
Run Code Online (Sandbox Code Playgroud)
  • 对于更复杂的操作,如果运算符优先级不够,您可能需要通过使用括号来帮助编译器理解您的意思,例如:
  int a = 1;
  int b[2] = {2,3};
  int *aPtr = &a;
  int *bPtr = b;
  
  int c = *aPtr * *(bPtr+1);
Run Code Online (Sandbox Code Playgroud)