2010-12-11 17 views

Trả lời

4

Điều này?

#define _countof(a) (sizeof(a)/sizeof(*(a)))

+3

đó sẽ là không an toàn khi a là một con trỏ (so với mảng). macro _countof là an toàn. – Uri

5

Tôi không nhận thức được một cho GCC, nhưng Linux sử dụng GCC's __builtin_types_compatible_p builtin để làm cho họ ARRAY_SIZE() vĩ mô an toàn hơn (nó sẽ gây ra một sự đột phá xây dựng nếu áp dụng cho một con trỏ):

/* &a[0] degrades to a pointer: a different type from an array */ 
#define __must_be_array(a) \ 
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) 

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr)) 

Lưu ý: Tôi nghĩ rằng macro BUILD_BUG_ON_ZERO() có tên gây hiểu lầm (nó gây ra lỗi xây dựng nếu biểu thức là không không và trả về 0 nếu không):

/* Force a compilation error if condition is true, but also produce a 
    result (of value 0 and type size_t), so the expression can be used 
    e.g. in a structure initializer (or where-ever else comma expressions 
    aren't permitted). */ 
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 

Tôi nghĩ việc đặt tên cho macro này xuất phát từ việc xem xét nó trong hai phần: BUILD_BUG_ON là macro làm gì khi biểu thức là đúng và ZERO là giá trị 'được trả về' bởi macro (nếu không có bản dựng phá vỡ).

10

Sử dụng C++ 11, hình thức phi vĩ mô là:

char arrname[5]; 
size_t count = std::extent< decltype(arrname) >::value; 

extent có thể được tìm thấy trong type_traits tiêu đề.

Hoặc nếu bạn muốn nó trông đẹp hơn một chút, quấn nó trong này:

template < typename T, size_t N > 
size_t countof(T (& arr)[ N ]) 
{ 
    return std::extent< T[ N ] >::value; 
} 

Và sau đó nó trở thành:

char arrname[5]; 
size_t count = countof(arrname); 

char arrtwo[5][6]; 
size_t count_fst_dim = countof(arrtwo); // 5 
size_t count_snd_dim = countof(arrtwo[0]); // 6 

Edit: Tôi chỉ nhận thấy "C" gắn cờ thay vì "C++". Vì vậy, nếu bạn đang ở đây cho C, xin vui lòng bỏ qua bài đăng này. Cảm ơn.

+0

Một khác biệt: ít nhất là trên MSVC, std :: extent :: giá trị trả về 0, trong khi _countof trả về số đếm thích hợp. – Ash

+0

Ngoài ra thử nghiệm nó trên GCC và rằng quá, trả về 0. – Ash

+3

Bạn phải làm cho countof chức năng của bạn constexpr, nếu không nó sẽ không hoạt động. Ngoài ra, nó đơn giản hơn để "trả về N;" thay vì "std :: mức độ < T[ N ] > :: giá trị;". – prgDevelop

2

Bạn có thể sử dụng thay vì boost::size():

#include <boost/range.hpp> 

int my_array[10]; 
boost::size(my_array); 
+1

Boost là C++, trong khi các câu hỏi được gắn thẻ là C. – tambre

+0

Câu trả lời bình chọn hàng đầu cũng là C++, như là '_countof' thực hiện trong MSVC – KindDragon

+1

Tôi sẽ không xem xét rằng biện minh cho việc đăng câu trả lời cho một ngôn ngữ khác trên một câu hỏi không được gắn thẻ bằng ngôn ngữ đó. – tambre

Các vấn đề liên quan