2010-08-24 6 views
7

trong C++ Tôi muốn khởi tạo một ma trận đôi (2 chiều đôi mảng) như tôi thường làm mà không cần con trỏ như sau:C++ đa chiều mảng khởi

double data[4][4] = { 
    1,0,0,0, 
    0,1,0,0, 
    0,0,1,0, 
    0,0,0,1 
}; 

Tuy nhiên, kể từ khi tôi muốn quay trở lại và chuyển nó cho các hàm, tôi cần nó như một con trỏ double**. Vì vậy, về cơ bản tôi cần phải khởi tạo dữ liệu một cách tốt đẹp (như trên), nhưng sau đó tôi cần lưu con trỏ vào mảng 2D mà không làm mất dữ liệu khi chức năng thoát.

Bất kỳ trợ giúp nào về điều này? :-)

+4

Tại sao bạn cần nó như một 'đôi ** '? Có gì sai với 'double (*) [4]'? –

+0

Đây là C++. Đây có phải là một lớp học, với mảng này như là một thành viên, mà đi một tham chiếu trở lại khi bạn gọi một chức năng thành viên? –

+0

có thể trùng lặp của [Truyền mảng hai chiều qua con trỏ] (http: // stackoverflow.com/questions/3515045/passing-two-dimensional-array-via-pointer) Đó là C, không phải C++, nhưng nó chính xác là cùng một vấn đề. –

Trả lời

9

Trừ khi bạn là đặc biệt về con trỏ, tôi sẽ muốn có một tài liệu tham khảo ở đây

void init(double (&r)[4][4]){ 
    // do assignment 
    r[0][0] = 1; 
} 

int main(){ 
    double data[4][4] = { 
     1.0,0,0, 
     0,1,0,0, 
     0,0,1,0, 
     0,0,0,1 
    }; 

    init(data); 
} 

Bằng cách này, nếu bạn vượt qua nó để một chức năng theo cách này, bạn sẽ được "chuyển nhượng" hơn là "khởi tạo" .

+0

Tôi nghĩ câu trả lời này đang trở nên ấm hơn. Nó có thể là một trong những tôi đang tìm kiếm! – Felix

+0

Bằng cách thay thế "init" bằng chức năng sao chép, điều này làm cho vấn đề của tôi trở nên thanh lịch. Cảm ơn! – Felix

1

Khởi tạo biến tạm thời theo cách này và sau đó sao chép nó vào bộ nhớ được cấp phát động.

3

double (*)[4] rất khác so với double **

Chỉ cần phác thảo cách bố trí của đôi bạn trong bộ nhớ cho cả hai và bạn nên hiểu lý do tại sao bạn không thể sử dụng chúng thay thế cho nhau.

+0

vì tôi không biết hoặc hiểu "double (*) [4]", tôi không thể phác họa nó. Nó có nghĩa là gì? – Felix

+0

@Felix: Nó có nghĩa là "con trỏ tới mảng dài-4". –

5

Tất cả các ma trận của bạn có 4x4 không? Sau đó, tôi chỉ đơn giản là sẽ xác định một lớp học với thành viên double[4][4] và vượt qua đối tượng của lớp đó xung quanh:

class Matrix 
{ 
    double m[4][4]; 
    // ... 
}; 

void function(const Matrix& matrix) 
{ 
    // ... 
} 

Nếu bạn cần ma trận có kích thước khác nhau, nhưng họ được biết tại thời gian biên dịch, sử dụng một mẫu:

template <size_t n> 
class Matrix 
{ 
    double m[n][n]; 
    // ... 
}; 

template <size_t n> 
void function(const Matrix<n,n>& matrix) 
{ 
    // ... 
} 

Điều này giúp bạn tránh được việc xử lý sự phân rã từ mảng sang con trỏ và làm cho mã IMHO dễ đọc hơn.

4

Trước tiên, khai báo mảng hai chiều không chính xác. Nó cần phải được thực hiện như sau:

double data[4][4] = { 
     {1.0,0,0,0}, 
     {0,1,0,0}, 
     {0,0,1,0}, 
     {0,0,0,1} 
    }; 

Thứ hai, cho đi qua nó trong một chức năng bạn có thể làm điều đó như

show(data); 

Trong tuyên bố chức năng, bạn cần phải cung cấp cho các lập luận như một mảng với cho tất cả các kích thước ngoại trừ thứ nguyên đầu tiên. Vì vậy, tuyên bố sẽ như sau:

void show(double arr[][4]) 
{ 
    ... 
    ... 
} 

Điều này chuyển mảng thành tham chiếu mà bạn cần sử dụng con trỏ.

Hy vọng điều này sẽ hữu ích.

+0

Cảm ơn! Đó là khởi tạo một dòng là những gì tôi đã tìm kiếm. –

0

Làm thế nào về vấn đề này (với con trỏ, và làm những gì bạn yêu cầu)

#include <iostream> 

using namespace std; 

int refer(double (*a)[4]) 
{ 
    cout<<"First value is "<<(*a)[0]; 
    (*a)[0] = 37; 
    cout<<"changed value is "<<(*a)[0]; 
} 

int main() 
{ 
    double data[4][4] = { 
    1.0,0,0, 
    0,1,0,0, 
    0,0,1,0, 
    0,0,0,1 
    }; 
    refer(data); 
    return 0; 
}