C /函数调用中的序列点

时间:2013-07-04 06:00:57

标签: c

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

  • 分号
  • 逗号
  • 逻辑OR / AND
  • 三元运营商
  • 函数调用(任何用作函数调用参数的表达式都是在调用时完成的)

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

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

int main(void) 
{

  int i = 0;

  foo(i++);

  return 0;

}

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

提前谢谢你。请考虑我来自南美洲所以如果我不清楚或没有任何意义,请哦,拜托,告诉我。

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

4 个答案:

答案 0 :(得分:10)

你的代码工作正常,它与序列点无关。关键是后缀++运算符返回非递增值(但仍将变量递增1)。

基本上:

  • i++ - 将i递增1并返回之前的值
  • ++i - 将i递增1并在增量后返回值

运算符的位置略微提示其语义。

答案 1 :(得分: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必须打印出来。

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

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

j = i ++;

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

如果你想打印1,请以这种方式调用foo:

FOO(++ I);

这将打印1.休息你知道,为什么!