2009-07-05 26 views
23

Có một thứ như một mảng răng cưa trong C hoặc C++ không?Các mảng răng cưa có tồn tại trong C/C++ không?

Khi tôi biên dịch này:

int jagged[][] = { {0,1}, {1,2,3} }; 

tôi nhận được lỗi này:

error: declaration of `jagged' as multidimensional array must have bounds for all dimensions except the first

Trả lời

14

Nếu bạn chỉ muốn khởi nó, bạn có thể nói:

int jagged[][3] = { {0,1}, {1,2,3} }; 

nhưng mảng vẫn sẽ có hình dạng [2] [3]. Nếu bạn muốn một mảng răng cưa thực sự, bạn sẽ phải tạo ra nó một cách tự động. Và nếu bạn làm điều đó, và đang sử dụng C++, bạn nên sử dụng std::vector, như friol gợi ý.

12

Trong C++ (không được biên dịch, và có lẽ có một cú pháp nhỏ gọn hơn):

std::vector<std::vector<int> > myArray; 

myArray.push_back(std::vector<int>()); 
myArray.push_back(std::vector<int>()); 

myArray[0].push_back(0); 
myArray[0].push_back(1); 

myArray[1].push_back(1); 
myArray[1].push_back(2); 
myArray[1].push_back(3); 

Vì vậy, bây giờ bạn có thể truy cập vào các yếu tố với, ví dụ, myArray [0] [0], vv

+1

Erm bạn đang đẩy con trỏ vào một vectơ không giữ con trỏ ... – Goz

21

Trong CI sẽ sử dụng một mảng con trỏ.

Ví dụ:

int *jagged[5]; 

jagged[0] = malloc(sizeof(int) * 10); 
jagged[1] = malloc(sizeof(int) * 3); 

vv vv

+0

Trong ví dụ này, cách chính xác để giải phóng bộ nhớ là gì? – papgeo

15

Có một loạt các cách để làm điều đó. Dưới đây là một cách khác:

int jagged_row0[] = {0,1}; 
int jagged_row1[] = {1,2,3}; 
int *jagged[] = { jagged_row0, jagged_row1 }; 
+3

+1. Đây là nơi các chữ kép của C99 thể hiện: 'int * jagged [] = {(int []) {0,1}, (int []) {1, 2, 3}};' cũng không đẹp sao? –

+2

Sự cố với giải pháp này là các mảng phụ ngay lập tức phân rã thành con trỏ, vì vậy bạn không có cách nào để nói những giới hạn đó là gì. –

+0

@Neil, tôi không nghĩ về điều này chút nào. Tất nhiên bạn có quyền. Điểm tốt :) –

2

Trong C99 bạn có thể làm như sau:

int jagged_row0[] = {0,1}; 
int jagged_row1[] = {1,2,3}; 

int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand 

// also since compound literals are lvalues ... 
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} }; 

Sự khác biệt duy nhất ở đây (so với câu trả lời rampion của) là các mảng không phân hủy để con trỏ và người ta để truy cập các mảng riêng lẻ thông qua một mức độ khác - (ví dụ: *jagged[0] - và kích thước của mỗi hàng phải được ghi lại - tức là sizeof(*jagged[0]) sẽ không biên dịch) - nhưng chúng xuất hiện lởm chởm đến xương;)

+0

Tôi nghĩ bạn không thể tạo mảng không hoàn chỉnh ... oh, bạn đang tạo một mảng con trỏ đến một loại không đầy đủ, điều đó có thể nhưng không mua cho bạn bất cứ thứ gì trên câu trả lời của hung hăng. –

3

lý do bạn gặp lỗi là bạn m ust chỉ định giới hạn cho ít nhất kích thước bên ngoài; tức là

int jagged[][3] = {{0,1},{1,2,3}}; 

Bạn không thể bị lởm chởm [0] là mảng 2 phần tử int và răng cưa [1] là một mảng gồm 3 phần tử int; một mảng phần tử N là một kiểu khác với mảng M-phần tử (trong đó N! = M), và tất cả các phần tử của một mảng phải cùng loại.

Điều bạn có thể làm là những gì người khác đã đề xuất ở trên và tạo lởm chởm như một mảng con trỏ tới int; cách mà mỗi phần tử có thể trỏ đến số nguyên mảng của các kích cỡ khác nhau:

int row0[] = {0,1}; 
int row1[] = {1,2,3}; 
int *jagged[] = {row0, row1}; 

Mặc dù row0 và ROW1 nhiều loại khác nhau (2 phần tử mảng vs 3 yếu tố int), trong bối cảnh initializer họ cả hai được chuyển đổi hoàn toàn sang cùng một loại (int *).

1

Với C++ 11 danh sách initializer this có thể được viết gọn hơn:

#include <vector> 
#include <iostream> 

int main() { 
    // declare and initialize array 
    std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}}; 
    // print content of array 
    for (auto row : arr) { 
     for (auto col : row) 
      std::cout << col << " "; 
     std::cout << "\n"; 
    } 
} 

Đầu ra là:

$ g++ test.cc -std=c++11 && ./a.out 
1 2 3 
4 5 

Để tham khảo:

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