5

我只是在学习一些 C 语言,或者更确切地说,是对一些神秘的细节有所了解。我正在使用 VTC 高级 C 编程,其中我发现序列点是:

  • 分号
  • 逗号
  • 逻辑或/与
  • 三元运算符
  • 函数调用(任何用作函数调用参数的表达式都已完成调用)

这些都是正确的吗?关于我尝试的最后一个:

void foo (int bar) { printf("I received %d\n", bar); }

int main(void) 
{

  int i = 0;

  foo(i++);

  return 0;

}

它没有打印 1,根据 VTC 的人所说,如果我理解正确,它应该,对吧?此外,函数调用中的这些括号是否与分组括号相同?(我的意思是,他们的优先级)。也许是因为括号的优先级高于 ++ 但我也尝试过 foo((i++)); 并得到相同的结果。只做 foo(i = i + 1); 产生了 1。

先感谢您。请考虑我来自南美,所以如果我不清楚或没有任何意义,请告诉我。

最热烈的问候,塞巴斯蒂安。

4

4 回答 4

10

您的代码按应有的方式工作,与序列点无关。关键是后缀++运算符返回非递增值(但仍将变量递增 1)。

基本上:

  • i++i加一并返回前一个值
  • ++i–加一并i返回加后的值

运算符的位置稍微暗示了它的语义。

于 2013-07-04T06:02:53.353 回答
4

序列均值在被调用i++之前被评估。foo

考虑这种情况(我没有打印bar):

int i = 0;
void foo (int bar) { printf("i = %d\n", i); }
int main(void){
    foo(i++);
    return 0;
}

i = 1必须打印。

于 2013-07-04T06:06:53.640 回答
3

C 实现了按值传递的语义。首先i ++评估,并保留该值,然后i修改(这可能发生在评估和下一个序列点之间的任何时间),然后使用备份值作为参数输入函数。

传递给函数的值始终与以任何其他方式使用参数表达式时看到的值相同。其他行为会相当令人惊讶,并且难以将常见的子表达式重构为函数。

于 2013-07-04T06:03:35.843 回答
1

当您执行以下操作时: int i = 0, j;

j = i++;

首先使用 i 的值,然后递增。因此,在您的情况下,使用 0 的 i 值(因此传递给您的函数 foo)然后递增。i 的增量值(现在为 1)仅对 main 可用,因为它是它的局部变量。

如果您想以这种方式打印 1 do 调用 foo :

富(++i);

这将打印 1. 休息一下,为什么!

于 2013-07-04T09:17:03.713 回答