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)
これらを再定義する必要はありません。
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によって提案されたように、ごめんなさい;))。
Objective-cのOSX実装を使用していないため、事前定義されたMINおよびMAXマクロにアクセスできない場合があります。
これらは自分で次のように定義できます
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
それらを定義するためのより良い方法はおそらくありますが、これらはあなたが使用するための単純なマクロを作成します。クラスが通常共有する一般的な.hファイルにそれらを追加できます。
これは、この特定のアプリケーションにとってはおそらく良い考えではありませんが、「名前なし」のパラメーターを使用して、または長さゼロの名前を使用して、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によって説明された問題に悩まされることはありません。
これは、2つ以上の入力を許可するmulti-maxおよびmulti-min用に作成したマクロです。
float a = MMAX(1,2,9.33,2.5); //a = 9.33
内部メカニズムはlongdoubleを使用し、使用している変数に出力をキャストするだけです。__VA_ARGS__
typeofを使用した解決策を希望しますが、引数ごとにそれを行う方法を理解できませんでした。おそらく、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;\
})