2009-12-28 36 views
6

Một số mã ví dụ để bắt đầu câu hỏi:Looping một mảng kích thước cố định mà không cần xác định kích thước của nó trong C

#define FOO_COUNT 5 

static const char *foo[] = { 
     "123", 
     "456", 
     "789", 
     "987", 
     "654" 
}; 

Cách này thường được lặp kết thúc, như đối với một ví dụ, như sau:

int i = FOO_COUNT; 
while (--i >= 0) { 
printf("%s\n", foo[i]); 

Có cách nào để thực hiện điều này mà không có con người đếm số 5 không? Trong tương lai, tôi có thể thêm/xóa các phần tử và quên cập nhật kích thước của mảng, do đó phá vỡ ứng dụng của tôi.

Trả lời

16
int i = sizeof(foo)/sizeof(foo[0]); 
+0

sẽ này vẫn hoạt động nếu con trỏ nhân vật trong foo chỉ vào chuỗi ký tự của kích thước biến? – randombits

+0

yes (15 char hạn) –

+0

vì vậy nếu bất kỳ yếu tố vượt quá 15 ký tự, việc kiểm tra này sẽ thất bại? lẽ tốt hơn để sử dụng NULL sentinel sau đó? cảm ơn một lần nữa – randombits

0

Có.

sizeof (foo)/sizeof (char *)

là 5.

2

Cách thông thường để làm điều này là để kết thúc mảng với NULL và lặp cho đến khi bạn nhấn đó.

2

Có.

int i = sizeof(foo)/sizeof(char*); 

Lưu ý: Điều này chỉ áp dụng cho các mảng được phân bổ tĩnh. Nó sẽ không hoạt động cho malloc ed hoặc new mảng ed.

12

Sử dụng một trọng điểm ở cuối, chẳng hạn như NULL:

static const char *foo[] = { 
     "123", 
     "456", 
     "789", 
     "987", 
     "654", 
     NULL 
}; 

for (char *it = foo[0]; it != NULL; it++) 
{ 
     ... 
} 
2
size_t i = sizeof foo/sizeof *foo; // or sizeof foo/sizeof foo[0] 

này chia tổng số byte trong mảng foo (sizeof foo) bằng số byte trong một phần tử duy nhất (sizeof *foo), cho số phần tử trong mảng.

2

Cũng có một phương pháp khác trong C99, đặc biệt nếu bạn muốn các chỉ mục có tên, cho phép bản địa hóa ví dụ và như vậy.

enum STRINGS { 
    STR_THING1, 
    STR_THING2, 
    STR_THING3, 
    STR_THING4, 
    STR_WHATEVER, 

    STR_MAX   /* Always put this one at the end, as the counting starts at 0 */ 
        /* this one will be defined as the number of elements */ 
}  

static const char *foo[STR_MAX] = { 
    [STR_THING1] = "123", 
    [STR_THING2] = "456", 
    [STR_THING3] = "789", 
    [STR_THING4] = "987", 
    [STR_WHATEVER] = "OR Something else", 
}; 

Bằng cách sử dụng trình khởi tạo tên chương trình vẫn chính xác ngay cả khi giá trị enum thay đổi.

for (i = STR_THING1; i<STR_MAX; i++) 
    puts(foo[i]); 

hoặc bất cứ nơi nào trong chương trình với chỉ số tên

printf("thing2 is %s\n", foo[STR_THING3]); 

Kỹ thuật này có thể được sử dụng để mô phỏng bó ressource. Khai báo một enum và một số mảng chuỗi với các biến thể ngôn ngữ và sử dụng một con trỏ trong phần còn lại của chương trình. Đơn giản và nhanh chóng (đặc biệt là trên các máy 64bit nơi nhận được địa chỉ của một hằng số (string) có thể tương đối tốn kém Edit:.. Sizeof foo/sizeof * Kỹ thuật foo vẫn hoạt động với điều này

0

Đối với một số ứng dụng, thửCatch sẽ làm việc.

+0

Ngay cả khi C có 'try' và' catch', tôi không thấy chúng có liên quan như thế nào để lặp qua một mảng. – Nefrubyr

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