22

我想在 Utils 类中定义一个 min 和 max 方法。

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

但我不想命名参数。这将是一个太重的符号。我想使用 C 风格的定义。但是[Utils min(a, b)]作为一个电话不起作用。我的问题是什么?

提前感谢您的帮助

4

7 回答 7

65

它已经被定义为宏。

MIN(a, b)

MAX(a, b)

你不需要重新定义这些。

于 2010-01-23T23:23:24.237 回答
30

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 所建议的,对不起,伙计;))。

于 2010-06-21T12:32:58.313 回答
17

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.

于 2010-01-23T23:51:00.530 回答
7

对于这个特定的应用程序,这可能不是一个好主意,但是可以使用“没有名称”的参数编写 Objective-C 方法,或者使用零长度名称:

+ min:(int)a :(int)b;
...
[Utils min:a :b]

(选择器将是@selector(min::)。)

于 2010-01-24T00:18:35.690 回答
2

Objective-C 类方法使用命名参数,句点。就是那样子。

为什么不让它成为一个全球性的、免费的功能呢?对于这种事情,您不应该需要 Utils 类。

如果您不想弄乱全局命名空间,可以使用 Objective-C++(将所有 .m 文件重命名为 .mm)并将其放在命名空间中。

于 2010-01-23T23:22:24.957 回答
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;
}

然后在你的objective-c类中......

#import "XXIntegerMath.h"
NSInteger minValue = imin(someValue, someOtherValue);

它不受 Regexident 所描述的问题的影响。

于 2014-07-30T11:11:36.423 回答
0

这是我为 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;\
})
于 2020-04-04T04:35:51.090 回答