这是获取数组大小的宏
#define array_size(array) \
(sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*)))
我认为通常(sizeof(array)/(sizeof(array [0]))足以获得数组的大小。
我想那部分
(sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))
是为了避免将整个事物除以零,任何人都可以帮忙解释一下?
提前致谢。
干杯,
答案 0 :(得分:12)
将sizeof array[0]
乘以除数
(sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))
如果,使除数为零
sizeof array == sizeof(void*)
和
sizeof array[0] > sizeof(void*)
在这些情况下,在编译期间会得到除零,这会导致编译失败。
这些检查试图检测作为指针的参数(它们是否是数组到指针转换的结果),因为人们无法通过使用该商来知道指针指向的“数组”有多大
如果其他指针类型的大小不同于void*
,则它会失败,并且它不会检测指向不大于void*
s的指针的指针。通过虚假的安全感来扼杀作者可能弊大于利。
答案 1 :(得分:6)
我认为通常(sizeof(array)/(sizeof(array [0]))足以获得数组的大小。
虽然这不是你的主要问题,但你提到了它。在C ++中确定数组大小的正确方法是使用模板:
template<typename T, size_t size>
constexpr size_t array_size(T(&)[size]){
return size;
}
答案 2 :(得分:1)
我认为这部分很清楚:sizeof( array ) / sizeof( array[0] )
这部分(sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))
是一个逻辑表达式,因此产生真或假。在计算整个表达式时,将sizeof( array[0] )
乘以逻辑表达式,编译器将逻辑表达式转换为0或1.因此,您最终得到了
sizeof( array ) / (sizeof( array[0] ) * 1)
或
sizeof( array ) / (sizeof( array[0] ) * 0)
。
第一种情况是正常和理想的情况。第二种情况会因为除以零而给出编译器错误。因此,如果您调用示例代码,则代码将无法编译:
long *p; // assuming a platform with sizeof(long)==sizeof(void*)
array_size(p);
但它不会像以下那样发现错误:
char *p;
array_size(p);
对于我希望它编译的案例,它将无法编译:
long x[1]; // assuming a platform with sizeof(long)==sizeof(void*)
array_size(x);
顺便说一句,如果你将这个函数声明为一个宏(并且在C ++中我真的更喜欢模板样式解决方案),你应该将宏中的所有array
更改为(array)
。