Frage

Ich mag eine Min- und Max-Methoden in einer Utils-Klasse definieren.

@interface Utils

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

@end

Aber ich will nicht benannte Parameter haben. Es wäre eine zu schwere Notation sein. Ich wollte die C-Stil-Definition verwenden. Aber dann [Utils min(a, b)] als ein Anruf nicht funktioniert. Was ist mein Problem?

Vielen Dank im Voraus für jede Hilfe

War es hilfreich?

Lösung

Da Sie nicht die OS X-Implementierung von Objective-C verwenden, können Sie keinen Zugriff auf die vordefinierten MIN und MAX-Makros haben.

Sie können diese definieren sich selbst als

#define MIN(a,b)    ((a) < (b) ? (a) : (b))
#define MAX(a,b)    ((a) > (b) ? (a) : (b))

Es ist wahrscheinlich eine bessere Art und Weise, sie zu definieren, aber diese werden die einfachen Makros für Ihren Gebrauch erstellen. Sie können sie in allen gängigen .h-Datei hinzufügen, dass Ihre Klassen normalerweise Aktie.

Andere Tipps

Es ist bereits als Makro definiert.

MIN(a, b)

MAX(a, b)

Sie brauchen nicht diese hier neu zu definieren.

Es ist ein ernstes Problem mit der Lösung von Brandon Bodnár geschrieben (die zum Zeitpunkt des Schreibens dieses Artikels als gültige Lösung markiert ist).

Ausgabe hier beschrieben: http: / /gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html Und die (gültig & secure) Lösung es: http: / /gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

Überzeugen Sie sich selbst:

#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;
}

Konsolenprotokoll:

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.

So nie die naive Implementierung verwenden , wie oben in dem Code gesehen (und wie von Brandon Bodnár, sorry Kumpel vorgeschlagen;).), Wenn Sie schlimmsten Fälle wie diese vermeiden wollen

Dies ist wahrscheinlich keine gute Idee, für diese spezielle Anwendung, aber es ist möglich Objective-C-Methoden mit den Parametern „ohne Namen“ zu schreiben, oder besser gesagt mit der Länge Null-Name:

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

(Der Wähler wäre @selector(min::).)

Objective-C-Klasse Methoden Parameter verwenden genannt, period. Das ist einfach so, wie es ist.

Warum macht es keine globale, freie Funktion? Sie sollten keine Utils-Klasse für diese Art der Sache müssen.

Wenn Sie nicht über den globalen Namensraum Krempel möchten, können Sie Objective-C ++ (benennen Sie alle .m-Dateien zu .mm) verwenden und sie in einem Namensraum.

In einer Vorlagendatei namens "XXIntegerMath.h" fallen diese ...

#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;
}

Dann in Ihrer Objective-C-Klasse ...

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

Es leidet nicht unter den von Regexident beschriebenen Problemen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top