函数参数中前增量和后增量的运算顺序?

发布于 2024-09-04 04:21:17 字数 370 浏览 8 评论 0原文

我有一些 C 代码:

main()
{
    int a=1;
    void xyz(int,int);

    xyz(++a,a++);     //which Unary Operator is executed first, ++a or a++?

    printf("%d",a);
}
void xyz(int x,int y)
{
    printf("\n%d %d",x,y);
}

函数 xyz 有两个传入的参数,++aa++。有人可以解释操作顺序来解释结果吗?

上面的代码根据使用的编译器打印“3 13”或“2 23”。

I have some C code:

main()
{
    int a=1;
    void xyz(int,int);

    xyz(++a,a++);     //which Unary Operator is executed first, ++a or a++?

    printf("%d",a);
}
void xyz(int x,int y)
{
    printf("\n%d %d",x,y);
}

The function xyz has two parameters passed in, ++a and a++. Can someone explain the sequence of operations to explain the result?

The above code prints "3 13" or "2 23" depending on which compiler is used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅黛梨妆こ 2024-09-11 04:21:18

引用 Kernighan &里奇,第 2.12 章:

函数参数的顺序
评估未指定,因此
声明

printf("%d %d\n", ++n, power(2, n)); /* 错误的 */

可以产生不同的结果
不同的编译器,取决于
n 是否在幂前递增
被称为。解决方案当然是

<前><代码>++n;
printf("%d %d\n", n, 幂(2, n));

函数调用、嵌套赋值
语句,以及增量和
自减运算符导致``side
效果'' - 一些变量被改变
作为评估的副产品
一个表达。在任何表达方式中
涉及副作用,可能有
对顺序的微妙依赖
哪些变量参与
表达式已更新。一不高兴
情况由语句所代表

a[i] = i++;

问题是下标是否
是 i 的旧值或新值。
编译器可以将其解释为
不同的方式,产生不同的
答案取决于他们
解释。标准
故意留下大多数这样的事情
未指定。当出现副作用时
(分配给变量)发生
在表达式中留下
编译器的自由裁量权,因为
最佳顺序很大程度上取决于机器
建筑学。 (该标准规定
指定所有副作用
参数在 a 之前生效
函数被调用,但不会
帮助调用上面的 printf 。)
道德是编写代码
取决于评估顺序是
任何方面的不良编程习惯
语言。自然是有必要的
知道要避免什么事情,但如果
你不知道它们是怎么做的
各种机器,你不会被诱惑
利用特定的优势
实施。

Quoting Kernighan & Ritchie, Chapter 2.12:

The order in which function arguments
are evaluated is not specified, so the
statement

printf("%d %d\n", ++n, power(2, n)); /* WRONG */

can produce different results with
different compilers, depending on
whether n is incremented before power
is called. The solution, of course, is
to write

++n;
printf("%d %d\n", n, power(2, n));

Function calls, nested assignment
statements, and increment and
decrement operators cause ``side
effects'' - some variable is changed
as a by-product of the evaluation of
an expression. In any expression
involving side effects, there can be
subtle dependencies on the order in
which variables taking part in the
expression are updated. One unhappy
situation is typified by the statement

a[i] = i++;

The question is whether the subscript
is the old value of i or the new.
Compilers can interpret this in
different ways, and generate different
answers depending on their
interpretation. The standard
intentionally leaves most such matters
unspecified. When side effects
(assignment to variables) take place
within an expression is left to the
discretion of the compiler, since the
best order depends strongly on machine
architecture. (The standard does
specify that all side effects on
arguments take effect before a
function is called, but that would not
help in the call to printf above.) The
moral is that writing code that
depends on order of evaluation is a
bad programming practice in any
language. Naturally, it is necessary
to know what things to avoid, but if
you don't know how they are done on
various machines, you won't be tempted
to take advantage of a particular
implementation.

月下客 2024-09-11 04:21:18

函数的一元运算符评估序列:

#include <stdio.h>

void xyz(int x, int y) {
    printf("x:%d y:%d ", x, y);
}

main() {
    int a;
    a=1;    xyz(++a, a);        printf("a:%d\n", a);
    a=1;    xyz(a, a++);        printf("a:%d\n", a);
    a=1;    xyz(++a, a++);      printf("a:%d\n", a);
}

将输出

x:2 y:2 a:2
x:2 y:1 a:2
x:3 y:1 a:3

在我的系统上。这表明首先计算函数的第二个参数。您不应依赖函数参数的求值顺序。它没有定义,所以在不同的系统上它会有所不同。

不过,找到这种行为的好例子还是不错的。

Unary Operator evaluation sequence for a function:

#include <stdio.h>

void xyz(int x, int y) {
    printf("x:%d y:%d ", x, y);
}

main() {
    int a;
    a=1;    xyz(++a, a);        printf("a:%d\n", a);
    a=1;    xyz(a, a++);        printf("a:%d\n", a);
    a=1;    xyz(++a, a++);      printf("a:%d\n", a);
}

will output

x:2 y:2 a:2
x:2 y:1 a:2
x:3 y:1 a:3

On my system. This indicates that the second parameter of the function is being evaluated first. You should not rely on order of evaluation of function parameters. It is not defined, so it will be different on different systems.

Good job on finding a nifty example of this behavior, though.

听风吹 2024-09-11 04:21:18

对于一元运算符,有前自增(++i)和后自增(i++)。对于预递增,要递增的值将在操作之前添加。例如:

#include <iostream>
using namespace std;

void main()
{
    int i = 0;
    cout << ++i;
}

在这种情况下,输出将为 1。在任何其他操作之前,变量“i”会增加值 1,即“cout <<”。 ++我'。

现在,如果我们在同一个函数中进行后置自增:

#include <iostream>
using namespace std;

void main()
{
    int i = 0;
    cout << i++;
}

输出将仅为 0。这是因为增量会在操作之后发生。但既然您想知道如何将它们作为参数传递,那么它就会这样:

#include <iostream>
using namespace std;
// Function Prototypes
void PrintNumbers(int, int);

void main()
{
    int a = 0, b = 0;
    PrintNumbers(++a, b++);
}

void PrintNumbers(int a, int b)
{
    cout << "First number: " << a << endl;
    cout << "Second number: " << b << endl;
}

当将这些变量作为参数传递时,输出将是:

 First number: 1
 Second number: 0

我希望这有帮助!

For uniary operators, there is the pre-increment (++i) and post-increment (i++). For pre-increment, the value to be incremented will added before an operation. For example:

#include <iostream>
using namespace std;

void main()
{
    int i = 0;
    cout << ++i;
}

In this case, the output would be 1. The variable 'i' was incremented by the value of 1 before any other operations i.e. 'cout << ++i'.

Now, if we did the post-increment in the same function:

#include <iostream>
using namespace std;

void main()
{
    int i = 0;
    cout << i++;
}

The output would only be 0. This is because the increment would happen after the operation. But since you want to know about passing them in as parameters, this is how it will go:

#include <iostream>
using namespace std;
// Function Prototypes
void PrintNumbers(int, int);

void main()
{
    int a = 0, b = 0;
    PrintNumbers(++a, b++);
}

void PrintNumbers(int a, int b)
{
    cout << "First number: " << a << endl;
    cout << "Second number: " << b << endl;
}

When passing in those variables as parameters, the output would be:

 First number: 1
 Second number: 0

I hope this helps!!

你是暖光i 2024-09-11 04:21:17

好吧,您的示例代码需要考虑两件事:

  1. 函数参数的求值顺序未指定,因此无论是 ++a 还是 a++ 首先求值都是实现 -依赖。
  2. 多次修改 a 的值而修改之间没有序列点会导致未定义的行为。因此,您的代码的结果是未定义的。

如果我们简化您的代码并删除未指定和未定义的行为,那么我们可以回答以下问题:

void xyz(int x) { }

int a = 1;
xyz(a++); // 1 is passed to xyz, then a is incremented to be 2

int a = 1;
xyz(++a); // a is incremented to be 2, then that 2 is passed to xyz

Well, there are two things to consider with your example code:

  1. The order of evaluation of function arguments is unspecified, so whether ++a or a++ is evaluated first is implementation-dependent.
  2. Modifying the value of a more than once without a sequence point in between the modifications results in undefined behavior. So, the results of your code are undefined.

If we simplify your code and remove the unspecified and undefined behavior, then we can answer the question:

void xyz(int x) { }

int a = 1;
xyz(a++); // 1 is passed to xyz, then a is incremented to be 2

int a = 1;
xyz(++a); // a is incremented to be 2, then that 2 is passed to xyz
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文