2012-10-10 36 views
10

Có lẽ là một câu hỏi ngây thơ - tôi đã từng sử dụng chương trình 20 năm trước và chưa được mã hóa nhiều kể từ đó. bộ nhớ của tôi như thế nào C preprocessor công trình đã teo đáng kể kể từ đó ...Định dạng mảng cho #define (bộ tiền xử lý C)

Tôi đang viết một chương trình rất đơn giản C và tôi đang cố gắng để khai báo một vài mảng tĩnh toàn cầu, nhưng kích thước của arrays sẽ phụ thuộc (trên một cách không tầm thường) trên biến số MODE. Một cái gì đó giống như ví dụ đơn giản dưới đây.

Hai điểm nhanh: Tôi biết tôi có thể chỉ kích thước arrays theo kích thước lớn nhất cần thiết bởi bất kỳ MODE, nhưng tôi không muốn điều đó vì (không giống như trong ví dụ đơn giản bên dưới) đôi khi một số ít các thứ nguyên này sẽ cực kỳ lớn trong khi những người khác thì nhỏ.

Ngoài ra, tôi muốn sử dụng các mảng toàn cục được xác định tĩnh - thay vì tự động phân bổ chúng khi chạy. Tôi muốn trình biên dịch có kích thước tại thời gian biên dịch.

//** Simplified example of what I'd like to do **//  
#define SIZE_LIST_1[5] = {2, 7, 23, 33, 12, 76} // I don't think this is valid syntax 
#define SIZE_LIST_2[5] = {11, 65, 222, 112, 444} 

#define MODE 4 
#define S1 SIZE_LIST_1[MODE] 
#define S2 SIZE_LIST_2[MODE] 

int a[S1], b[S2]; 
+0

'int SIZE_LIST_1 [5] = {2,7 ... 76};' –

+1

Macro thay thế. – Jack

+0

Tôi không hiểu ý bạn là gì [S1]. bạn đang cố làm gì ở đó? –

Trả lời

10

Bạn cần phải xác định một loạt các macro helper đầu tiên trước khi bạn có thể làm điều này một cách đơn giản:

#define CONCAT(A,B)   A ## B 
#define EXPAND_CONCAT(A,B) CONCAT(A, B) 

#define ARGN(N, LIST)  EXPAND_CONCAT(ARG_, N) LIST 
#define ARG_0(A0, ...)  A0 
#define ARG_1(A0, A1, ...) A1 
#define ARG_2(A0, A1, A2, ...)  A2 
#define ARG_3(A0, A1, A2, A3, ...) A3 
#define ARG_4(A0, A1, A2, A3, A4, ...)  A4 
#define ARG_5(A0, A1, A2, A3, A4, A5, ...) A5 
#define ARG_6(A0, A1, A2, A3, A4, A5, A6, ...)  A6 
#define ARG_7(A0, A1, A2, A3, A4, A5, A6, A7, ...) A7 
#define ARG_8(A0, A1, A2, A3, A4, A5, A6, A7, A8, ...)  A8 
#define ARG_9(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, ...) A9 
#define ARG_10(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10 

/* above should be in a pp_helper.h header file or some such */ 

#define SIZE_LIST_1 (2, 7, 23, 33, 12, 76) 
#define SIZE_LIST_2 (11, 65, 222, 112, 444, 1000) 

#define S1 ARGN(MODE, SIZE_LIST_1) 
#define S2 ARGN(MODE, SIZE_LIST_2) 

#define MODE 4 

int a[S1], b[S2]; 

Có một loạt các tiền xử lý 'thư viện' bạn có thể nhận được với mã boilerplate (tăng PP, P99), hoặc bạn chỉ có thể cuộn của riêng bạn. Vấn đề chính là bạn cần xác định các macro ARG dựa trên số lượng đối số lớn nhất mà bạn từng muốn xử lý.

7

Có lẽ tốt nhất bạn có thể làm là một cái gì đó như thế này:

#define SIZE_LIST_1_0 2 
#define SIZE_LIST_1_1 7 
#define SIZE_LIST_1_2 23 
#define SIZE_LIST_1_3 33 
#define SIZE_LIST_1_4 12 

#define SIZE_LIST_2_0 11 
#define SIZE_LIST_2_1 65 
#define SIZE_LIST_2_2 222 
#define SIZE_LIST_2_3 112 
#define SIZE_LIST_2_4 444 

#define MODE 4 

#define S1 SIZE_LIST_1_##MODE 
#define S2 SIZE_LIST_2_##MODE 

int a[S1], b[S2]; 
+0

Cảm ơn bạn Paul - đó là một chút lộn xộn, nhưng có thể giải quyết vấn đề. Tôi đã không biết bạn có thể làm điều đó. Tôi lấy nó không có cách nào 'thanh lịch hơn' để làm điều đó? – user1735592

+0

Không - bộ tiền xử lý thực sự rất hạn chế và không được thiết kế cho loại lạm dụng này. Tôi không chắc chắn tại sao câu trả lời này có một cuộc bỏ phiếu xuống vô danh mặc dù - nó không phải là rất thanh lịch nhưng nó giải quyết vấn đề. Oh well ... –

+1

Tôi cũng không thấy lý do tại sao nó nên được bình chọn. Cảm ơn bạn một lần nữa cho ý tưởng. – user1735592

3

Tôi sợ không có khả năng như vậy.

tôi đề nghị các phương pháp sau đây thay vì:

#define MODE 0 

#define DECLARE_ARRAYS_WITH_SIZES(S1, S2, S3) \ 
    int arr1[S1]; \ 
    int arr2[S2]; \ 
    int arr3[S3]; 

#if MODE == 0 
DECLARE_ARRAYS_WITH_SIZES(3, 6, 7) 
#elif MODE == 1 
DECLARE_ARRAYS_WITH_SIZES(8, 2, 1) 
#endif 
Các vấn đề liên quan