简体   繁体   English

C /函数调用中的序列点

[英]Sequence points in C / function calls

I'm just learning some C, or rather, getting a sense of some of the arcane details. 我只是学习一些C,或者更确切地说,了解一些神秘的细节。 And I was using VTC advanced C programming in which I found that the sequence points are : 我正在使用VTC高级C编程,其中我发现序列点是:

  • Semicolon 分号
  • Comma 逗号
  • Logical OR / AND 逻辑OR / AND
  • Ternary operator 三元运算符
  • Function calls (Any expression used as an argument to a function call is finalized the call is made) 函数调用(用作函数调用的参数的任何表达式在调用完成时完成)

are all these correct ?. 这些都是正确的吗? Regarding the last one I tried: 关于我试过的最后一个:

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

int main(void) 
{

  int i = 0;

  foo(i++);

  return 0;

}

And it didnt print 1, which according to what the VTC's guy said and if I undertood correctly, it should, right ?. 它没有打印1,根据VTC的人所说的,如果我说得对,它应该,对吧? Also, are these parens in the function call the same as the grouping parens ? 此外,函数中的这些parens是否与分组parens相同? (I mean, their precedence). (我的意思是,他们的优先权)。 Maybe it is because parens have higher precedence than ++ but I've also tried foo((i++)); 也许是因为parens的优先级高于++,但我也尝试过foo((i ++)); and got the same result. 并得到了相同的结果。 Only doing foo(i = i + 1); 只做foo(i = i + 1); yielded 1. 屈服1。

Thank you in advance. 先感谢您。 Please consider that I'm from South America so if I wasnt clear or nothing makes sense please, oh please, tell me. 请考虑我来自南美洲所以,如果我不清楚或没有任何意义,请,哦,拜托,告诉我。

Warmest regards, Sebastian. 最热烈的问候,塞巴斯蒂安。

Your code is working like it should and it has nothing to do with sequence points. 你的代码工作正常,它与序列点无关。 The point is that the postfix ++ operator returns the non-incremented value (but increments the variable by 1 nonetheless). 关键是postfix ++运算符返回非递增的值 (但仍然将变量递增1)。

Basically: 基本上:

  • i++ – Increment i by one and return the previous value i++ - 将i递增1并返回先前的值
  • ++i – Increment i by one and return the value after the increment ++i -增量i由一个和增量后返回值

The position of the operator gives a slight hint for its semantics. 运算符的位置略微暗示了它的语义。

Sequence means i++ is evaluted before foo is invoked. 顺序意味着在调用foo之前评估i++

Consider this case ( I am not printing bar ! ): 考虑这种情况( 我不打印bar ):

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

i = 1 must be printed. 必须打印i = 1

C implements pass-by-value semantics. C实现了按值传递语义。 First i ++ is evaluated, and the value is kept, then i is modified (this may happen any time between the evaluation and the next sequence point), then the function is entered with the backup value as the argument. 首先评估i ++ ,并保留该值,然后修改i (这可能在评估和下一个序列点之间的任何时间发生),然后以备份值作为参数输入函数。

The value passed into a function is always the same as the one you would see if using the argument expression in any other way. 传递给函数的值总是与以任何其他方式使用参数表达式时看到的值相同。 Other behavior would be fairly surprising, and make it difficult to refactor common subexpressions into functions. 其他行为相当令人惊讶,并且难以将常见的子表达式重构为函数。

When you do something like: int i = 0, j; 当你做类似的事情:int i = 0,j;

j = i++; j = i ++;

the value of i is used first and then incremented. 首先使用i的值然后递增。 hence in your case the values of i which is 0 is used (hence passed to your function foo) and then incremented. 因此,在您的情况下,使用i的值为0(因此传递给您的函数foo),然后递增。 the incremented values of i (now 1) will be available only for main as it is its local variable. i(现在为1)的递增值仅适用于main,因为它是本地变量。

If you want to print 1 the do call foo this way: 如果你想打印1,请用这种方式调用foo:

foo(++i); FOO(++ⅰ);

this will print 1. Rest you know, why! 这将打印1.休息你知道,为什么!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM