我在查看这个页面:https://en.cppreference.com/w/c/language/operator_precedence
引起我的注意的是,括号运算符的唯一描述是“函数调用”。这是否意味着表达式x = a * (b+c)-(d*e)
有两个函数调用?
我在查看这个页面:https://en.cppreference.com/w/c/language/operator_precedence
引起我的注意的是,括号运算符的唯一描述是“函数调用”。这是否意味着表达式x = a * (b+c)-(d*e)
有两个函数调用?
如上所述,括号可以用来分组表达式。Syntax
1
primary-expression: identifier constant string-literal ( expression ) generic-selection
...
5 A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression. It is an lvalue, a function designator, or a void expression if the unparenthesized expression is, respectively, an lvalue, a function designator, or a void expression.
postfix-expression:
...
postfix-expression(argument-expression-list opt)
...
所以在你的表达式中:
x = a * (b+c)-(d*e)
if
和switch
语句的语法中使用括号:if (expression) statement, if (expression) statement else statement, switch (expression) statement。第6.8.5节关于迭代语句也在while
和for
语句的语法中使用括号。
- while (表达式) 语句
- do 语句 while (表达式);
- for (表达式可选; 表达式可选; 表达式可选) 语句
- for (声明 表达式可选; 表达式可选 ) 语句
函数调用是后缀表达式。
在这些表达式中:
x = a * (b+c)-(d*e);
子表达式(b+c)
和(d*e)
是主要表达式。您可以将任何表达式括在括号中,这样您就会得到一个主要表达式。
例如,您甚至可以以以下方式重写表达式语句
( x = ( ( ( a ) * (b+c) )-(d*e) ) );
( a )
(b+c)
(d*e)
( ( a ) * (b+c) )
( ( ( a ) * (b+c) )-(d*e) )
( x = ( ( ( a ) * (b+c) )-(d*e) ) )
( *p )() // a function call
a[n] // using the subscript operator
x++; // using the postfix increment operator
函数调用的定义是:
postfix-expression:
primary-expression
postfix-expression ( argument-expression-listopt )
从C标准(6.5.2.2函数调用)中可知:
1. 表示被调用函数的表达式必须具有指向返回void或返回非数组完整对象类型的函数指针类型。
下面是一些奇怪的函数调用的例子:)
#include <stdio.h>
void f( void )
{
printf( "Hello " );
}
void g( void )
{
puts( "Broman" );
}
int main( void )
{
void ( *funcs[] )( void ) = { f, g };
void ( **p_func )( void ) = funcs;
( *p_func++ )();
p_func[0]();
}
Hello Broman
请注意,在这些调用中
( *p_func++ )();
p_func[0]();
( *p_func++ )
是一种基本表达式(Primary Expression),而表达式 p_func[0]
则是后缀表达式(Postfix Expression)(参见上文对后缀表达式的部分定义)。
(*p)()
和(*p)
都是后缀表达式,对于新手来说可能会有些困惑。当谈论函数调用时,“后缀表达式”一词通常指的是函数调用运算符之前的表达式。 - M.M没有标识符时(将标识符作为函数调用。如果括号左边没有标识符或完整表达式,则没有调用。
当我第一次学习c语言时,我遇到了相反的问题。我弄不清为什么clrscr;
不能清除屏幕。(它是一个求值为指向clrscr
的指针的表达式,但没有任何作用)。
实际上,您可以拥有函数指针类型的表达式,并且这些表达式可以使用()进行调用,语法在两者之间完全没有歧义。因此,clrscr();
是函数调用,(clrscr)()
也是函数调用。在到达函数指针时,我们也可以执行resolve_function()()
。操作始终是在表达式后面的(,而不是在运算符后面。如果是在运算符后面,它必须是分组括号。
"最初的回答"翻译成英文是"Original Answer"
(
参数表达式列表)
”,其中 参数表达式列表 是可选的。后缀表达式 不需要是标识符。它可以是指向函数的指针,甚至是返回指向函数的指针的函数调用。 - Eric Postpischil
x = a * (b+c)-(d*e)
是一个表达式,而不是语句。在这里,(
不是一个运算符。术语“括号运算符”是指()
作为运算符的情况。同样,在int *p = 0;
中,*
和=
不是运算符,即使相同的符号在不同的上下文中用作运算符。 - M.M