我想在Utils类中定义min和max方法。
@interface Utils
int min(int a, int b);
int max(int a, int b);
@end
但我不想要命名参数。这将是一个太沉重的表示法。我想使用C风格的定义。但是[Utils min(a, b)]
作为电话不起作用。我的问题是什么?
提前感谢您提供任何帮助
答案 0 :(得分:62)
它已被定义为宏。
MIN(a, b)
MAX(a, b)
你不需要重新定义这些。
答案 1 :(得分:29)
BrandonBodná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.
所以永远不会使用上面的代码中看到的天真实现(并且正如BrandonBodnár所建议的,抱歉伙伴;))如果你想避免像这样的最坏情况。
答案 2 :(得分:18)
由于您没有使用objective-c的OS X实现,因此您可能无法访问预定义的MIN和MAX宏。
您可以将自己定义为
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
可能有更好的方法来定义它们,但这些将创建供您使用的简单宏。您可以将它们添加到您的类通常共享的任何常见.h文件中。
答案 3 :(得分:6)
对于这个特定的应用程序来说,这可能不是一个好主意,但是可能使用参数“无名称”编写Objective-C方法,或者更确切地说使用零长度名称:
+ min:(int)a :(int)b;
...
[Utils min:a :b]
(选择器为@selector(min::)
。)
答案 4 :(得分:1)
Objective-C类方法使用命名参数,句点。这就是它的方式。
为什么不把它变成一个全局的免费功能呢?你不应该为这类事情使用Utils类。
如果您不想混淆全局命名空间,可以使用Objective-C ++(将所有.m文件重命名为.mm)并将其放在命名空间中。
答案 5 :(得分:0)
在名为“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;
}
然后在你的目标-c班......
#import "XXIntegerMath.h"
NSInteger minValue = imin(someValue, someOtherValue);
它没有遭受Regexident描述的问题。
答案 6 :(得分:0)
这是我为multi-max和multi-min创建的宏,它允许两个以上的输入。
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;\
})