为了克服前一个缺点,我已经制作了 。它不是成品,但你明白了: #define NUMELEM(arr)(sizeof(arr)/ sizeof *(arr)) 模板< int positive_or_negative> struct VerifyType { unsigned must_not_be_negative:positive_or_negative; / * Can'' t有负位字段* / }; #define VERIFY(compile_time_constant)\ (sizeof(VerifyType< \ (compile_time_constant)?1:-1 >)) #define ARRLEN(arr)((void)VERIFY(NUMELEM(arr)1),NUMELEM(arr)) #include< iostream> 使用std :: cout; int main() { int array [5]; int * p =数组; cout<< ARRLEN(阵列)<< ''\ n''; cout<< ARRLEN(p)<< \\\; / *编译器错误* / } 本质上,它只执行编译时断言以确保 NUMELEM (arr)大于1。当然,我们将有一些技术细节,例如 数组,其长度为1. 为什么不消除上述问题呢?那些 一般会是宏吗?使用矢量代替,它''知道'它的大小。 std :: vector< intv(10); v.push_back(0) ; std :: cout<< v.size()<< \\\; //打印11 -Mike > - Frederick Gotham Frederick Gotham发布: #define VERIFY(compile_time_constant)\ (sizeof(VerifyType< \ (compile_time_constant)?1:-1 >)) #define ARRLEN(arr)((void)VERIFY(NUMELEM(arr)1),NUMELEM(arr)) 我会重新定位void演员: #define VERIFY(compile_time_constant)\ ((void)sizeof(VerifyType< \ (compile_time_constant) )?1:-1 >)) #define ARRLEN(arr)(VERIFY(NUMELEM(arr) )1),NUMELEM(arr)) - Frederick Gotham Frederick Gotham发布: 我将重新定位void演员: 我在路上留下了一些必要的括号。我会重写 整件事: #define NUMELEM(arr)(sizeof(arr)/ sizeof *(arr)) 模板< int positive_or_negative> struct VerifyType { unsigned must_not_be_negative:positive_or_negative; / *不能有负位字段* / }; #define VERIFY(compile_time_constant)\ ( (void)sizeof(VerifyType< \ (compile_time_constant)?1:-1 >)) #define ARRLEN(arr)(VERIFY(NUMELEM((arr))1),NUMELEM((arr))) #include< iostream> 使用std :: cout; int main() { int array [ 5]; int * p =数组; cout<< ARRLEN(阵列)<< ''\ n''; cout<< ARRLEN(p)<< \\\; / *编译器错误* / } - Frederick Gotham Many people use a method quite akin to the following to determine anarray''s length: #define NUMELEM(arr) (sizeof (arr) / sizeof *(arr)) I recall reading an article written by Alf P. Steinbach which listedseveral methods of determining an array''s length. He listed the pro''s andcon''s of each. One of the con''s of the above method is that the macro can''t detect whetherit is erronously supplied with a pointer instead of an array. (It alsoevaluates "arr" twice, which is bad if we call a function which returns anarray by reference!). In an attempt to overcome the former shortcoming, I''ve cooked up thefollowing. It''s not a finished product, but you get the idea: #define NUMELEM(arr) (sizeof (arr) / sizeof *(arr)) template <int positive_or_negative>struct VerifyType {unsigned must_not_be_negative : positive_or_negative;/* Can''t have negative bit field */}; #define VERIFY(compile_time_constant) \( sizeof(VerifyType< \(compile_time_constant) ? 1 : -1 >) )#define ARRLEN(arr) ((void)VERIFY(NUMELEM(arr) 1), NUMELEM(arr)) #include <iostream>using std::cout; int main(){int array[5]; int *p = array; cout << ARRLEN(array) << ''\n''; cout << ARRLEN(p) << ''\n''; /* Compiler ERROR */} In essence, it simply performs a compile-time assert to ensure that NUMELEM(arr) is greater than one. Of course, we''ll have technicalities such asarrays whose length is 1. -- Frederick Gotham 解决方案 "Frederick Gotham" <fg*******@SPAM.comwrote in messagenews:zb*******************@news.indigo.ie...>Many people use a method quite akin to the following to determine anarray''s length: #define NUMELEM(arr) (sizeof (arr) / sizeof *(arr))I recall reading an article written by Alf P. Steinbach which listedseveral methods of determining an array''s length. He listed the pro''s andcon''s of each.One of the con''s of the above method is that the macro can''t detectwhetherit is erronously supplied with a pointer instead of an array. (It alsoevaluates "arr" twice, which is bad if we call a function which returns anarray by reference!).In an attempt to overcome the former shortcoming, I''ve cooked up thefollowing. It''s not a finished product, but you get the idea:#define NUMELEM(arr) (sizeof (arr) / sizeof *(arr))template <int positive_or_negative>struct VerifyType { unsigned must_not_be_negative : positive_or_negative; /* Can''t have negative bit field */};#define VERIFY(compile_time_constant) \ ( sizeof(VerifyType< \ (compile_time_constant) ? 1 : -1 >) ) #define ARRLEN(arr) ((void)VERIFY(NUMELEM(arr) 1), NUMELEM(arr))#include <iostream>using std::cout;int main(){ int array[5]; int *p = array; cout << ARRLEN(array) << ''\n''; cout << ARRLEN(p) << ''\n''; /* Compiler ERROR */}In essence, it simply performs a compile-time assert to ensure thatNUMELEM(arr) is greater than one. Of course, we''ll have technicalities such asarrays whose length is 1.Why not eliminate the above described problems as well as thosewill macros in general? Use a vector instead, it ''knows'' its size. std::vector<intv(10);v.push_back(0);std::cout << v.size() << ''\n''; // prints 11 -Mike >--Frederick Gotham Frederick Gotham posted: #define VERIFY(compile_time_constant) \ ( sizeof(VerifyType< \ (compile_time_constant) ? 1 : -1 >) ) #define ARRLEN(arr) ((void)VERIFY(NUMELEM(arr) 1), NUMELEM(arr)) I''ll relocate that "void" cast: #define VERIFY(compile_time_constant) \( (void)sizeof(VerifyType< \(compile_time_constant) ? 1 : -1 >) )#define ARRLEN(arr) (VERIFY(NUMELEM(arr) 1), NUMELEM(arr)) -- Frederick GothamFrederick Gotham posted: I''ll relocate that "void" cast: I''ve left a few necessary parentheses out along the way. I''ll re-write thewhole thing: #define NUMELEM(arr) (sizeof (arr) / sizeof *(arr)) template <int positive_or_negative>struct VerifyType {unsigned must_not_be_negative : positive_or_negative;/* Can''t have negative bit field */}; #define VERIFY(compile_time_constant) \( (void)sizeof(VerifyType< \(compile_time_constant) ? 1 : -1 >) )#define ARRLEN(arr) (VERIFY(NUMELEM((arr)) 1), NUMELEM((arr))) #include <iostream>using std::cout; int main(){int array[5]; int *p = array; cout << ARRLEN(array) << ''\n''; cout << ARRLEN(p) << ''\n''; /* Compiler ERROR */} -- Frederick Gotham 这篇关于更安全的阵列长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-10 22:36