C foo(x+;+;,y)::x是否总是在作为参数发送后递增?

C foo(x+;+;,y)::x是否总是在作为参数发送后递增?,c,increment,function-call,C,Increment,Function Call,涉及x++的表达式的增量是否总是在要复制到函数的变量之后进行 电话: foo(x++, y); 职能: int foo(int x, int y) { return x*y; } 对于所有编译器来说,这是一种未定义的行为吗?让我们看看这里的官方描述,以获得更深入的理解 对于后缀运算符,引用第§6.5.2.3章中的C11 后缀++运算符的结果是操作数的值。作为副作用 操作数对象的值递增(即,适当类型的值1为 添加到它)。[…]结果的值计算顺序在 更新操作数的存储值 关于函数调用,第§6.

涉及
x++
的表达式的增量是否总是在要复制到函数的变量之后进行

电话:

foo(x++, y);
职能:

int foo(int x, int y)
{
   return x*y;
}

对于所有编译器来说,这是一种未定义的行为吗?

让我们看看这里的官方描述,以获得更深入的理解

对于后缀运算符,引用第§6.5.2.3章中的
C11

后缀
++
运算符的结果是操作数的值。作为副作用 操作数对象的值递增(即,适当类型的值1为 添加到它)。[…]结果的值计算顺序在 更新操作数的存储值

关于函数调用,第§6.5.2.3章

在函数指示符和实际值的评估之后有一个序列点 参数,但在实际调用之前。调用函数中的每个求值(包括 其他函数调用)在 被调用函数体的执行顺序不确定 被调用函数的执行

因此,根据上面的描述,您的代码中没有任何问题,如上所示

传递
x
的旧值,然后增加该值

但是,请注意第二个报价的最后一部分,您需要保持代码的完整性。例如,您需要确保在没有序列点的情况下,值不会发生变化。差不多

 foo(x++, x++, y);

将是一个问题,因为您试图多次更改同一变量(
x
)。

让我们看看这里的官方描述,以获得更深入的理解

对于后缀运算符,引用第§6.5.2.3章中的
C11

后缀
++
运算符的结果是操作数的值。作为副作用 操作数对象的值递增(即,适当类型的值1为 添加到它)。[…]结果的值计算顺序在 更新操作数的存储值

关于函数调用,第§6.5.2.3章

在函数指示符和实际值的评估之后有一个序列点 参数,但在实际调用之前。调用函数中的每个求值(包括 其他函数调用)在 被调用函数体的执行顺序不确定 被调用函数的执行

因此,根据上面的描述,您的代码中没有任何问题,如上所示

传递
x
的旧值,然后增加该值

但是,请注意第二个报价的最后一部分,您需要保持代码的完整性。例如,您需要确保在没有序列点的情况下,值不会发生变化。差不多

 foo(x++, x++, y);

将是一个问题,因为您试图多次更改同一变量(
x
)。

每当使用后增量时,变量的原始值将发送到函数。然后,x的值将递增。

每当使用后递增时,变量的原始值将发送到函数。然后,x的值将增加。

考虑以下程序

#include <stdio.h>

int x;

void foo(int x1 )
{
    extern int x;

    printf( "x1 = %d\n", x1 );
    printf( "x = %d\n", x );
}

int main(void) 
{
    foo( x++ );

    return 0;
}
因此,正如所见,表达式
x++
的值是递增之前的操作数值

x1 = 0
但是,副作用是在函数获得控制之前应用的

x = 1

程序结构良好,没有未定义的行为

考虑以下程序

#include <stdio.h>

int x;

void foo(int x1 )
{
    extern int x;

    printf( "x1 = %d\n", x1 );
    printf( "x = %d\n", x );
}

int main(void) 
{
    foo( x++ );

    return 0;
}
因此,正如所见,表达式
x++
的值是递增之前的操作数值

x1 = 0
但是,副作用是在函数获得控制之前应用的

x = 1

程序结构良好,没有未定义的行为

在您显示的代码中没有未定义的内容,并且您可以随时替换调用
foo(x++,y)有两行:
foo(x,y);x++为清晰起见。将尽可能多的操作塞进一行不会获得奖励积分。Bug会因此获得奖励。不可以,但未定义。但那是另一种蠕虫。最后(
x*x++
)你应该读一读。作为程序问题,某些东西是否未定义并不取决于编译器;定义(即语义规则)来自标准。在您显示的代码中没有未定义的内容。您可以随时替换调用
foo(x++,y)有两行:
foo(x,y);x++为清晰起见。将尽可能多的操作塞进一行不会获得奖励积分。Bug会因此获得奖励。不可以,但未定义。但那是另一种蠕虫。最后(
x*x++
)你应该读一读。作为程序问题,某些东西是否未定义并不取决于编译器;定义(即语义规则)来自标准。