C++ 宏(最小最大)不能正常工作
C++ macro (min max) not working properly
为什么下面的代码不起作用?它打印 INT_MAX。但是如果我取消注释内部 for 循环中的两行,那么它工作正常(打印 2)。我不能这样组合两个宏?不确定是否需要进一步的细节...非常不言自明。
谢谢。
#include <iostream>
#include <limits.h>
using namespace std;
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
int main(int argc, char **argv)
{
int N = 100;
int *drop = new int[N+1];
drop[0] = 0; drop[1] = 1; drop[2] = 1;
for(int i=3; i<=N; i++)
{
drop[i] = INT_MAX;
for(int start=1; start<=i; start++)
{
drop[i] = min(drop[i], max(start, drop[i-start]+1));
//int x = max(start, drop[i-start]+1);
//drop[i] = min(drop[i], x);
}
}
cout<<drop[3]<<endl;
return 0;
}
将宏中的术语括起来:
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
事实上,这个:
drop[i] = min(drop[i], max(start, drop[i-start]+1));
扩展到这个(没有括号):
drop[i] < start > drop[i-start]+1 ? start: drop[i-start]+1 ? drop[i] : start > drop[i-start]+1 ? start: drop[i-start]+1;
这可能不会按照您想要的顺序进行评估。使用括号强制执行正确的操作顺序。
如评论中所述,如果宏参数被多次求值,则不应将宏与具有副作用的表达式一起使用。
C++ 已经在 <algorithm>
中定义了 std::min
和 std::max
。您可以将代码更改为纯 C++ 版本
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
int main(int argc, char ** argv) {
int N = 100;
int * drop = new int[N + 1];
drop[0] = 0;
drop[1] = drop[2] = 1;
for (int i = 3; i <= N; ++i) {
drop[i] = numeric_limits<int>::max(); // <limits>
for(int start = 1; start <= i; ++start)
drop[i] = min(drop[i], max(start, drop[i - start] + 1)); // <algorithm>
}
cout << drop[3] << endl;
return 0;
}
这不是一个答案,而是对所有开发人员的恳求:请不要那样使用宏。 C++ 为这些目的提供了模板函数。请记住,宏只是替换参数而不是预先评估它们。即使您像 samgak 解释的那样添加括号,这也只能解决一半的问题。考虑这样的代码:
int x = 5;
int y = max(++x, 0);
调用者会期望 x=6
和 y=6
之后;但是宏将扩展到
int y = (++x > 0)? ++x : 0;
导致 x=7
和 y=7
。
为什么下面的代码不起作用?它打印 INT_MAX。但是如果我取消注释内部 for 循环中的两行,那么它工作正常(打印 2)。我不能这样组合两个宏?不确定是否需要进一步的细节...非常不言自明。
谢谢。
#include <iostream>
#include <limits.h>
using namespace std;
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
int main(int argc, char **argv)
{
int N = 100;
int *drop = new int[N+1];
drop[0] = 0; drop[1] = 1; drop[2] = 1;
for(int i=3; i<=N; i++)
{
drop[i] = INT_MAX;
for(int start=1; start<=i; start++)
{
drop[i] = min(drop[i], max(start, drop[i-start]+1));
//int x = max(start, drop[i-start]+1);
//drop[i] = min(drop[i], x);
}
}
cout<<drop[3]<<endl;
return 0;
}
将宏中的术语括起来:
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
事实上,这个:
drop[i] = min(drop[i], max(start, drop[i-start]+1));
扩展到这个(没有括号):
drop[i] < start > drop[i-start]+1 ? start: drop[i-start]+1 ? drop[i] : start > drop[i-start]+1 ? start: drop[i-start]+1;
这可能不会按照您想要的顺序进行评估。使用括号强制执行正确的操作顺序。
如评论中所述,如果宏参数被多次求值,则不应将宏与具有副作用的表达式一起使用。
C++ 已经在 <algorithm>
中定义了 std::min
和 std::max
。您可以将代码更改为纯 C++ 版本
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
int main(int argc, char ** argv) {
int N = 100;
int * drop = new int[N + 1];
drop[0] = 0;
drop[1] = drop[2] = 1;
for (int i = 3; i <= N; ++i) {
drop[i] = numeric_limits<int>::max(); // <limits>
for(int start = 1; start <= i; ++start)
drop[i] = min(drop[i], max(start, drop[i - start] + 1)); // <algorithm>
}
cout << drop[3] << endl;
return 0;
}
这不是一个答案,而是对所有开发人员的恳求:请不要那样使用宏。 C++ 为这些目的提供了模板函数。请记住,宏只是替换参数而不是预先评估它们。即使您像 samgak 解释的那样添加括号,这也只能解决一半的问题。考虑这样的代码:
int x = 5;
int y = max(++x, 0);
调用者会期望 x=6
和 y=6
之后;但是宏将扩展到
int y = (++x > 0)? ++x : 0;
导致 x=7
和 y=7
。