++i 和 i+1 传递给函数,在 C++ 中给出不同的结果
++i and i+1 passed to function giving different results in c++
#include <stdio.h>
int noOfTriplet(int arr[], int n, int product, int count, int m){
if(count == 3 && product == m) return 1;
else if(count == 3 || n==0) return 0;
// using count+1 here gives answer 3 while passing ++count gives answer 1 why
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m) + noOfTriplet(arr, n-1, product, count, m);
}
int main(){
int arr[] = { 1, 4, 6, 2, 3, 8};
int n = 6;
int product = 1;
int count = 0;
int m = 24;
printf("%d\n", noOfTriplet(arr, n, product, count, m));
}
在上面的代码中,传递 count +1 时答案是 3,但是当我写 ++count 时,答案变成 1。
这不应该像这样。因为 count +1 和 ++count 是等价的。
在函数 noOfTriplet() 的 return 语句中,您在 2 个递归调用中使用 count
变量,将它们的结果相加如下:
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m)
+
noOfTriplet(arr, n-1, product, count, m);
首先,由于 +
运算符,您不能假设首先进行哪些递归调用,这取决于编译器。
接下来,你应该意识到count + 1
不会改变参数count
的实际值,而++count
肯定会改变。
在
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m) + noOfTriplet(arr, n-1, product, count, m);
您正在使用 count
两次。当您更改为
return noOfTriplet(arr, n-1, product*arr[n-1], ++count, m) + noOfTriplet(arr, n-1, product, count, m);
然后编译器可能会首先评估 noOfTriplet(arr, n-1, product*arr[n-1], ++count, m)
,增加 count
的副作用,然后使用已经增加的 count
评估 noOfTriplet(arr, n-1, product, count, m)
。因此结果不同。
由于未定义求值顺序(是的,这些规则在 C++17 中有所改变,但尽管如此)你不应该依赖它并保留你当前拥有的版本 count + 1
和 count
.
表达式不一样,operator ++
改变变量值,count + 1
不改变,它计算表达式并使用它的结果。
此外,表达式:
return noOfTriplet(arr, n-1, product*arr[n-1], ++count, m) +
noOfTriplet(arr, n-1, product, count, m);
未排序,因此导致 undefined/unspecified 行为。
Order of evaluation of any part of any expression, including order of evaluation of function arguments is unspecified. The compiler can evaluate operands and other subexpressions in any order, and may choose another order when the same expression is evaluated again.
示例:
1) If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2) If a side effect on a scalar object is unsequenced relative to a value computation using the value of the same scalar object, the behavior is undefined.
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior
#include <stdio.h>
int noOfTriplet(int arr[], int n, int product, int count, int m){
if(count == 3 && product == m) return 1;
else if(count == 3 || n==0) return 0;
// using count+1 here gives answer 3 while passing ++count gives answer 1 why
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m) + noOfTriplet(arr, n-1, product, count, m);
}
int main(){
int arr[] = { 1, 4, 6, 2, 3, 8};
int n = 6;
int product = 1;
int count = 0;
int m = 24;
printf("%d\n", noOfTriplet(arr, n, product, count, m));
}
在上面的代码中,传递 count +1 时答案是 3,但是当我写 ++count 时,答案变成 1。 这不应该像这样。因为 count +1 和 ++count 是等价的。
在函数 noOfTriplet() 的 return 语句中,您在 2 个递归调用中使用 count
变量,将它们的结果相加如下:
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m)
+
noOfTriplet(arr, n-1, product, count, m);
首先,由于 +
运算符,您不能假设首先进行哪些递归调用,这取决于编译器。
接下来,你应该意识到count + 1
不会改变参数count
的实际值,而++count
肯定会改变。
在
return noOfTriplet(arr, n-1, product*arr[n-1], count + 1, m) + noOfTriplet(arr, n-1, product, count, m);
您正在使用 count
两次。当您更改为
return noOfTriplet(arr, n-1, product*arr[n-1], ++count, m) + noOfTriplet(arr, n-1, product, count, m);
然后编译器可能会首先评估 noOfTriplet(arr, n-1, product*arr[n-1], ++count, m)
,增加 count
的副作用,然后使用已经增加的 count
评估 noOfTriplet(arr, n-1, product, count, m)
。因此结果不同。
由于未定义求值顺序(是的,这些规则在 C++17 中有所改变,但尽管如此)你不应该依赖它并保留你当前拥有的版本 count + 1
和 count
.
表达式不一样,operator ++
改变变量值,count + 1
不改变,它计算表达式并使用它的结果。
此外,表达式:
return noOfTriplet(arr, n-1, product*arr[n-1], ++count, m) +
noOfTriplet(arr, n-1, product, count, m);
未排序,因此导致 undefined/unspecified 行为。
Order of evaluation of any part of any expression, including order of evaluation of function arguments is unspecified. The compiler can evaluate operands and other subexpressions in any order, and may choose another order when the same expression is evaluated again.
示例:
1) If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2) If a side effect on a scalar object is unsequenced relative to a value computation using the value of the same scalar object, the behavior is undefined.
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior