10

我有一些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”。

4

4 回答 4

28

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

  1. 函数参数的求值顺序未指定,因此是否++aa++求值取决于实现。
  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
于 2010-06-07T13:12:23.853 回答
9

引用 Kernighan & Ritchie,第 2.12 章:

未指定评估函数参数的顺序,因此语句

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

可以使用不同的编译器产生不同的结果,具体取决于 n 在调用 power 之前是否递增。解决方案当然是写

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

函数调用、嵌套赋值语句以及递增和递减运算符会导致“副作用”——某些变量作为表达式求值的副产品而改变。在任何涉及副作用的表达式中,对参与表达式的变量的更新顺序可能存在细微的依赖关系。陈述代表了一种不愉快的情况

a[i] = i++;

问题是下标是 i 的旧值还是新值。编译器可以用不同的方式解释这一点,并根据他们的解释产生不同的答案。该标准有意将大多数此类事项未指定。当表达式中发生副作用(分配给变量)时,由编译器自行决定,因为最佳顺序很大程度上取决于机器架构。(标准确实指定参数的所有副作用在调用函数之前生效,但这对上面对 printf 的调用没有帮助。)道德是编写依赖于评估顺序的代码是一种糟糕的编程习惯任何语言。当然,有必要知道要避免哪些事情,但如果你不知道

于 2010-06-07T13:20:22.393 回答
1

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

#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

在我的系统上。这表明函数的第二个参数首先被评估。您不应依赖函数参数的评估顺序。它没有定义,因此在不同的系统上会有所不同。

不过,很好地找到了这种行为的一个很好的例子。

于 2010-06-07T13:21:32.270 回答
-1

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

#include <iostream>
using namespace std;

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

在这种情况下,输出将是 1。变量“i”在任何其他操作(即“cout << ++i”)之前增加了 1 的值。

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

#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

我希望这有帮助!!

于 2013-10-18T14:51:30.763 回答