我想在 Utils 类中定义一个 min 和 max 方法。
@interface Utils
int min(int a, int b);
int max(int a, int b);
@end
但我不想命名参数。这将是一个太重的符号。我想使用 C 风格的定义。但是[Utils min(a, b)]
作为一个电话不起作用。我的问题是什么?
提前感谢您的帮助
我想在 Utils 类中定义一个 min 和 max 方法。
@interface Utils
int min(int a, int b);
int max(int a, int b);
@end
但我不想命名参数。这将是一个太重的符号。我想使用 C 风格的定义。但是[Utils min(a, b)]
作为一个电话不起作用。我的问题是什么?
提前感谢您的帮助
它已经被定义为宏。
MIN(a, b)
MAX(a, b)
你不需要重新定义这些。
Brandon Bodnár 发布的解决方案存在严重问题(在撰写本文时已被标记为有效解决方案)。
此处描述的问题:http: //gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html 以及(有效且安全的)解决方案:http://gcc.gnu。 org/onlinedocs/gcc-3.4.6/gcc/Typeof.html
自己检查一下:
#include <stdio.h>
#define NAIVE_MAX(a,b) (a > b ? a : b)
#define NAIVE_MIN(a,b) (a < b ? a : b)
#if !defined MAX
#define MAX(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a > __b ? __a : __b; })
#endif
#if !defined MIN
#define MIN(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a < __b ? __a : __b; })
#endif
int main (int argc, const char * argv[]) {
int a = 3;
int b = 5;
#pragma mark NON-FATAL CASES:
printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b));
printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b));
printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b));
printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b));
printf("\nEverything fine so far...\n\n");
#pragma mark FATAL CASES:
//cache:
int _a = a;
int _b = b;
printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++));
//reset:
a = _a;
b = _b;
printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++));
//reset:
a = _a;
b = _b;
printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b));
//reset:
a = _a;
b = _b;
printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b));
printf("\nOuch, this doesn't look right at all!\n\n");
#pragma mark NON-FATAL CASES:
//reset:
a = _a;
b = _b;
printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++));
//reset:
a = _a;
b = _b;
printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++));
//reset:
a = _a;
b = _b;
printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b));
//reset:
a = _a;
b = _b;
printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b));
printf("\nAh, much better now.\n\n");
return 0;
}
控制台日志:
NAIVE_MAX(3, 5) => 5
NAIVE_MIN(3, 5) => 3
MAX(3, 5) => 5
MIN(3, 5) => 3
Everything fine so far...
NAIVE_MAX(3++, 5++) => 6
NAIVE_MIN(3++, 5++) => 4
NAIVE_MAX(++3, ++5) => 7
NAIVE_MIN(++3, ++5) => 5
Ouch, this doesn't look right at all!
MAX(3++, 5++) => 5
MIN(3++, 5++) => 3
MAX(++3, ++5) => 6
MIN(++3, ++5) => 4
Ah, much better now.
因此,如果您想避免像这样的最坏情况,永远不要使用上面代码中看到的幼稚实现(以及 Brandon Bodnár 所建议的,对不起,伙计;))。
Since you aren't using the OS X Implementation of objective-c, you may not have access to the predefined MIN and MAX macros.
You can define these yourself as
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
There is probably a better way to define them, but these will create the simple macros for your use. You can add them into any common .h file that your classes normally share.
对于这个特定的应用程序,这可能不是一个好主意,但是可以使用“没有名称”的参数编写 Objective-C 方法,或者使用零长度名称:
+ min:(int)a :(int)b;
...
[Utils min:a :b]
(选择器将是@selector(min::)
。)
Objective-C 类方法使用命名参数,句点。就是那样子。
为什么不让它成为一个全球性的、免费的功能呢?对于这种事情,您不应该需要 Utils 类。
如果您不想弄乱全局命名空间,可以使用 Objective-C++(将所有 .m 文件重命名为 .mm)并将其放在命名空间中。
在名为“XXIntegerMath.h”的模板文件中删除这个...
#import <Foundation/Foundation.h>
static inline NSInteger imax(NSInteger a, NSInteger b) {
return a > b ? a : b;
}
static inline NSInteger imin(NSInteger a, NSInteger b) {
return a < b ? a : b;
}
然后在你的objective-c类中......
#import "XXIntegerMath.h"
NSInteger minValue = imin(someValue, someOtherValue);
它不受 Regexident 所描述的问题的影响。
这是我为 multi-max 和 multi-min 创建的宏,它允许超过 2 个输入。
float a = MMAX(1,2,9.33,2.5); //a = 9.33
内部机制使用 long double ,您只需将输出转换为您正在使用的任何变量。我更喜欢使用 typeof 的解决方案,但无法根据每个参数弄清楚如何做到这一点__VA_ARGS__
,也许比我更精通 C 语言的人可以弄清楚并发表评论?无论如何,这是宏定义:
#define MMAX(...) ({\
long double __inputs[(sizeof((long double[]){__VA_ARGS__})/sizeof(long double))] = {__VA_ARGS__};\
long double __maxValue = __inputs[0];\
for (int __i = 0; __i < (sizeof((long double[]){__VA_ARGS__})/sizeof(long double)); ++__i) {\
long double __inputValue = __inputs[__i];\
__maxValue = __maxValue>__inputValue?__maxValue:__inputValue;\
}\
__maxValue;\
})
#define MMIN(...) ({\
long double __inputs[(sizeof((long double[]){__VA_ARGS__})/sizeof(long double))] = {__VA_ARGS__};\
long double __minValue = __inputs[0];\
for (int __i = 0; __i < (sizeof((long double[]){__VA_ARGS__})/sizeof(long double)); ++__i) {\
long double __inputValue = __inputs[__i];\
__minValue = __minValue<__inputValue?__minValue:__inputValue;\
}\
__minValue;\
})