2008-10-24 21 views
5

Tôi chỉ mới bắt đầu học C++ để bào chữa cho câu hỏi đơn giản này. Những gì tôi đang làm là đọc các số từ một tệp và sau đó cố thêm chúng vào một mảng. Vấn đề của tôi là làm thế nào để bạn tăng kích thước của mảng? Ví dụ tôi nghĩ rằng có thể chỉ cần làm:Mảng động

#include <iostream> 
using namespace std; 

int main() { 
    double *x; 
    x = new double[1]; 
    x[0]=5; 
    x = new double[1]; 
    x[1]=6; 
    cout << x[0] << "," << x[1] << endl; 
    return 0; 
} 

Nhưng điều này rõ ràng chỉ ghi đè giá trị, 5, mà ban đầu tôi đặt thành x [0] và vì vậy đầu ra 0,6. Làm thế nào tôi sẽ làm cho nó để nó sẽ sản lượng 5,6?

Hãy nhận ra rằng đối với ví dụ tôi đã đưa vào, tôi không muốn làm lộn xộn nó bằng cách đọc mã từ tệp hoặc mã để lấy số từ người dùng. Trong ứng dụng thực tế, tôi sẽ không biết làm thế nào lớn của một mảng tôi cần tại thời gian biên dịch vì vậy xin vui lòng không cho tôi biết chỉ cần thực hiện một mảng với hai yếu tố và đặt chúng bằng 5 và 6 tương ứng.

Cảm ơn sự giúp đỡ của bạn.

Trả lời

17

Bạn không muốn làm việc trực tiếp với mảng. Thay vào đó, hãy cân nhắc sử dụng một số vector. Sau đó, bạn có thể gọi hàm push_back để thêm mọi thứ vào cuối và nó sẽ tự động thay đổi kích cỡ vectơ cho bạn.

#include <iostream> 
#include <vector> 

int 
main() { 
    double value; 
    std::vector<double> values; 

    // Read in values 
    while (std::cin >> value) { 
     values.push_back(value); 
    } 

    // Print them back out 
    for (std::size_t i(0), len(values.size()); i != len; ++i) { 
     std::cout << values[i]; 
    } 
} 
+0

Bạn phải cẩn thận với vector mặc dù chúng có xu hướng sử dụng khá chậm. – Huppie

+0

Chậm là tương đối. tức là, lập hồ sơ cho chương trình của bạn và xem liệu nó có tác động đến mọi thứ hay không. Nếu có, hãy viết một trình phân bổ tùy chỉnh, được tối ưu hóa để phân bổ đôi (và các đối tượng có kích thước 'sizeof (double)'). –

+0

Nó sẽ không chậm hơn so với thực hiện thay đổi kích thước cho mình với mới, xóa và sao chép. –

4

Bạn nên sử dụng lớp thu thập để thực hiện việc này thay vì tự quản lý. Hãy xem lớp "vector". Về cơ bản nó là một mảng động tự động thay đổi kích thước theo yêu cầu.

Trong trường hợp của bạn, bạn sẽ sử dụng "vectơ" với loại "gấp đôi". Bạn cũng có thể cần phải đọc lên trên các mẫu trong C++.

http://www.cplusplus.com/reference/stl/vector/

4

Hoặc, nếu bạn không muốn sử dụng STL này hay cách khác điều động, bạn chỉ có thể tạo ra các mảng với kích thước chính xác ngay từ đầu: x = new double [2];

Tất nhiên, vấn đề có mức độ lớn. Nếu bạn không biết, thì bạn sẽ cần phải tạo ra nó là "đủ lớn" (như một trăm, hoặc một nghìn) ... mà, tại một số điểm, sẽ không đủ lớn và nó sẽ thất bại trong một số cách tìm kiếm ngẫu nhiên. Vì vậy, sau đó bạn sẽ cần phải thay đổi kích thước nó. Và một khi bạn nhận được đến thời điểm đó, bạn sẽ muốn bạn sử dụng STL ngay từ đầu, giống như các câu trả lời khác đang yêu cầu bạn làm.

#include <iostream> 
using namespace std; 
int main() { 
    double *x = new double[2]; 
    x[0]=5; 
    x[1]=6; 
    cout << x[0] << "," << x[1] << endl; 
    return 0; 
} 
2

Nếu vì một số lý do bạn không có quyền truy cập vào STL - hoặc muốn học cách để làm điều này bản thân - bạn có thể sử dụng một thuật toán như thế này:

Phân bổ mảng của bạn như một số tùy ý kích thước và nhớ số lượng phần tử trong đó và kích thước của nó là bao nhiêu:

int *a = malloc(int * ARBITRARY_SIZE); 
int size = 0; 
int allocated = ARBITRARY_SIZE; 

mỗi lần bạn thêm phần tử mới, tăng "kích thước". Nếu kích thước bằng ARBITRARY_SIZE, nhân 'phân bổ' cho 2, và phân bổ lại mảng. Dù bằng cách nào, chỉ định giá trị mới cho [size].

void addElement(int value) { 
    ++size; 

    if (size == allocated) { 
    allocated *= 2; 
    a = realloc(sizeof(int) * allocated); 
    a = new_a; 
    } 

    a[size] = value; 
} 

Lưu ý rằng mã của bạn ở trên có ít nhất một lỗi - bạn không phân bổ đủ không gian cho x [1] trong cả hai trường hợp.

Cũng rõ ràng trong mã thực tế bạn muốn kiểm tra xem trả lại từ malloc & realloc không phải là không.

+0

Nó cũng truyền thống để kiểm tra giá trị trả về từ malloc cho null. Không giống như mới nó không ném std :: bad_alloc trên thất bại, và bãi lõi là khó khăn hơn để gỡ lỗi hơn xác nhận không thành công ;-) –

+0

Thực hiện thay đổi. Mặc dù các bãi lõi dễ debug hơn hầu hết các lỗi khác :) –

3

Dưới đây là một ví dụ dù cho biện pháp tốt, vì vậy bạn có thể thấy các mô hình:

#include <iostream> 
using namespace std; 

int main() { 
    // Allocate some memory for a double array of size 1 and store 
    // an address to the beginning of the memory in mem_address. 
    double* mem_address = new double[1]; 

    // Assign 5 to the first element in the array. 
    mem_address[0] = 5; 

    // Save the address of the memory mem_address is currently 
    // referencing. 
    double* saved_address = mem_address; 

    // Allocate some memory for a double array of size 2 and store 
    // an address to the beginning of the memory in mem_address. 
    mem_address = new double[2]; 

    // Copy over the 1 element from the first memory block 
    // to the new one. 
    mem_address[0] = saved_address[0]; 

    // Done with the old memory, so clean it up. 
    delete [] saved_address; 

    // Assign 6 to the second element in the new array. 
    mem_address[1] = 6; 

    // Print out the 2 elements in the new array. 
    cout << mem_address[0] << "\n"; 
    cout << mem_address[1] << "\n"; 

    // Done with the new array memory now, so clean it up. 
    delete [] mem_address; 
} 
0

Một mảng luôn cần một khối liền kề của bộ nhớ. Trong một tình huống mà bạn có thể cần phải thay đổi kích thước mảng sau này, việc phân bổ lại có lẽ là giải pháp duy nhất. Đây là những gì Moishe và Shadow2531 làm ở trên.

Vấn đề với phân bổ lại là nó có thể là một hoạt động tốn kém. Vì vậy, nếu bạn cần thêm 5 phần tử vào mảng phần tử 5000, bạn có thể sẽ sao chép tất cả 5000 phần tử trên bộ nhớ.

Thay vào đó, sử dụng danh sách được liên kết có thể được xem xét cho trường hợp như vậy.